[Bug] "Configure" window superimposed on underlying UI elements #14
This commit is contained in:
parent
559205e7c0
commit
295a95d4ae
8 changed files with 167 additions and 2 deletions
81
frontend/e2e/configure-modal.spec.ts
Normal file
81
frontend/e2e/configure-modal.spec.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Configure Modal (Issue #14)', () => {
|
||||
test('Configure modal has proper backdrop overlay', async ({ page }) => {
|
||||
// Navigate to the app
|
||||
await page.goto('/app');
|
||||
|
||||
// Wait for page to load
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Check if there are any projects listed
|
||||
const projectCards = page.locator('[class*="card"]').filter({ hasText: /Configure|Settings/ });
|
||||
|
||||
// If no projects, check that we see the "No projects" message or create project button
|
||||
const noProjectsMessage = page.getByText('No projects yet');
|
||||
const hasNoProjects = await noProjectsMessage.isVisible().catch(() => false);
|
||||
|
||||
if (hasNoProjects) {
|
||||
console.log('No projects found - skipping configure modal test');
|
||||
return;
|
||||
}
|
||||
|
||||
// Find and click the Settings/Configure button on first project
|
||||
const settingsButton = page.locator('button').filter({ has: page.locator('svg') }).first();
|
||||
|
||||
// Look for a settings icon button
|
||||
const configureButton = page.locator('[title="Setup project"], [title="Configure"]').first();
|
||||
|
||||
if (await configureButton.isVisible()) {
|
||||
await configureButton.click();
|
||||
|
||||
// Wait for modal to appear
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Check that the modal backdrop exists with proper styling
|
||||
const backdrop = page.locator('.fixed.inset-0').filter({ has: page.locator('.card') });
|
||||
|
||||
// Verify backdrop has semi-transparent background (bg-black/50)
|
||||
const backdropElement = backdrop.first();
|
||||
if (await backdropElement.isVisible()) {
|
||||
const bgClass = await backdropElement.getAttribute('class');
|
||||
|
||||
// Check for semi-transparent background class
|
||||
expect(bgClass).toContain('bg-black/50');
|
||||
|
||||
// Verify clicking outside closes the modal
|
||||
await backdropElement.click({ position: { x: 10, y: 10 } });
|
||||
|
||||
// Modal should be closed
|
||||
await expect(backdrop).not.toBeVisible({ timeout: 2000 });
|
||||
|
||||
console.log('✅ Configure modal has proper backdrop and closes on outside click');
|
||||
}
|
||||
} else {
|
||||
console.log('No configure button found');
|
||||
}
|
||||
});
|
||||
|
||||
test('Configure modal can be closed with X button', async ({ page }) => {
|
||||
await page.goto('/app');
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Find configure/settings button
|
||||
const configureButton = page.locator('[title="Setup project"]').first();
|
||||
|
||||
if (await configureButton.isVisible().catch(() => false)) {
|
||||
await configureButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Find and click the close button (X)
|
||||
const closeButton = page.locator('button').filter({ hasText: '✕' });
|
||||
await closeButton.click();
|
||||
|
||||
// Verify modal is closed
|
||||
const modal = page.locator('.fixed.inset-0').filter({ has: page.locator('.card') });
|
||||
await expect(modal).not.toBeVisible({ timeout: 2000 });
|
||||
|
||||
console.log('✅ Configure modal closes with X button');
|
||||
}
|
||||
});
|
||||
});
|
||||
47
frontend/e2e/screenshot-test.spec.ts
Normal file
47
frontend/e2e/screenshot-test.spec.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('Take screenshot of configure modal', async ({ page }) => {
|
||||
// Navigate to the app
|
||||
await page.goto('/app');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Take screenshot of projects page
|
||||
await page.screenshot({ path: 'e2e/screenshots/projects-page.png', fullPage: true });
|
||||
|
||||
// Click on a project in the sidebar to select it
|
||||
const projectItem = page.locator('text=diatrak').first();
|
||||
if (await projectItem.isVisible()) {
|
||||
await projectItem.click();
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Take screenshot after selecting project
|
||||
await page.screenshot({ path: 'e2e/screenshots/project-selected.png', fullPage: true });
|
||||
|
||||
// Now look for Configure button
|
||||
const configureButton = page.getByRole('button', { name: /Configure/i });
|
||||
const configVisible = await configureButton.isVisible().catch(() => false);
|
||||
console.log(`Configure button visible: ${configVisible}`);
|
||||
|
||||
if (configVisible) {
|
||||
await configureButton.click();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Take screenshot of the modal
|
||||
await page.screenshot({ path: 'e2e/screenshots/configure-modal.png', fullPage: true });
|
||||
|
||||
// Check if backdrop has correct class
|
||||
const backdrop = page.locator('.bg-black\\/50');
|
||||
const backdropVisible = await backdrop.isVisible().catch(() => false);
|
||||
console.log(`Backdrop with bg-black/50 visible: ${backdropVisible}`);
|
||||
|
||||
expect(backdropVisible).toBe(true);
|
||||
} else {
|
||||
// Try looking for Settings icon button
|
||||
const settingsBtn = page.locator('[title*="Setup"], button:has(svg)').filter({ hasText: '' });
|
||||
console.log(`Settings buttons found: ${await settingsBtn.count()}`);
|
||||
}
|
||||
} else {
|
||||
console.log('No project found to click');
|
||||
}
|
||||
});
|
||||
BIN
frontend/e2e/screenshots/configure-modal.png
Normal file
BIN
frontend/e2e/screenshots/configure-modal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 125 KiB |
BIN
frontend/e2e/screenshots/project-selected.png
Normal file
BIN
frontend/e2e/screenshots/project-selected.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
BIN
frontend/e2e/screenshots/projects-page.png
Normal file
BIN
frontend/e2e/screenshots/projects-page.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
26
frontend/playwright.config.ts
Normal file
26
frontend/playwright.config.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
testDir: './e2e',
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
baseURL: 'http://localhost:5173',
|
||||
trace: 'on-first-retry',
|
||||
screenshot: 'only-on-failure',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
webServer: {
|
||||
command: 'npm run dev',
|
||||
url: 'http://localhost:5173',
|
||||
reuseExistingServer: true,
|
||||
},
|
||||
});
|
||||
|
|
@ -97,11 +97,18 @@ export default function ProjectSetup({
|
|||
];
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 flex items-center justify-center z-50 p-4 bg-dark-navy">
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 flex items-center justify-center z-50 p-4 bg-black/50 backdrop-blur-sm"
|
||||
onClick={onClose}
|
||||
>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.95 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.95 }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className="card w-full max-w-4xl max-h-[90vh] overflow-hidden flex flex-col"
|
||||
>
|
||||
{/* Header */}
|
||||
|
|
@ -158,7 +165,7 @@ export default function ProjectSetup({
|
|||
</AnimatePresence>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
4
frontend/test-results/.last-run.json
Normal file
4
frontend/test-results/.last-run.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"status": "passed",
|
||||
"failedTests": []
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue