main
mjs 103 lines 3.87 KB
Raw
1 /**
2 * Visual spec for SquadScope — home page
3 *
4 * Run with:
5 * npx playwright test --config tests/visual/playwright.config.mjs
6 */
7
8 import { test, expect } from '@playwright/test';
9
10 // CSS injected into every page to suppress dynamic / noisy elements
11 const NOISE_SUPPRESSION_CSS = `
12 .cost-dashboard__date,
13 [data-cost-date],
14 .run-date,
15 .last-updated { visibility: hidden !important; }
16 .dynamic-counter, .repo-count, [data-live] { visibility: hidden !important; }
17 *, *::before, *::after { animation-duration: 0s !important; transition-duration: 0s !important; }
18 `;
19
20 async function settle(page) {
21 await page.waitForLoadState('networkidle').catch(() => page.waitForTimeout(1000));
22 await page.addStyleTag({ content: NOISE_SUPPRESSION_CSS });
23 await page.waitForTimeout(300); // font settle
24 }
25
26 // ---------------------------------------------------------------------------
27 // Home
28 // ---------------------------------------------------------------------------
29
30 test('home — full page', async ({ page }) => {
31 await page.goto('/');
32 await settle(page);
33 await expect(page).toHaveScreenshot('home.png', { fullPage: true });
34 });
35
36 // ---------------------------------------------------------------------------
37 // About / cost transparency
38 // ---------------------------------------------------------------------------
39
40 test('about — full page', async ({ page }) => {
41 await page.goto('/about/');
42 await settle(page);
43 await expect(page).toHaveScreenshot('about.png', { fullPage: true });
44 });
45
46 // ---------------------------------------------------------------------------
47 // Latest weekly
48 // ---------------------------------------------------------------------------
49
50 test('weekly w22 — full page', async ({ page }) => {
51 await page.goto('/weekly/2026/w22/');
52 await settle(page);
53 await expect(page).toHaveScreenshot('weekly-w22.png', { fullPage: true });
54 });
55
56 // ---------------------------------------------------------------------------
57 // Monthly rollup
58 // ---------------------------------------------------------------------------
59
60 test('monthly may 2026 — full page', async ({ page }) => {
61 await page.goto('/monthly/2026/05/');
62 await settle(page);
63 await expect(page).toHaveScreenshot('monthly-may.png', { fullPage: true });
64 });
65
66 // ---------------------------------------------------------------------------
67 // Yearly rollup
68 // ---------------------------------------------------------------------------
69
70 test('yearly 2026 — full page', async ({ page }) => {
71 await page.goto('/yearly/2026/');
72 await settle(page);
73 await expect(page).toHaveScreenshot('yearly-2026.png', { fullPage: true });
74 });
75
76 // ---------------------------------------------------------------------------
77 // Cover image / fallback visual placement (#358)
78 // ---------------------------------------------------------------------------
79
80 test('weekly article — cover card renders above content', async ({ page }) => {
81 await page.goto('/weekly/2026/w22/');
82 await settle(page);
83 const cover = page.locator('.article-cover');
84 await expect(cover).toBeVisible();
85 // Verify the cover is spatially above the article content
86 const content = page.locator('.post-content, article .content, .entry-content').first();
87 const coverBox = await cover.boundingBox();
88 const contentBox = await content.boundingBox();
89 if (coverBox && contentBox) {
90 expect(coverBox.y).toBeLessThan(contentBox.y);
91 }
92 await expect(cover).toHaveScreenshot('weekly-cover-card.png');
93 });
94
95 test('weekly article — cover card responsive (mobile)', async ({ page, browserName }, testInfo) => {
96 // Only run in mobile projects to avoid redundant viewport override
97 test.skip(!testInfo.project.name.includes('mobile'), 'mobile-only test');
98 await page.goto('/weekly/2026/w22/');
99 await settle(page);
100 const cover = page.locator('.article-cover');
101 await expect(cover).toBeVisible();
102 await expect(cover).toHaveScreenshot('weekly-cover-card-mobile.png');
103 });