|
1 | 1 | /** |
2 | | - * E2E Integration Tests using shared test-site (FluffyCloud) |
| 2 | + * E2E tests for the Vizzly Vitest plugin |
3 | 3 | * |
4 | | - * These tests verify the Vitest plugin integration with Vizzly using |
5 | | - * the same test-site as other SDKs for visual consistency. |
| 4 | + * Tests the toMatchScreenshot matcher works correctly with: |
| 5 | + * - Page screenshots |
| 6 | + * - Element screenshots |
| 7 | + * - Properties/metadata |
| 8 | + * - Threshold options |
6 | 9 | * |
7 | | - * Uses custom commands to navigate Playwright to the test-site URLs. |
8 | | - * |
9 | | - * Local TDD mode: |
10 | | - * vizzly tdd start |
11 | | - * npm run test:e2e |
12 | | - * |
13 | | - * One-shot TDD mode: |
14 | | - * npm run test:e2e:tdd |
| 10 | + * Uses the shared test-site CSS for consistent styling. |
15 | 11 | */ |
16 | 12 |
|
17 | | -import { describe, expect, test } from 'vitest'; |
18 | | -import { commands, page } from 'vitest/browser'; |
| 13 | +import { beforeAll, describe, expect, test } from 'vitest'; |
| 14 | +import { page } from 'vitest/browser'; |
19 | 15 |
|
20 | | -// Base URL for test-site (defined in vitest.e2e.config.js) |
| 16 | +// Base URL for test-site assets (defined in vitest.e2e.config.js) |
21 | 17 | // eslint-disable-next-line no-undef |
22 | 18 | let baseUrl = __TEST_SITE_URL__; |
23 | 19 |
|
24 | | -describe('Homepage', () => { |
25 | | - test('full page screenshot', async () => { |
26 | | - await commands.loadPage(`${baseUrl}/index.html`); |
27 | | - await expect(page).toMatchScreenshot('homepage-full.png'); |
28 | | - }); |
29 | | - |
30 | | - test('navigation bar', async () => { |
31 | | - await commands.loadPage(`${baseUrl}/index.html`); |
32 | | - let nav = page.getByRole('navigation'); |
33 | | - await expect(nav).toMatchScreenshot('homepage-nav.png'); |
34 | | - }); |
35 | | - |
36 | | - test('hero section', async () => { |
37 | | - await commands.loadPage(`${baseUrl}/index.html`); |
38 | | - // Get hero by heading text |
39 | | - let hero = page.getByRole('heading', { name: 'Every Pet Deserves' }); |
40 | | - await expect(hero).toMatchScreenshot('homepage-hero.png'); |
41 | | - }); |
42 | | - |
43 | | - test('features heading', async () => { |
44 | | - await commands.loadPage(`${baseUrl}/index.html`); |
45 | | - // Get features section heading |
46 | | - let featuresHeading = page.getByRole('heading', { name: 'Why Choose FluffyCloud?' }); |
47 | | - await expect(featuresHeading).toMatchScreenshot('homepage-features-heading.png'); |
48 | | - }); |
49 | | -}); |
50 | | - |
51 | | -describe('Features Page', () => { |
52 | | - test('full page screenshot', async () => { |
53 | | - await commands.loadPage(`${baseUrl}/features.html`); |
54 | | - await expect(page).toMatchScreenshot('features-full.png'); |
55 | | - }); |
56 | | - |
57 | | - test('navigation bar', async () => { |
58 | | - await commands.loadPage(`${baseUrl}/features.html`); |
59 | | - let nav = page.getByRole('navigation'); |
60 | | - await expect(nav).toMatchScreenshot('features-nav.png'); |
61 | | - }); |
62 | | -}); |
63 | | - |
64 | | -describe('Pricing Page', () => { |
65 | | - test('full page screenshot', async () => { |
66 | | - await commands.loadPage(`${baseUrl}/pricing.html`); |
67 | | - await expect(page).toMatchScreenshot('pricing-full.png'); |
68 | | - }); |
69 | | - |
70 | | - test('pricing heading', async () => { |
71 | | - await commands.loadPage(`${baseUrl}/pricing.html`); |
72 | | - // Get the pricing section heading |
73 | | - let pricingHeading = page.getByRole('heading', { level: 1 }); |
74 | | - await expect(pricingHeading).toMatchScreenshot('pricing-heading.png'); |
| 20 | +// Load test-site CSS before all tests |
| 21 | +beforeAll(async () => { |
| 22 | + let link = document.createElement('link'); |
| 23 | + link.rel = 'stylesheet'; |
| 24 | + link.href = `${baseUrl}/dist/output.css`; |
| 25 | + document.head.appendChild(link); |
| 26 | + |
| 27 | + // Wait for CSS to load |
| 28 | + await new Promise((resolve) => { |
| 29 | + link.onload = resolve; |
| 30 | + link.onerror = resolve; |
75 | 31 | }); |
76 | 32 | }); |
77 | 33 |
|
78 | | -describe('Contact Page', () => { |
79 | | - test('full page screenshot', async () => { |
80 | | - await commands.loadPage(`${baseUrl}/contact.html`); |
81 | | - await expect(page).toMatchScreenshot('contact-full.png'); |
82 | | - }); |
| 34 | +describe('Vizzly Vitest Plugin', () => { |
| 35 | + test('page screenshot', async () => { |
| 36 | + document.body.innerHTML = ` |
| 37 | + <div class="p-8 bg-white"> |
| 38 | + <h1 class="text-3xl font-bold text-primary-600">Hello Vizzly</h1> |
| 39 | + <p class="text-gray-600 mt-2">Testing the Vitest plugin</p> |
| 40 | + </div> |
| 41 | + `; |
83 | 42 |
|
84 | | - test('contact heading', async () => { |
85 | | - await commands.loadPage(`${baseUrl}/contact.html`); |
86 | | - let heading = page.getByRole('heading', { level: 1 }); |
87 | | - await expect(heading).toMatchScreenshot('contact-heading.png'); |
| 43 | + await expect(page).toMatchScreenshot('page.png'); |
88 | 44 | }); |
89 | | -}); |
90 | 45 |
|
91 | | -describe('Screenshot Options', () => { |
92 | | - test('with custom threshold', async () => { |
93 | | - await commands.loadPage(`${baseUrl}/index.html`); |
94 | | - let nav = page.getByRole('navigation'); |
95 | | - await expect(nav).toMatchScreenshot('threshold-test.png', { |
96 | | - threshold: 5, |
97 | | - }); |
| 46 | + test('element screenshot', async () => { |
| 47 | + document.body.innerHTML = ` |
| 48 | + <div class="p-8"> |
| 49 | + <button class="bg-primary-600 hover:bg-primary-700 text-white px-6 py-3 rounded-lg font-medium"> |
| 50 | + Click me |
| 51 | + </button> |
| 52 | + </div> |
| 53 | + `; |
| 54 | + |
| 55 | + let button = page.getByRole('button'); |
| 56 | + await expect(button).toMatchScreenshot('button.png'); |
98 | 57 | }); |
99 | 58 |
|
100 | | - test('with properties', async () => { |
101 | | - await commands.loadPage(`${baseUrl}/index.html`); |
102 | | - await expect(page).toMatchScreenshot('props-test.png', { |
| 59 | + test('screenshot with properties', async () => { |
| 60 | + document.body.innerHTML = ` |
| 61 | + <div class="p-8"> |
| 62 | + <div class="bg-gray-900 text-white p-6 rounded-xl shadow-lg"> |
| 63 | + <h2 class="text-xl font-semibold">Dark Theme Card</h2> |
| 64 | + <p class="text-gray-300 mt-2">Component with metadata</p> |
| 65 | + </div> |
| 66 | + </div> |
| 67 | + `; |
| 68 | + |
| 69 | + await expect(page).toMatchScreenshot('card.png', { |
103 | 70 | properties: { |
104 | | - browser: 'chromium', |
105 | | - viewport: '1280x720', |
106 | | - page: 'homepage', |
| 71 | + theme: 'dark', |
| 72 | + component: 'card', |
107 | 73 | }, |
108 | 74 | }); |
109 | 75 | }); |
110 | 76 |
|
111 | | - test('element with threshold and properties', async () => { |
112 | | - await commands.loadPage(`${baseUrl}/index.html`); |
113 | | - let nav = page.getByRole('navigation'); |
114 | | - await expect(nav).toMatchScreenshot('combined-options.png', { |
115 | | - threshold: 3, |
116 | | - properties: { |
117 | | - component: 'navigation', |
118 | | - variant: 'default', |
119 | | - }, |
| 77 | + test('screenshot with threshold', async () => { |
| 78 | + document.body.innerHTML = ` |
| 79 | + <div class="p-8"> |
| 80 | + <span class="text-2xl font-bold text-red-500">Warning!</span> |
| 81 | + </div> |
| 82 | + `; |
| 83 | + |
| 84 | + await expect(page).toMatchScreenshot('warning.png', { |
| 85 | + threshold: 5, |
120 | 86 | }); |
121 | 87 | }); |
122 | | -}); |
123 | 88 |
|
124 | | -describe('Cross-Page Navigation', () => { |
125 | | - test('captures multiple pages in sequence', async () => { |
126 | | - let pages = ['index.html', 'features.html', 'pricing.html', 'contact.html']; |
| 89 | + test('multiple elements in sequence', async () => { |
| 90 | + document.body.innerHTML = ` |
| 91 | + <nav class="flex gap-6 p-4 bg-gray-100 rounded-lg"> |
| 92 | + <a href="#" class="text-primary-600 font-medium">Home</a> |
| 93 | + <a href="#" class="text-gray-600 hover:text-primary-600">About</a> |
| 94 | + <a href="#" class="text-gray-600 hover:text-primary-600">Contact</a> |
| 95 | + </nav> |
| 96 | + `; |
127 | 97 |
|
128 | | - for (let pageName of pages) { |
129 | | - await commands.loadPage(`${baseUrl}/${pageName}`); |
130 | | - let nav = page.getByRole('navigation'); |
131 | | - await expect(nav).toMatchScreenshot(`nav-${pageName.replace('.html', '')}.png`, { |
132 | | - properties: { page: pageName }, |
133 | | - }); |
134 | | - } |
135 | | - }); |
136 | | -}); |
| 98 | + let nav = page.getByRole('navigation'); |
| 99 | + await expect(nav).toMatchScreenshot('nav.png'); |
137 | 100 |
|
138 | | -describe('Footer', () => { |
139 | | - test('footer brand on homepage', async () => { |
140 | | - await commands.loadPage(`${baseUrl}/index.html`); |
141 | | - // Get footer by text |
142 | | - let footerBrand = page.getByText('FluffyCloud', { exact: false }).last(); |
143 | | - await expect(footerBrand).toMatchScreenshot('footer-brand.png'); |
| 101 | + let homeLink = page.getByRole('link', { name: 'Home' }); |
| 102 | + await expect(homeLink).toMatchScreenshot('home-link.png'); |
144 | 103 | }); |
145 | 104 | }); |
0 commit comments