mirror of
https://github.com/imjasonh/apkviz
synced 2026-07-08 01:45:15 +00:00
This web application visualizes package dependencies in the Wolfi Linux distribution, providing powerful insights into the package ecosystem. Features: - Interactive force-directed dependency graph visualization - Shows both forward dependencies (what a package depends on) and reverse dependencies (what depends on it) - Click any node to re-center the visualization on that package - Transitive dependency analysis with toggle control - Advanced package analytics including: - Criticality scores showing how many packages depend on each package - Total size impact analysis (package + all dependencies) - Dependency depth metrics - Bus factor warnings for critical infrastructure packages - "Most Critical Packages" dashboard showing system-wide statistics - Real-time search with auto-complete - Different visual styles for direct vs transitive dependencies - Playwright-based testing infrastructure for automated UI testing Technical implementation: - TypeScript + D3.js for visualization - Webpack build system - Analyzes Wolfi's APKINDEX for package metadata - Efficient dependency graph algorithms - Responsive design with detailed package information panel 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
42 lines
No EOL
1.5 KiB
JavaScript
42 lines
No EOL
1.5 KiB
JavaScript
const { chromium } = require('playwright');
|
|
|
|
async function testClickSimple() {
|
|
const browser = await chromium.launch({ headless: true });
|
|
const page = await browser.newPage();
|
|
|
|
await page.goto('http://localhost:8081', { waitUntil: 'networkidle' });
|
|
await page.waitForTimeout(2000);
|
|
|
|
// Start with busybox (default)
|
|
console.log('Starting with busybox (default)');
|
|
const initialSearch = await page.$eval('#search', el => el.value);
|
|
console.log('Initial search box:', initialSearch);
|
|
|
|
await page.screenshot({ path: 'playwright-output/nav-1-busybox.png', fullPage: true });
|
|
|
|
// Click on the first visible circle (any dependency)
|
|
const firstCircle = await page.$('circle');
|
|
if (firstCircle) {
|
|
console.log('\nClicking on a node...');
|
|
await firstCircle.click();
|
|
await page.waitForTimeout(2000);
|
|
|
|
// Check what happened
|
|
const newSearch = await page.$eval('#search', el => el.value);
|
|
console.log('Search box after click:', newSearch);
|
|
|
|
// Get package details
|
|
const packageName = await page.$eval('#package-info h3', el => el.textContent);
|
|
console.log('Package details showing:', packageName);
|
|
|
|
await page.screenshot({ path: 'playwright-output/nav-2-clicked.png', fullPage: true });
|
|
|
|
// Count nodes to see if view changed
|
|
const nodeCount = await page.$$eval('circle', circles => circles.length);
|
|
console.log('Number of nodes in view:', nodeCount);
|
|
}
|
|
|
|
await browser.close();
|
|
}
|
|
|
|
testClickSimple().catch(console.error); |