Skip to content

Commit d2c4e8a

Browse files
committed
test: update visual tests to work with new design
1 parent ad3a31b commit d2c4e8a

File tree

4 files changed

+246
-12
lines changed

4 files changed

+246
-12
lines changed

playwright.config.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,21 @@ export default defineConfig({
4141
name: 'webkit',
4242
use: { ...devices['Desktop Safari'] },
4343
},
44+
// Project specifically for visual testing with stable configuration
45+
{
46+
name: 'visual-tests',
47+
testMatch: /.*\.spec\.ts/,
48+
use: {
49+
...devices['Desktop Chrome'],
50+
viewport: { width: 1280, height: 720 },
51+
deviceScaleFactor: 1,
52+
colorScheme: 'light',
53+
// Ensure consistent rendering for visual tests
54+
launchOptions: {
55+
args: ['--font-render-hinting=none', '--disable-gpu-rasterization']
56+
}
57+
},
58+
},
4459
],
4560

4661
webServer: {
@@ -49,5 +64,6 @@ export default defineConfig({
4964
reuseExistingServer: !process.env.CI,
5065
stdout: 'pipe',
5166
stderr: 'pipe',
67+
timeout: 60000, // Give more time for the server to start, especially in CI
5268
},
5369
});

tests/layout.spec.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { test, expect } from '@playwright/test';
7+
8+
// This test file focuses on the layout structure
9+
test.describe('Layout Tests', () => {
10+
// Test the two-column layout on desktop
11+
test('two-column desktop layout', async ({ page }) => {
12+
// Set viewport to desktop size
13+
await page.setViewportSize({ width: 1280, height: 800 });
14+
await page.goto('/');
15+
16+
// Wait for content to load
17+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
18+
19+
// Check for the SidebarControls component if it exists in the new layout
20+
const hasSidebar = await page.isVisible('.sidebar-controls, [role="search"], .filters');
21+
22+
if (hasSidebar) {
23+
// Take a screenshot of the full layout
24+
await expect(page).toHaveScreenshot('desktop-two-column-layout.png', {
25+
timeout: 5000,
26+
maxDiffPixelRatio: 0.05,
27+
threshold: 0.2,
28+
});
29+
30+
// Perform a sidebar interaction if possible (like changing a filter)
31+
// and verify the layout maintains its structure
32+
if (await page.isVisible('select')) {
33+
await page.selectOption('select:nth-of-type(1)', 'merged');
34+
await page.waitForTimeout(500); // Wait for content to update
35+
36+
await expect(page).toHaveScreenshot('desktop-two-column-layout-filtered.png', {
37+
timeout: 5000,
38+
maxDiffPixelRatio: 0.05,
39+
threshold: 0.2,
40+
});
41+
}
42+
} else {
43+
// If no sidebar is present, just verify the standard layout
44+
await expect(page).toHaveScreenshot('desktop-layout.png', {
45+
timeout: 5000,
46+
maxDiffPixelRatio: 0.05,
47+
threshold: 0.2,
48+
});
49+
}
50+
});
51+
52+
// Test responsive layout adaptation on different devices
53+
test('responsive layout adaptation', async ({ page }) => {
54+
// Start with mobile view (should be single column)
55+
await page.setViewportSize({ width: 375, height: 667 });
56+
await page.goto('/');
57+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
58+
59+
await expect(page).toHaveScreenshot('mobile-layout.png', {
60+
timeout: 5000,
61+
maxDiffPixelRatio: 0.05,
62+
threshold: 0.2,
63+
});
64+
65+
// Check tablet view
66+
await page.setViewportSize({ width: 768, height: 1024 });
67+
await page.goto('/');
68+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
69+
70+
await expect(page).toHaveScreenshot('tablet-layout.png', {
71+
timeout: 5000,
72+
maxDiffPixelRatio: 0.05,
73+
threshold: 0.2,
74+
});
75+
76+
// Check larger desktop view
77+
await page.setViewportSize({ width: 1440, height: 900 });
78+
await page.goto('/');
79+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
80+
81+
await expect(page).toHaveScreenshot('large-desktop-layout.png', {
82+
timeout: 5000,
83+
maxDiffPixelRatio: 0.05,
84+
threshold: 0.2,
85+
});
86+
});
87+
});

tests/ui-components.spec.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import { test, expect } from '@playwright/test';
7+
8+
// This test file specifically focuses on UI components in isolation
9+
test.describe('UI Components Tests', () => {
10+
// We'll create a simple test page that renders the components
11+
// This approach ensures we can test components independent of the main application
12+
13+
// Test pagination component
14+
test('pagination component visual test', async ({ page }) => {
15+
// First navigate to the homepage
16+
await page.goto('/');
17+
18+
// Wait for the pagination component to be visible
19+
// This test will be skipped if pagination isn't shown (e.g., not enough entries)
20+
if (await page.isVisible('nav[aria-label="Pagination"]')) {
21+
// Take a screenshot of the pagination component
22+
await expect(page.locator('nav[aria-label="Pagination"]')).toHaveScreenshot('pagination-component.png', {
23+
timeout: 5000,
24+
maxDiffPixelRatio: 0.05,
25+
threshold: 0.2,
26+
});
27+
28+
// Click the next page button to see styling changes
29+
const nextButton = page.locator('button[aria-label="Next page"]');
30+
if (await nextButton.isEnabled()) {
31+
await nextButton.click();
32+
await page.waitForTimeout(300); // Wait for any transitions
33+
34+
await expect(page.locator('nav[aria-label="Pagination"]')).toHaveScreenshot('pagination-component-next.png', {
35+
timeout: 5000,
36+
maxDiffPixelRatio: 0.05,
37+
threshold: 0.2,
38+
});
39+
}
40+
} else {
41+
test.skip();
42+
}
43+
});
44+
45+
// Test the filtering mechanism
46+
test('filter components visual test', async ({ page }) => {
47+
await page.goto('/');
48+
49+
// Check if select elements exist
50+
if (await page.isVisible('select')) {
51+
// Take a screenshot of the filters
52+
await expect(page.locator('div[role="search"]')).toHaveScreenshot('filter-components.png', {
53+
timeout: 5000,
54+
maxDiffPixelRatio: 0.05,
55+
threshold: 0.2,
56+
});
57+
58+
// Test interaction with the filters
59+
await page.selectOption('select:nth-of-type(1)', 'merged');
60+
await page.waitForTimeout(300);
61+
62+
await expect(page.locator('div[role="search"]')).toHaveScreenshot('filter-components-selected.png', {
63+
timeout: 5000,
64+
maxDiffPixelRatio: 0.05,
65+
threshold: 0.2,
66+
});
67+
} else {
68+
test.skip();
69+
}
70+
});
71+
72+
// Test individual entry card
73+
test('entry card visual test', async ({ page }) => {
74+
await page.goto('/');
75+
76+
// Wait for entries to load
77+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
78+
79+
// Take a screenshot of the first entry card
80+
await expect(page.locator('[data-testid="changelog-entry"]:first-of-type')).toHaveScreenshot('entry-card.png', {
81+
timeout: 5000,
82+
maxDiffPixelRatio: 0.05,
83+
threshold: 0.2,
84+
});
85+
86+
// Test dark mode version of the card
87+
await page.emulateMedia({ colorScheme: 'dark' });
88+
await page.reload();
89+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
90+
91+
await expect(page.locator('[data-testid="changelog-entry"]:first-of-type')).toHaveScreenshot('entry-card-dark.png', {
92+
timeout: 5000,
93+
maxDiffPixelRatio: 0.05,
94+
threshold: 0.2,
95+
});
96+
});
97+
});

tests/visual.spec.ts

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ test.describe('Visual Regression Tests', () => {
99
test('homepage visual test', async ({ page }) => {
1010
await page.goto('/');
1111

12-
// Wait for content to be loaded
12+
// Wait for content to be fully loaded
1313
await page.waitForSelector('h1');
14+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
1415

1516
// Compare the screenshot with a reference
1617
// Use updateSnapshots flag in CI to automate snapshot creation
1718
await expect(page).toHaveScreenshot('homepage.png', {
18-
timeout: 5000,
19+
timeout: 10000,
1920
maxDiffPixelRatio: 0.05, // Allow 5% difference
2021
threshold: 0.2, // More tolerant threshold for CI variations
2122
});
@@ -27,8 +28,10 @@ test.describe('Visual Regression Tests', () => {
2728
await page.setViewportSize({ width: 375, height: 667 });
2829
await page.goto('/');
2930
await page.waitForSelector('h1');
31+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
32+
3033
await expect(page).toHaveScreenshot('homepage-mobile.png', {
31-
timeout: 5000,
34+
timeout: 10000,
3235
maxDiffPixelRatio: 0.05,
3336
threshold: 0.2,
3437
});
@@ -37,8 +40,10 @@ test.describe('Visual Regression Tests', () => {
3740
await page.setViewportSize({ width: 768, height: 1024 });
3841
await page.goto('/');
3942
await page.waitForSelector('h1');
43+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
44+
4045
await expect(page).toHaveScreenshot('homepage-tablet.png', {
41-
timeout: 5000,
46+
timeout: 10000,
4247
maxDiffPixelRatio: 0.05,
4348
threshold: 0.2,
4449
});
@@ -47,28 +52,57 @@ test.describe('Visual Regression Tests', () => {
4752
await page.setViewportSize({ width: 1280, height: 800 });
4853
await page.goto('/');
4954
await page.waitForSelector('h1');
55+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
56+
5057
await expect(page).toHaveScreenshot('homepage-desktop.png', {
51-
timeout: 5000,
58+
timeout: 10000,
5259
maxDiffPixelRatio: 0.05,
5360
threshold: 0.2,
5461
});
5562
});
5663

57-
// Test dark mode if applicable
64+
// Test dark mode
5865
test('dark mode visual test', async ({ page }) => {
5966
await page.goto('/');
6067

61-
// Enable dark mode if your app has a way to toggle it
62-
// This is hypothetical and would need to be adjusted for your actual app
63-
await page.evaluate(() => {
64-
document.documentElement.classList.add('dark');
65-
});
68+
// Emulate dark mode using prefers-color-scheme
69+
await page.emulateMedia({ colorScheme: 'dark' });
6670

71+
// Wait for content to be fully loaded
6772
await page.waitForSelector('h1');
73+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
74+
6875
await expect(page).toHaveScreenshot('homepage-dark-mode.png', {
69-
timeout: 5000,
76+
timeout: 10000,
7077
maxDiffPixelRatio: 0.05,
7178
threshold: 0.2,
7279
});
7380
});
81+
82+
// Test filter interactions
83+
test('filter interaction test', async ({ page }) => {
84+
await page.goto('/');
85+
86+
// Wait for content to be fully loaded
87+
await page.waitForSelector('[data-testid="changelog-entry"]', { timeout: 10000 });
88+
89+
// If SidebarControls is visible in the layout
90+
if (await page.isVisible('select:has([value="all"])')) {
91+
// Click on status filter dropdown and select 'Merged'
92+
await page.selectOption('select:nth-of-type(1)', 'merged');
93+
94+
// Wait for the filtered results to update
95+
await page.waitForTimeout(500);
96+
97+
// Take a screenshot of the filtered results
98+
await expect(page).toHaveScreenshot('homepage-filtered-by-status.png', {
99+
timeout: 5000,
100+
maxDiffPixelRatio: 0.05,
101+
threshold: 0.2,
102+
});
103+
104+
// Reset filter back to 'All'
105+
await page.selectOption('select:nth-of-type(1)', 'all');
106+
}
107+
});
74108
});

0 commit comments

Comments
 (0)