mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-08-28 05:25:25 +00:00
* feat: configure eslint with unused import removal Add ESLint v9 (flat config) for code quality: - eslint-plugin-unused-imports for auto-removing dead imports - @typescript-eslint for TypeScript-aware linting - eslint-plugin-react-hooks for React hooks rules - eslint-config-prettier to avoid formatting conflicts - lint-staged runs eslint --fix before prettier on .ts/.tsx - CI lint job added to ci-quality.yml * refactor: remove unused imports via eslint --fix Auto-fixed by eslint-plugin-unused-imports. No logic changes. * chore: add eslint fix commit to .git-blame-ignore-revs
133 lines
5.1 KiB
TypeScript
133 lines
5.1 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
/**
|
|
* Debug harnesses for investigating specific UI issues.
|
|
* Excluded from `npm run test:e2e` via testIgnore in playwright.config.ts.
|
|
* Run directly: DEBUG_E2E=1 npx playwright test e2e/debug-issues.spec.ts
|
|
*/
|
|
const BACKEND_URL = process.env.BACKEND_URL ?? 'http://localhost:4747';
|
|
const debugTest = process.env.DEBUG_E2E ? test : test.skip;
|
|
|
|
async function connectToServer(page: import('@playwright/test').Page) {
|
|
page.on('console', (msg) => {
|
|
if (msg.type() === 'error') console.log(`[error] ${msg.text()}`);
|
|
});
|
|
|
|
await page.goto('/');
|
|
await page.getByText('Server').click();
|
|
const serverInput = page.locator('input[name="server-url-input"]');
|
|
await serverInput.fill(BACKEND_URL);
|
|
await page.getByRole('button', { name: /Connect/ }).click();
|
|
await expect(page.locator('[data-testid="status-ready"]')).toBeVisible({ timeout: 30_000 });
|
|
// Wait for LadybugDB to finish loading — poll isDatabaseReady via process list visibility
|
|
await expect(page.locator('[data-testid="status-ready"]')).toBeVisible({ timeout: 30_000 });
|
|
}
|
|
|
|
debugTest('debug: process view Reset View button', async ({ page }, testInfo) => {
|
|
await connectToServer(page);
|
|
|
|
// Open Processes tab
|
|
await page.getByRole('button', { name: 'Nexus AI' }).click();
|
|
await page.getByText('Processes').click();
|
|
await expect(page.getByText(/\d+ processes detected/)).toBeVisible({ timeout: 10_000 });
|
|
|
|
// Click View on the first Cross-Community process
|
|
// The View button has opacity-0 by default, use JS click to bypass
|
|
const viewButtons = page.locator('button:has-text("View")');
|
|
const count = await viewButtons.count();
|
|
console.log(`Found ${count} View buttons`);
|
|
|
|
// Use evaluate to click the first one regardless of visibility
|
|
await page.evaluate(() => {
|
|
const btns = document.querySelectorAll('button');
|
|
for (const btn of btns) {
|
|
if (btn.textContent?.trim() === 'View') {
|
|
btn.click();
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
|
|
// Wait for modal to appear
|
|
const modal = page.locator('[data-testid="process-modal"]');
|
|
await expect(modal).toBeVisible({ timeout: 5_000 });
|
|
|
|
// Screenshot: modal should be open with flowchart
|
|
await page.screenshot({ path: testInfo.outputPath('debug-modal-open.png'), fullPage: true });
|
|
|
|
// Get the diagram's current transform
|
|
const diagramDiv = modal.locator('[style*="transform"]');
|
|
const transformBefore = await diagramDiv.getAttribute('style');
|
|
console.log('Transform BEFORE zoom:', transformBefore);
|
|
|
|
// Zoom in using the + button
|
|
const zoomInBtn = modal.getByRole('button', { name: /Zoom in/ });
|
|
await zoomInBtn.click();
|
|
await zoomInBtn.click();
|
|
await zoomInBtn.click();
|
|
// Wait for zoom animation to settle
|
|
await expect(async () => {
|
|
const t = await diagramDiv.getAttribute('style');
|
|
expect(t).not.toBe(transformBefore);
|
|
}).toPass({ timeout: 2_000 });
|
|
|
|
const transformAfterZoom = await diagramDiv.getAttribute('style');
|
|
console.log('Transform AFTER zoom:', transformAfterZoom);
|
|
await page.screenshot({ path: testInfo.outputPath('debug-modal-zoomed.png'), fullPage: true });
|
|
|
|
// Click Reset View
|
|
const resetBtn = modal.getByRole('button', { name: 'Reset View' });
|
|
await resetBtn.click();
|
|
// Wait for reset animation to settle
|
|
await expect(async () => {
|
|
const t = await diagramDiv.getAttribute('style');
|
|
expect(t).toBe(transformBefore);
|
|
}).toPass({ timeout: 2_000 });
|
|
|
|
const transformAfterReset = await diagramDiv.getAttribute('style');
|
|
console.log('Transform AFTER reset:', transformAfterReset);
|
|
await page.screenshot({
|
|
path: testInfo.outputPath('debug-modal-after-reset.png'),
|
|
fullPage: true,
|
|
});
|
|
|
|
// Verify transform actually changed back
|
|
expect(transformAfterZoom).not.toBe(transformBefore);
|
|
expect(transformAfterReset).toBe(transformBefore);
|
|
});
|
|
|
|
debugTest('debug: lightbulb clears node selection dimming', async ({ page }, testInfo) => {
|
|
await connectToServer(page);
|
|
|
|
// Wait for graph canvas to render
|
|
await expect(page.locator('canvas').first()).toBeVisible({ timeout: 10_000 });
|
|
|
|
await page.screenshot({ path: testInfo.outputPath('debug-before-select.png'), fullPage: true });
|
|
|
|
// Click a file in the tree to select a node (causes dimming)
|
|
const fileItem = page.getByText('start.sh');
|
|
await fileItem.click();
|
|
await page.waitForTimeout(500);
|
|
await page.screenshot({ path: testInfo.outputPath('debug-node-selected.png'), fullPage: true });
|
|
|
|
// Check the lightbulb button state
|
|
const lightbulbBtn = page.locator('button[title*="Turn off"], button[title*="Turn on"]');
|
|
const title = await lightbulbBtn.getAttribute('title');
|
|
console.log('Lightbulb title before click:', title);
|
|
|
|
// Click the lightbulb
|
|
await lightbulbBtn.click();
|
|
await page.waitForTimeout(500);
|
|
|
|
const titleAfter = await lightbulbBtn.getAttribute('title');
|
|
console.log('Lightbulb title after click:', titleAfter);
|
|
await page.screenshot({ path: testInfo.outputPath('debug-after-lightbulb.png'), fullPage: true });
|
|
|
|
// Click it again to toggle back on
|
|
await lightbulbBtn.click();
|
|
await page.waitForTimeout(500);
|
|
await page.screenshot({
|
|
path: testInfo.outputPath('debug-after-lightbulb-toggle-back.png'),
|
|
fullPage: true,
|
|
});
|
|
});
|