-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsetup.js
More file actions
154 lines (135 loc) · 4.65 KB
/
setup.js
File metadata and controls
154 lines (135 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* Vitest setup file for Vizzly plugin
* This extends the expect API with our custom toMatchScreenshot matcher
*/
import { expect } from 'vitest';
// Custom matcher that completely replaces Vitest's toMatchScreenshot
// This runs in browser context, so we make direct HTTP calls instead of using Node SDK
async function toMatchScreenshot(element, name, options = {}) {
let serverUrl =
typeof __VIZZLY_SERVER_URL__ !== 'undefined' ? __VIZZLY_SERVER_URL__ : '';
let buildId =
typeof __VIZZLY_BUILD_ID__ !== 'undefined' ? __VIZZLY_BUILD_ID__ : '';
// If no server URL, Vizzly is not available
if (!serverUrl) {
return {
pass: true,
message: () =>
'Vizzly not available. Run `vizzly tdd start` or `vizzly run "npm test"` to enable visual testing.',
};
}
// Import page from Vitest browser context
const { page } = await import('vitest/browser');
// Take screenshot - Vitest browser mode returns a file path, not the image data
let screenshotPath;
if (typeof element === 'object' && element.locator) {
// It's a Playwright locator
screenshotPath = await element.screenshot(options);
} else {
// It's the page object
screenshotPath = await page.screenshot(options);
}
let screenshotName = name || `screenshot-${Date.now()}`;
// Extract options from top-level
let threshold = options.threshold ?? 0;
let fullPage = options.fullPage;
let customProperties = options.properties ?? {};
// Prepare properties
let properties = {
framework: 'vitest',
vitest: true,
...customProperties,
};
try {
// Vitest browser mode saves screenshots to disk and returns the file path
// The TDD server can read the file directly since it's on the same machine
// Just send the path as-is
let response = await fetch(`${serverUrl}/screenshot`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: screenshotName,
image: screenshotPath, // Send file path directly
type: 'file-path',
buildId: buildId || null,
threshold,
fullPage,
properties,
}),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
let result = await response.json();
// In cloud mode, always pass
if (buildId) {
return {
pass: true,
message: () => '',
};
}
// In TDD mode, check comparison result
// TDD handler returns { success, comparison: { name, status } }
let comparison = result.comparison || result;
let comparisonStatus = comparison.status;
if (comparisonStatus === 'new') {
return {
pass: false,
message: () =>
`New screenshot baseline created: ${screenshotName}. View at http://localhost:47392/dashboard`,
};
} else if (comparisonStatus === 'passed') {
return {
pass: true,
message: () => '',
};
} else if (comparisonStatus === 'failed') {
let diffPercent = comparison.diffPercentage
? comparison.diffPercentage.toFixed(2)
: '0.00';
if (comparison.diffPercentage <= threshold) {
return {
pass: true,
message: () =>
`Screenshot within threshold: ${screenshotName} (${diffPercent}% ≤ ${threshold.toFixed(2)}%)`,
};
}
return {
pass: false,
message: () =>
`Visual difference detected: ${screenshotName} (${diffPercent}% difference). View at http://localhost:47392/dashboard`,
};
}
// Unknown status
return {
pass: false,
message: () => `Unknown comparison status: ${comparisonStatus}`,
};
} catch (error) {
// Differentiate between error types for better debugging
let errorMessage;
if (error.name === 'TypeError' && error.message.includes('fetch')) {
errorMessage = `Vizzly server not reachable at ${serverUrl}. Is the TDD server running? Run 'vizzly tdd start' or 'vizzly run "npm test"'.`;
} else if (
error.message.includes('HTTP 500') ||
error.message.includes('HTTP 502') ||
error.message.includes('HTTP 503')
) {
errorMessage = `Vizzly server error: ${error.message}. Check the TDD server logs for details.`;
} else if (error.message.includes('screenshot')) {
errorMessage = `Screenshot capture failed: ${error.message}. Check that the element exists and is visible.`;
} else {
errorMessage = `Vizzly screenshot failed: ${error.message}`;
}
return {
pass: false,
message: () => errorMessage,
};
}
}
// Extend expect with our custom matcher
expect.extend({
toMatchScreenshot,
});