@argos-ci/vitest 0.4.2 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/internal.d.mts +10 -7
- package/dist/internal.mjs +40 -18
- package/dist/plugin.mjs +41 -18
- package/package.json +3 -3
package/dist/internal.d.mts
CHANGED
|
@@ -25,7 +25,7 @@ declare function resetTesterScale(ctx: BrowserCommandContext): Promise<() => Pro
|
|
|
25
25
|
* box is not painted, so the iframe must be sized to hold the content.
|
|
26
26
|
*
|
|
27
27
|
* @param size - The viewport size, `"default"` to keep the natural size, or
|
|
28
|
-
* `"initial"` to restore the size
|
|
28
|
+
* `"initial"` to restore the size the iframe had before Argos resized it.
|
|
29
29
|
* @param options.fullPage - When `true`, grow the height to fit the content
|
|
30
30
|
* while keeping the viewport width (Playwright-style full page).
|
|
31
31
|
*/
|
|
@@ -35,9 +35,12 @@ declare function setIframeViewportSize(ctx: BrowserCommandContext, size: Viewpor
|
|
|
35
35
|
/**
|
|
36
36
|
* Grow the Vitest iframe to fit its content so nothing is clipped.
|
|
37
37
|
*
|
|
38
|
-
* This must run
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* This must run once the content has reached its final size — after `argosCSS`
|
|
39
|
+
* (which may inject a `zoom`) is applied *and* after stabilization has waited
|
|
40
|
+
* for images and fonts. `setIframeViewportSize` sizes the iframe before any of
|
|
41
|
+
* that, so it can't account for the final content size. It only ever grows the
|
|
42
|
+
* iframe, never shrinks it; use `setIframeViewportSize(ctx, "initial")` to
|
|
43
|
+
* restore the original size afterwards.
|
|
41
44
|
*
|
|
42
45
|
* @param options.fitWidth - Also grow the iframe horizontally to paint content
|
|
43
46
|
* wider than the viewport. When `false`, only the height grows (to match
|
|
@@ -55,9 +58,9 @@ declare function fitIframeToContent(ctx: BrowserCommandContext, options: {
|
|
|
55
58
|
* on. It:
|
|
56
59
|
* - strips the Vitest-specific `viewports`/`fullPage` options (they drive the
|
|
57
60
|
* iframe resize, not Playwright);
|
|
58
|
-
* - wraps `beforeScreenshot` so the
|
|
59
|
-
* (
|
|
60
|
-
*
|
|
61
|
+
* - wraps `beforeScreenshot` so the iframe is grown to fit once the content has
|
|
62
|
+
* settled (see {@link fitIframeToContent}) — otherwise wide/tall content
|
|
63
|
+
* would be clipped;
|
|
61
64
|
* - captures the iframe's `<body>` via `@argos-ci/playwright`.
|
|
62
65
|
*
|
|
63
66
|
* @param config.fitWidth - Grow the iframe horizontally as well as vertically
|
package/dist/internal.mjs
CHANGED
|
@@ -12,6 +12,15 @@ const VITEST_IFRAME_SELECTOR = "iframe[data-vitest=\"true\"]";
|
|
|
12
12
|
*/
|
|
13
13
|
const VITEST_TESTER_ID = "vitest-tester";
|
|
14
14
|
/**
|
|
15
|
+
* Attribute holding the iframe's inline size from before Argos resized it, as
|
|
16
|
+
* JSON.
|
|
17
|
+
*
|
|
18
|
+
* The presence of the attribute — not the values it holds — is what marks the
|
|
19
|
+
* size as backed up: the original `style.width`/`style.height` are usually
|
|
20
|
+
* empty strings, which are indistinguishable from "nothing was saved yet".
|
|
21
|
+
*/
|
|
22
|
+
const SIZE_BACKUP_ATTRIBUTE = "data-argos-size-backup";
|
|
23
|
+
/**
|
|
15
24
|
* Remove the scale from the Vitest `#vitest-tester` element before taking a
|
|
16
25
|
* screenshot to avoid ending up with small screenshots.
|
|
17
26
|
* @returns A function to restore the scale after the screenshot.
|
|
@@ -40,26 +49,29 @@ async function resetTesterScale(ctx) {
|
|
|
40
49
|
* box is not painted, so the iframe must be sized to hold the content.
|
|
41
50
|
*
|
|
42
51
|
* @param size - The viewport size, `"default"` to keep the natural size, or
|
|
43
|
-
* `"initial"` to restore the size
|
|
52
|
+
* `"initial"` to restore the size the iframe had before Argos resized it.
|
|
44
53
|
* @param options.fullPage - When `true`, grow the height to fit the content
|
|
45
54
|
* while keeping the viewport width (Playwright-style full page).
|
|
46
55
|
*/
|
|
47
56
|
async function setIframeViewportSize(ctx, size, options = {}) {
|
|
48
|
-
await ctx.page.evaluate(({ size, fullPage, selector }) => {
|
|
57
|
+
await ctx.page.evaluate(({ size, fullPage, selector, backupAttribute }) => {
|
|
49
58
|
const iframe = document.querySelector(selector);
|
|
50
59
|
if (!(iframe instanceof HTMLIFrameElement)) throw new Error("Vitest iframe not found");
|
|
51
60
|
if (!iframe.contentDocument) throw new Error("Vitest iframe contentDocument not found");
|
|
52
61
|
if (size === "initial") {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
const backup = iframe.getAttribute(backupAttribute);
|
|
63
|
+
if (backup !== null) {
|
|
64
|
+
const { width, height } = JSON.parse(backup);
|
|
65
|
+
iframe.style.width = width;
|
|
66
|
+
iframe.style.height = height;
|
|
67
|
+
iframe.removeAttribute(backupAttribute);
|
|
56
68
|
}
|
|
57
69
|
return;
|
|
58
70
|
}
|
|
59
|
-
if (!iframe.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
71
|
+
if (!iframe.hasAttribute(backupAttribute)) iframe.setAttribute(backupAttribute, JSON.stringify({
|
|
72
|
+
width: iframe.style.width,
|
|
73
|
+
height: iframe.style.height
|
|
74
|
+
}));
|
|
63
75
|
if (size !== "default") iframe.style.width = `${size.width}px`;
|
|
64
76
|
if (fullPage) {
|
|
65
77
|
if (!iframe.contentWindow) throw new Error(`Can't access iframe window`);
|
|
@@ -73,24 +85,32 @@ async function setIframeViewportSize(ctx, size, options = {}) {
|
|
|
73
85
|
}, {
|
|
74
86
|
size,
|
|
75
87
|
fullPage: options.fullPage ?? false,
|
|
76
|
-
selector: VITEST_IFRAME_SELECTOR
|
|
88
|
+
selector: VITEST_IFRAME_SELECTOR,
|
|
89
|
+
backupAttribute: SIZE_BACKUP_ATTRIBUTE
|
|
77
90
|
});
|
|
78
91
|
}
|
|
79
92
|
/**
|
|
80
93
|
* Grow the Vitest iframe to fit its content so nothing is clipped.
|
|
81
94
|
*
|
|
82
|
-
* This must run
|
|
83
|
-
*
|
|
84
|
-
*
|
|
95
|
+
* This must run once the content has reached its final size — after `argosCSS`
|
|
96
|
+
* (which may inject a `zoom`) is applied *and* after stabilization has waited
|
|
97
|
+
* for images and fonts. `setIframeViewportSize` sizes the iframe before any of
|
|
98
|
+
* that, so it can't account for the final content size. It only ever grows the
|
|
99
|
+
* iframe, never shrinks it; use `setIframeViewportSize(ctx, "initial")` to
|
|
100
|
+
* restore the original size afterwards.
|
|
85
101
|
*
|
|
86
102
|
* @param options.fitWidth - Also grow the iframe horizontally to paint content
|
|
87
103
|
* wider than the viewport. When `false`, only the height grows (to match
|
|
88
104
|
* Playwright's `fullPage` semantics: full height, viewport width).
|
|
89
105
|
*/
|
|
90
106
|
async function fitIframeToContent(ctx, options) {
|
|
91
|
-
await ctx.page.evaluate(({ fitWidth, selector }) => {
|
|
107
|
+
await ctx.page.evaluate(({ fitWidth, selector, backupAttribute }) => {
|
|
92
108
|
const iframe = document.querySelector(selector);
|
|
93
109
|
if (!(iframe instanceof HTMLIFrameElement) || !iframe.contentDocument) return;
|
|
110
|
+
if (!iframe.hasAttribute(backupAttribute)) iframe.setAttribute(backupAttribute, JSON.stringify({
|
|
111
|
+
width: iframe.style.width,
|
|
112
|
+
height: iframe.style.height
|
|
113
|
+
}));
|
|
94
114
|
const { body, documentElement } = iframe.contentDocument;
|
|
95
115
|
const contentHeight = Math.max(body.scrollHeight, body.offsetHeight, documentElement.scrollHeight);
|
|
96
116
|
if (contentHeight > iframe.clientHeight) iframe.style.height = `${contentHeight}px`;
|
|
@@ -100,7 +120,8 @@ async function fitIframeToContent(ctx, options) {
|
|
|
100
120
|
}
|
|
101
121
|
}, {
|
|
102
122
|
fitWidth: options.fitWidth,
|
|
103
|
-
selector: VITEST_IFRAME_SELECTOR
|
|
123
|
+
selector: VITEST_IFRAME_SELECTOR,
|
|
124
|
+
backupAttribute: SIZE_BACKUP_ATTRIBUTE
|
|
104
125
|
});
|
|
105
126
|
}
|
|
106
127
|
//#endregion
|
|
@@ -112,9 +133,9 @@ async function fitIframeToContent(ctx, options) {
|
|
|
112
133
|
* on. It:
|
|
113
134
|
* - strips the Vitest-specific `viewports`/`fullPage` options (they drive the
|
|
114
135
|
* iframe resize, not Playwright);
|
|
115
|
-
* - wraps `beforeScreenshot` so the
|
|
116
|
-
* (
|
|
117
|
-
*
|
|
136
|
+
* - wraps `beforeScreenshot` so the iframe is grown to fit once the content has
|
|
137
|
+
* settled (see {@link fitIframeToContent}) — otherwise wide/tall content
|
|
138
|
+
* would be clipped;
|
|
118
139
|
* - captures the iframe's `<body>` via `@argos-ci/playwright`.
|
|
119
140
|
*
|
|
120
141
|
* @param config.fitWidth - Grow the iframe horizontally as well as vertically
|
|
@@ -127,6 +148,7 @@ async function screenshotFrame(ctx, name, options, config) {
|
|
|
127
148
|
...rest,
|
|
128
149
|
beforeScreenshot: async (api) => {
|
|
129
150
|
await userBeforeScreenshot?.(api);
|
|
151
|
+
await api.runStabilization();
|
|
130
152
|
await fitIframeToContent(ctx, { fitWidth: config.fitWidth });
|
|
131
153
|
}
|
|
132
154
|
};
|
package/dist/plugin.mjs
CHANGED
|
@@ -16,6 +16,15 @@ const VITEST_IFRAME_SELECTOR = "iframe[data-vitest=\"true\"]";
|
|
|
16
16
|
*/
|
|
17
17
|
const VITEST_TESTER_ID = "vitest-tester";
|
|
18
18
|
/**
|
|
19
|
+
* Attribute holding the iframe's inline size from before Argos resized it, as
|
|
20
|
+
* JSON.
|
|
21
|
+
*
|
|
22
|
+
* The presence of the attribute — not the values it holds — is what marks the
|
|
23
|
+
* size as backed up: the original `style.width`/`style.height` are usually
|
|
24
|
+
* empty strings, which are indistinguishable from "nothing was saved yet".
|
|
25
|
+
*/
|
|
26
|
+
const SIZE_BACKUP_ATTRIBUTE = "data-argos-size-backup";
|
|
27
|
+
/**
|
|
19
28
|
* Remove the scale from the Vitest `#vitest-tester` element before taking a
|
|
20
29
|
* screenshot to avoid ending up with small screenshots.
|
|
21
30
|
* @returns A function to restore the scale after the screenshot.
|
|
@@ -44,26 +53,29 @@ async function resetTesterScale(ctx) {
|
|
|
44
53
|
* box is not painted, so the iframe must be sized to hold the content.
|
|
45
54
|
*
|
|
46
55
|
* @param size - The viewport size, `"default"` to keep the natural size, or
|
|
47
|
-
* `"initial"` to restore the size
|
|
56
|
+
* `"initial"` to restore the size the iframe had before Argos resized it.
|
|
48
57
|
* @param options.fullPage - When `true`, grow the height to fit the content
|
|
49
58
|
* while keeping the viewport width (Playwright-style full page).
|
|
50
59
|
*/
|
|
51
60
|
async function setIframeViewportSize(ctx, size, options = {}) {
|
|
52
|
-
await ctx.page.evaluate(({ size, fullPage, selector }) => {
|
|
61
|
+
await ctx.page.evaluate(({ size, fullPage, selector, backupAttribute }) => {
|
|
53
62
|
const iframe = document.querySelector(selector);
|
|
54
63
|
if (!(iframe instanceof HTMLIFrameElement)) throw new Error("Vitest iframe not found");
|
|
55
64
|
if (!iframe.contentDocument) throw new Error("Vitest iframe contentDocument not found");
|
|
56
65
|
if (size === "initial") {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
const backup = iframe.getAttribute(backupAttribute);
|
|
67
|
+
if (backup !== null) {
|
|
68
|
+
const { width, height } = JSON.parse(backup);
|
|
69
|
+
iframe.style.width = width;
|
|
70
|
+
iframe.style.height = height;
|
|
71
|
+
iframe.removeAttribute(backupAttribute);
|
|
60
72
|
}
|
|
61
73
|
return;
|
|
62
74
|
}
|
|
63
|
-
if (!iframe.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
75
|
+
if (!iframe.hasAttribute(backupAttribute)) iframe.setAttribute(backupAttribute, JSON.stringify({
|
|
76
|
+
width: iframe.style.width,
|
|
77
|
+
height: iframe.style.height
|
|
78
|
+
}));
|
|
67
79
|
if (size !== "default") iframe.style.width = `${size.width}px`;
|
|
68
80
|
if (fullPage) {
|
|
69
81
|
if (!iframe.contentWindow) throw new Error(`Can't access iframe window`);
|
|
@@ -77,24 +89,32 @@ async function setIframeViewportSize(ctx, size, options = {}) {
|
|
|
77
89
|
}, {
|
|
78
90
|
size,
|
|
79
91
|
fullPage: options.fullPage ?? false,
|
|
80
|
-
selector: VITEST_IFRAME_SELECTOR
|
|
92
|
+
selector: VITEST_IFRAME_SELECTOR,
|
|
93
|
+
backupAttribute: SIZE_BACKUP_ATTRIBUTE
|
|
81
94
|
});
|
|
82
95
|
}
|
|
83
96
|
/**
|
|
84
97
|
* Grow the Vitest iframe to fit its content so nothing is clipped.
|
|
85
98
|
*
|
|
86
|
-
* This must run
|
|
87
|
-
*
|
|
88
|
-
*
|
|
99
|
+
* This must run once the content has reached its final size — after `argosCSS`
|
|
100
|
+
* (which may inject a `zoom`) is applied *and* after stabilization has waited
|
|
101
|
+
* for images and fonts. `setIframeViewportSize` sizes the iframe before any of
|
|
102
|
+
* that, so it can't account for the final content size. It only ever grows the
|
|
103
|
+
* iframe, never shrinks it; use `setIframeViewportSize(ctx, "initial")` to
|
|
104
|
+
* restore the original size afterwards.
|
|
89
105
|
*
|
|
90
106
|
* @param options.fitWidth - Also grow the iframe horizontally to paint content
|
|
91
107
|
* wider than the viewport. When `false`, only the height grows (to match
|
|
92
108
|
* Playwright's `fullPage` semantics: full height, viewport width).
|
|
93
109
|
*/
|
|
94
110
|
async function fitIframeToContent(ctx, options) {
|
|
95
|
-
await ctx.page.evaluate(({ fitWidth, selector }) => {
|
|
111
|
+
await ctx.page.evaluate(({ fitWidth, selector, backupAttribute }) => {
|
|
96
112
|
const iframe = document.querySelector(selector);
|
|
97
113
|
if (!(iframe instanceof HTMLIFrameElement) || !iframe.contentDocument) return;
|
|
114
|
+
if (!iframe.hasAttribute(backupAttribute)) iframe.setAttribute(backupAttribute, JSON.stringify({
|
|
115
|
+
width: iframe.style.width,
|
|
116
|
+
height: iframe.style.height
|
|
117
|
+
}));
|
|
98
118
|
const { body, documentElement } = iframe.contentDocument;
|
|
99
119
|
const contentHeight = Math.max(body.scrollHeight, body.offsetHeight, documentElement.scrollHeight);
|
|
100
120
|
if (contentHeight > iframe.clientHeight) iframe.style.height = `${contentHeight}px`;
|
|
@@ -104,7 +124,8 @@ async function fitIframeToContent(ctx, options) {
|
|
|
104
124
|
}
|
|
105
125
|
}, {
|
|
106
126
|
fitWidth: options.fitWidth,
|
|
107
|
-
selector: VITEST_IFRAME_SELECTOR
|
|
127
|
+
selector: VITEST_IFRAME_SELECTOR,
|
|
128
|
+
backupAttribute: SIZE_BACKUP_ATTRIBUTE
|
|
108
129
|
});
|
|
109
130
|
}
|
|
110
131
|
//#endregion
|
|
@@ -116,9 +137,9 @@ async function fitIframeToContent(ctx, options) {
|
|
|
116
137
|
* on. It:
|
|
117
138
|
* - strips the Vitest-specific `viewports`/`fullPage` options (they drive the
|
|
118
139
|
* iframe resize, not Playwright);
|
|
119
|
-
* - wraps `beforeScreenshot` so the
|
|
120
|
-
* (
|
|
121
|
-
*
|
|
140
|
+
* - wraps `beforeScreenshot` so the iframe is grown to fit once the content has
|
|
141
|
+
* settled (see {@link fitIframeToContent}) — otherwise wide/tall content
|
|
142
|
+
* would be clipped;
|
|
122
143
|
* - captures the iframe's `<body>` via `@argos-ci/playwright`.
|
|
123
144
|
*
|
|
124
145
|
* @param config.fitWidth - Grow the iframe horizontally as well as vertically
|
|
@@ -131,6 +152,7 @@ async function screenshotFrame(ctx, name, options, config) {
|
|
|
131
152
|
...rest,
|
|
132
153
|
beforeScreenshot: async (api) => {
|
|
133
154
|
await userBeforeScreenshot?.(api);
|
|
155
|
+
await api.runStabilization();
|
|
134
156
|
await fitIframeToContent(ctx, { fitWidth: config.fitWidth });
|
|
135
157
|
}
|
|
136
158
|
};
|
|
@@ -209,6 +231,7 @@ const createArgosScreenshotCommand = (pluginOptions = {}) => {
|
|
|
209
231
|
}
|
|
210
232
|
return attachments;
|
|
211
233
|
} finally {
|
|
234
|
+
await setIframeViewportSize(ctx, "initial");
|
|
212
235
|
await restore();
|
|
213
236
|
}
|
|
214
237
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@argos-ci/vitest",
|
|
3
3
|
"description": "Vitest SDK for visual testing with Argos.",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.3",
|
|
5
5
|
"author": "Smooth Code",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@argos-ci/browser": "6.4.5",
|
|
55
55
|
"@argos-ci/core": "6.7.2",
|
|
56
|
-
"@argos-ci/playwright": "7.4.
|
|
56
|
+
"@argos-ci/playwright": "7.4.3",
|
|
57
57
|
"@argos-ci/util": "4.1.0"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"check-format": "prettier --check --ignore-unknown --ignore-path=./.gitignore --ignore-path=../../.gitignore --ignore-path=../../.prettierignore .",
|
|
82
82
|
"lint": "eslint ."
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "fd20b0af878b8186d6950c2e9c4ab381ca3fcaa1"
|
|
85
85
|
}
|