Skip to content

Commit b3c8503

Browse files
Test Userclaude
andcommitted
test(qa): add automated QA tests for PR #92 UX Revamp
- Generated by Night Watch QA agent - UI tests: 13 tests covering Command Palette, Activity Center, Log Filters - Tests verify keyboard shortcuts (Ctrl+K), navigation, filtering, and UI structure - Artifacts: screenshots and videos captured for visual evidence Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ea855cb commit b3c8503

File tree

2 files changed

+207
-0
lines changed

2 files changed

+207
-0
lines changed

web/playwright.config.run.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
export default defineConfig({
4+
testDir: './tests/e2e/qa',
5+
fullyParallel: false,
6+
forbidOnly: false,
7+
retries: 0,
8+
workers: 1,
9+
reporter: [['html'], ['list']],
10+
11+
use: {
12+
baseURL: 'http://localhost:7576',
13+
trace: 'retain-on-failure',
14+
screenshot: 'on',
15+
video: {
16+
mode: 'on',
17+
size: { width: 1280, height: 720 },
18+
},
19+
},
20+
21+
projects: [
22+
{
23+
name: 'chromium',
24+
use: { ...devices['Desktop Chrome'] },
25+
},
26+
],
27+
28+
// Don't start a server - use existing
29+
webServer: undefined,
30+
});
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
/**
4+
* E2E tests for UX Revamp: Command Palette, Activity Center, Log Filters
5+
* PR #92: feat(web): UX Revamp - Command Palette, Activity Center, Log Filters
6+
*/
7+
test.describe('UX Revamp - Command Palette', () => {
8+
test.beforeEach(async ({ page }) => {
9+
await page.goto('#/');
10+
await page.waitForLoadState('networkidle');
11+
// Wait for app to be ready
12+
await page.waitForTimeout(2000);
13+
});
14+
15+
test('should open command palette with Ctrl+K keyboard shortcut', async ({ page }) => {
16+
// Press Ctrl+K to open command palette
17+
await page.keyboard.press('Control+k');
18+
19+
// Command palette should be visible
20+
const commandPalette = page.locator('[data-command-palette]');
21+
await expect(commandPalette).toBeVisible({ timeout: 10000 });
22+
23+
// Take screenshot
24+
await page.screenshot({ path: 'test-results/command-palette-open.png', fullPage: false });
25+
});
26+
27+
test('should display navigation commands in command palette', async ({ page }) => {
28+
await page.keyboard.press('Control+k');
29+
await page.waitForTimeout(500);
30+
31+
// Check for navigation category - using more flexible selector
32+
const navigateCategory = page.locator('text=/navigate/i');
33+
await expect(navigateCategory.first()).toBeVisible({ timeout: 5000 });
34+
35+
// Check for common navigation commands
36+
await expect(page.locator('text=Dashboard')).toBeVisible();
37+
await expect(page.locator('text=Logs')).toBeVisible();
38+
39+
await page.screenshot({ path: 'test-results/command-palette-navigation.png', fullPage: false });
40+
});
41+
42+
test('should filter commands by search term', async ({ page }) => {
43+
await page.keyboard.press('Control+k');
44+
await page.waitForTimeout(500);
45+
46+
// Type search term
47+
const input = page.locator('[data-command-palette] input');
48+
await input.fill('log');
49+
50+
// Should show Logs command
51+
await expect(page.locator('button:has-text("Logs")')).toBeVisible();
52+
53+
await page.screenshot({ path: 'test-results/command-palette-filtered.png', fullPage: false });
54+
});
55+
56+
test('should close command palette with Escape', async ({ page }) => {
57+
await page.keyboard.press('Control+k');
58+
await page.waitForTimeout(500);
59+
60+
// Command palette should be visible
61+
await expect(page.locator('[data-command-palette]')).toBeVisible();
62+
63+
// Press Escape
64+
await page.keyboard.press('Escape');
65+
66+
// Command palette should be hidden
67+
await expect(page.locator('[data-command-palette]')).not.toBeVisible({ timeout: 5000 });
68+
});
69+
70+
test('should navigate to Logs page when selecting Logs command', async ({ page }) => {
71+
await page.keyboard.press('Control+k');
72+
await page.waitForTimeout(500);
73+
74+
// Click on Logs command
75+
await page.click('button:has-text("Logs")');
76+
77+
// Should navigate to logs page
78+
await expect(page).toHaveURL(/.*#\/logs/);
79+
80+
await page.screenshot({ path: 'test-results/navigated-to-logs.png', fullPage: false });
81+
});
82+
});
83+
84+
test.describe('UX Revamp - Activity Center', () => {
85+
test.beforeEach(async ({ page }) => {
86+
await page.goto('#/');
87+
await page.waitForLoadState('networkidle');
88+
await page.waitForTimeout(2000);
89+
});
90+
91+
test('should have activity center button in top bar', async ({ page }) => {
92+
// Check for bell icon button using svg selector
93+
const bellButton = page.locator('button').filter({ has: page.locator('svg') }).nth(0);
94+
await expect(bellButton.first()).toBeVisible();
95+
96+
await page.screenshot({ path: 'test-results/top-bar-activity-button.png', fullPage: false });
97+
});
98+
99+
test('should open activity center when clicking bell icon', async ({ page }) => {
100+
// Find and click the bell icon button
101+
const bellButton = page.locator('button').filter({ has: page.locator('svg.lucide-bell, svg[class*="bell"]') });
102+
await bellButton.first().click();
103+
104+
// Activity center panel should be visible
105+
await expect(page.locator('text=/activity/i')).toBeVisible({ timeout: 5000 });
106+
107+
await page.screenshot({ path: 'test-results/activity-center-open.png', fullPage: false });
108+
});
109+
});
110+
111+
test.describe('UX Revamp - Log Filters', () => {
112+
test.beforeEach(async ({ page }) => {
113+
await page.goto('#/logs');
114+
await page.waitForLoadState('networkidle');
115+
await page.waitForTimeout(2000);
116+
});
117+
118+
test('should display log filter bar on logs page', async ({ page }) => {
119+
// Check for filter elements - look for buttons with agent names or "All"
120+
const allButton = page.locator('button:has-text("All")');
121+
await expect(allButton.first()).toBeVisible({ timeout: 10000 });
122+
123+
await page.screenshot({ path: 'test-results/log-filter-bar.png', fullPage: false });
124+
});
125+
126+
test('should display search input for log filtering', async ({ page }) => {
127+
// Check for search input with filter placeholder
128+
const searchInput = page.locator('input[placeholder*="filter" i], input[placeholder*="search" i]');
129+
await expect(searchInput.first()).toBeVisible({ timeout: 5000 });
130+
});
131+
132+
test('should display agent filter pills', async ({ page }) => {
133+
// Check for agent pills (Executor, Reviewer, etc.)
134+
const executorPill = page.locator('button:has-text("Executor")');
135+
await expect(executorPill.first()).toBeVisible({ timeout: 5000 });
136+
137+
await page.screenshot({ path: 'test-results/log-agent-pills.png', fullPage: false });
138+
});
139+
140+
test('should display errors only checkbox', async ({ page }) => {
141+
// Check for errors only toggle
142+
const errorToggle = page.locator('text=/error.*only/i, label:has(input[type="checkbox"])');
143+
await expect(errorToggle.first()).toBeVisible({ timeout: 5000 });
144+
});
145+
});
146+
147+
test.describe('UX Revamp - Integration', () => {
148+
test.beforeEach(async ({ page }) => {
149+
await page.goto('#/');
150+
await page.waitForLoadState('networkidle');
151+
await page.waitForTimeout(2000);
152+
});
153+
154+
test('should navigate from command palette to logs and see filters', async ({ page }) => {
155+
// Open command palette
156+
await page.keyboard.press('Control+k');
157+
await expect(page.locator('[data-command-palette]')).toBeVisible({ timeout: 5000 });
158+
159+
// Navigate to logs
160+
await page.click('button:has-text("Logs")');
161+
await expect(page).toHaveURL(/.*#\/logs/);
162+
163+
// Log filters should be visible
164+
const allButton = page.locator('button:has-text("All")');
165+
await expect(allButton.first()).toBeVisible({ timeout: 5000 });
166+
167+
await page.screenshot({ path: 'test-results/integration-logs-filters.png', fullPage: false });
168+
});
169+
170+
test('should display top bar with status indicator', async ({ page }) => {
171+
// Check for online status indicator
172+
const statusIndicator = page.locator('text=/online|offline/i');
173+
await expect(statusIndicator.first()).toBeVisible({ timeout: 5000 });
174+
175+
await page.screenshot({ path: 'test-results/top-bar-status.png', fullPage: false });
176+
});
177+
});

0 commit comments

Comments
 (0)