Skip to content

Commit defd76a

Browse files
committed
🐛 Fix Vitest E2E tests to properly test the SDK
- Test the actual SDK functionality (toMatchScreenshot matcher) - Load test-site CSS for consistent styling with other SDKs - Remove custom commands (loadPage was for full-page navigation, not SDK testing) - Test page screenshots, element screenshots, properties, and thresholds
1 parent d55cca1 commit defd76a

File tree

3 files changed

+79
-171
lines changed

3 files changed

+79
-171
lines changed

clients/vitest/src/commands.js

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 75 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,104 @@
11
/**
2-
* E2E Integration Tests using shared test-site (FluffyCloud)
2+
* E2E tests for the Vizzly Vitest plugin
33
*
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
69
*
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.
1511
*/
1612

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';
1915

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)
2117
// eslint-disable-next-line no-undef
2218
let baseUrl = __TEST_SITE_URL__;
2319

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;
7531
});
7632
});
7733

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+
`;
8342

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');
8844
});
89-
});
9045

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');
9857
});
9958

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', {
10370
properties: {
104-
browser: 'chromium',
105-
viewport: '1280x720',
106-
page: 'homepage',
71+
theme: 'dark',
72+
component: 'card',
10773
},
10874
});
10975
});
11076

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,
12086
});
12187
});
122-
});
12388

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+
`;
12797

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');
137100

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');
144103
});
145104
});

clients/vitest/vitest.e2e.config.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,16 @@ import handler from 'serve-handler';
55
import { playwright } from '@vitest/browser-playwright';
66
import { defineConfig } from 'vitest/config';
77
import { vizzlyPlugin } from './src/index.js';
8-
import * as commands from './src/commands.js';
98

10-
// Path to shared test-site
9+
// Path to shared test-site (for CSS assets)
1110
let testSitePath = resolve(import.meta.dirname, '../../test-site');
1211

1312
// Verify test-site exists
1413
if (!existsSync(resolve(testSitePath, 'index.html'))) {
1514
throw new Error(`test-site not found at ${testSitePath}`);
1615
}
1716

18-
// Start static server for test-site on a random available port
17+
// Start static server for test-site assets
1918
let server = createServer((req, res) => {
2019
return handler(req, res, {
2120
public: testSitePath,
@@ -33,7 +32,7 @@ let testSitePort = server.address().port;
3332
// Clean up server on exit - use unref() so it doesn't keep the process alive
3433
server.unref();
3534

36-
// E2E tests config - runs in browser mode with real test-site
35+
// E2E tests config - runs in browser mode
3736
export default defineConfig({
3837
plugins: [vizzlyPlugin()],
3938
test: {
@@ -42,15 +41,10 @@ export default defineConfig({
4241
instances: [
4342
{
4443
browser: 'chromium',
45-
provider: playwright({
46-
launch: {
47-
viewport: { width: 1280, height: 720 },
48-
},
49-
}),
44+
provider: playwright(),
5045
},
5146
],
5247
headless: true,
53-
commands,
5448
},
5549
include: ['tests/e2e/**/*.test.js'],
5650
},

0 commit comments

Comments
 (0)