@argos-ci/playwright 5.0.8 → 5.0.10
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/index.d.ts +15 -6
- package/dist/index.js +112 -50
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ElementHandle, Locator, Page, PageScreenshotOptions, LocatorScreenshotOptions } from '@playwright/test';
|
|
1
|
+
import { ElementHandle, Locator, Page, PageScreenshotOptions, LocatorScreenshotOptions, Frame } from '@playwright/test';
|
|
2
2
|
import { ViewportOption, StabilizationPluginOptions } from '@argos-ci/browser';
|
|
3
3
|
import { ScreenshotMetadata } from '@argos-ci/util';
|
|
4
4
|
|
|
@@ -19,7 +19,7 @@ type ArgosScreenshotOptions = {
|
|
|
19
19
|
*/
|
|
20
20
|
argosCSS?: string;
|
|
21
21
|
/**
|
|
22
|
-
* Disable hover effects by moving the mouse to the top-left corner of the
|
|
22
|
+
* Disable hover effects by moving the mouse to the top-left corner of the document.
|
|
23
23
|
* @default true
|
|
24
24
|
*/
|
|
25
25
|
disableHover?: boolean;
|
|
@@ -59,6 +59,12 @@ type ArgosScreenshotOptions = {
|
|
|
59
59
|
*/
|
|
60
60
|
afterScreenshot?: () => Promise<void> | void;
|
|
61
61
|
} & LocatorOptions & ScreenshotOptions<LocatorScreenshotOptions> & ScreenshotOptions<PageScreenshotOptions>;
|
|
62
|
+
type Attachment = {
|
|
63
|
+
name: string;
|
|
64
|
+
contentType: string;
|
|
65
|
+
path: string;
|
|
66
|
+
};
|
|
67
|
+
type Handler = Page | Frame;
|
|
62
68
|
/**
|
|
63
69
|
* Stabilize the UI and takes a screenshot of the application under test.
|
|
64
70
|
*
|
|
@@ -68,9 +74,9 @@ type ArgosScreenshotOptions = {
|
|
|
68
74
|
*/
|
|
69
75
|
declare function argosScreenshot(
|
|
70
76
|
/**
|
|
71
|
-
* Playwright `page` object.
|
|
77
|
+
* Playwright `page` or `frame` object.
|
|
72
78
|
*/
|
|
73
|
-
|
|
79
|
+
handler: Handler,
|
|
74
80
|
/**
|
|
75
81
|
* Name of the screenshot. Must be unique.
|
|
76
82
|
*/
|
|
@@ -78,7 +84,7 @@ name: string,
|
|
|
78
84
|
/**
|
|
79
85
|
* Options for the screenshot.
|
|
80
86
|
*/
|
|
81
|
-
options?: ArgosScreenshotOptions): Promise<
|
|
87
|
+
options?: ArgosScreenshotOptions): Promise<Attachment[]>;
|
|
82
88
|
|
|
83
89
|
/**
|
|
84
90
|
* Get the CSP script hash.
|
|
@@ -88,10 +94,13 @@ declare function getCSPScriptHash(): string;
|
|
|
88
94
|
type MetadataConfig = {
|
|
89
95
|
sdk: ScreenshotMetadata["sdk"];
|
|
90
96
|
playwrightLibraries: string[];
|
|
97
|
+
url?: string;
|
|
98
|
+
test?: ScreenshotMetadata["test"];
|
|
99
|
+
viewport?: ScreenshotMetadata["viewport"];
|
|
91
100
|
};
|
|
92
101
|
/**
|
|
93
102
|
* Set the metadata config.
|
|
94
103
|
*/
|
|
95
104
|
declare function setMetadataConfig(metadata: MetadataConfig): void;
|
|
96
105
|
|
|
97
|
-
export { type ArgosScreenshotOptions, setMetadataConfig as DO_NOT_USE_setMetadataConfig, argosScreenshot, getCSPScriptHash };
|
|
106
|
+
export { type ArgosScreenshotOptions, type Attachment, setMetadataConfig as DO_NOT_USE_setMetadataConfig, type MetadataConfig, argosScreenshot, getCSPScriptHash };
|
package/dist/index.js
CHANGED
|
@@ -42,6 +42,9 @@ var DEFAULT_PLAYWRIGHT_LIBRARIES = [
|
|
|
42
42
|
"playwright",
|
|
43
43
|
"playwright-core"
|
|
44
44
|
];
|
|
45
|
+
function getMetadataOverrides() {
|
|
46
|
+
return metadataConfigStorage.getStore();
|
|
47
|
+
}
|
|
45
48
|
async function getAutomationLibraryMetadata() {
|
|
46
49
|
const metadataConfig = metadataConfigStorage.getStore();
|
|
47
50
|
const libraries = metadataConfig?.playwrightLibraries ?? DEFAULT_PLAYWRIGHT_LIBRARIES;
|
|
@@ -81,8 +84,31 @@ async function getLibraryMetadata() {
|
|
|
81
84
|
sdk
|
|
82
85
|
};
|
|
83
86
|
}
|
|
84
|
-
|
|
87
|
+
function resolveTestFilePath(filepath, repositoryPath) {
|
|
88
|
+
if (!repositoryPath) {
|
|
89
|
+
return filepath;
|
|
90
|
+
}
|
|
91
|
+
return relative(repositoryPath, filepath);
|
|
92
|
+
}
|
|
93
|
+
async function getTestMetadata(testInfo) {
|
|
85
94
|
const repositoryPath = await getGitRepositoryPath();
|
|
95
|
+
const metadataConfig = metadataConfigStorage.getStore();
|
|
96
|
+
if (metadataConfig?.test) {
|
|
97
|
+
return {
|
|
98
|
+
...metadataConfig.test,
|
|
99
|
+
location: metadataConfig.test?.location ? {
|
|
100
|
+
file: resolveTestFilePath(
|
|
101
|
+
metadataConfig.test.location.file,
|
|
102
|
+
repositoryPath
|
|
103
|
+
),
|
|
104
|
+
line: metadataConfig.test.location.line,
|
|
105
|
+
column: metadataConfig.test.location.column
|
|
106
|
+
} : void 0
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (!testInfo) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
86
112
|
const testMetadata = {
|
|
87
113
|
id: testInfo.testId,
|
|
88
114
|
title: testInfo.title,
|
|
@@ -91,7 +117,7 @@ async function getTestMetadataFromTestInfo(testInfo) {
|
|
|
91
117
|
retries: testInfo.project.retries,
|
|
92
118
|
repeat: testInfo.repeatEachIndex,
|
|
93
119
|
location: {
|
|
94
|
-
file:
|
|
120
|
+
file: resolveTestFilePath(testInfo.file, repositoryPath),
|
|
95
121
|
line: testInfo.line,
|
|
96
122
|
column: testInfo.column
|
|
97
123
|
}
|
|
@@ -111,12 +137,12 @@ function checkIsUsingArgosReporter(testInfo) {
|
|
|
111
137
|
|
|
112
138
|
// src/screenshot.ts
|
|
113
139
|
var DEFAULT_SCREENSHOT_ROOT = "./screenshots";
|
|
114
|
-
async function injectArgos(
|
|
115
|
-
const injected = await
|
|
140
|
+
async function injectArgos(handler) {
|
|
141
|
+
const injected = await handler.evaluate(
|
|
116
142
|
() => typeof window.__ARGOS__ !== "undefined"
|
|
117
143
|
);
|
|
118
144
|
if (!injected) {
|
|
119
|
-
await
|
|
145
|
+
await handler.addScriptTag({ content: getGlobalScript() });
|
|
120
146
|
}
|
|
121
147
|
}
|
|
122
148
|
async function getTestInfo() {
|
|
@@ -127,6 +153,15 @@ async function getTestInfo() {
|
|
|
127
153
|
return null;
|
|
128
154
|
}
|
|
129
155
|
}
|
|
156
|
+
function checkIsFrame(handler) {
|
|
157
|
+
return "page" in handler && typeof handler.page === "function";
|
|
158
|
+
}
|
|
159
|
+
function getPage(handler) {
|
|
160
|
+
if (checkIsFrame(handler)) {
|
|
161
|
+
return handler.page();
|
|
162
|
+
}
|
|
163
|
+
return handler;
|
|
164
|
+
}
|
|
130
165
|
function getViewportSize(page) {
|
|
131
166
|
const viewportSize = page.viewportSize();
|
|
132
167
|
if (!viewportSize) {
|
|
@@ -142,37 +177,38 @@ async function setViewportSize(page, viewportSize) {
|
|
|
142
177
|
);
|
|
143
178
|
}
|
|
144
179
|
function getStabilizationContext(options) {
|
|
145
|
-
const { fullPage, argosCSS, stabilize } = options;
|
|
180
|
+
const { fullPage, argosCSS, stabilize, viewports } = options;
|
|
146
181
|
return {
|
|
147
182
|
fullPage,
|
|
148
183
|
argosCSS,
|
|
184
|
+
viewports,
|
|
149
185
|
options: stabilize
|
|
150
186
|
};
|
|
151
187
|
}
|
|
152
|
-
async function beforeAll(
|
|
188
|
+
async function beforeAll(handler, options) {
|
|
153
189
|
const { disableHover = true } = options;
|
|
154
190
|
const context = getStabilizationContext(options);
|
|
155
|
-
await
|
|
191
|
+
await handler.evaluate(
|
|
156
192
|
(context2) => window.__ARGOS__.beforeAll(context2),
|
|
157
193
|
context
|
|
158
194
|
);
|
|
159
195
|
if (disableHover) {
|
|
160
|
-
await
|
|
196
|
+
await getPage(handler).mouse.move(0, 0);
|
|
161
197
|
}
|
|
162
198
|
return async () => {
|
|
163
|
-
await
|
|
199
|
+
await handler.evaluate(
|
|
164
200
|
() => window.__ARGOS__.afterAll()
|
|
165
201
|
);
|
|
166
202
|
};
|
|
167
203
|
}
|
|
168
|
-
async function beforeEach(
|
|
204
|
+
async function beforeEach(handler, options) {
|
|
169
205
|
const context = getStabilizationContext(options);
|
|
170
|
-
await
|
|
206
|
+
await handler.evaluate(
|
|
171
207
|
(context2) => window.__ARGOS__.beforeEach(context2),
|
|
172
208
|
context
|
|
173
209
|
);
|
|
174
210
|
return async () => {
|
|
175
|
-
await
|
|
211
|
+
await handler.evaluate(
|
|
176
212
|
() => window.__ARGOS__.afterEach()
|
|
177
213
|
);
|
|
178
214
|
};
|
|
@@ -191,11 +227,11 @@ async function increaseTimeout() {
|
|
|
191
227
|
}
|
|
192
228
|
return null;
|
|
193
229
|
}
|
|
194
|
-
async function waitForReadiness(
|
|
230
|
+
async function waitForReadiness(handler, options) {
|
|
195
231
|
const context = getStabilizationContext(options);
|
|
196
232
|
const timeout = await increaseTimeout();
|
|
197
233
|
try {
|
|
198
|
-
await
|
|
234
|
+
await handler.waitForFunction(
|
|
199
235
|
(context2) => {
|
|
200
236
|
const argos = window.__ARGOS__;
|
|
201
237
|
return argos.waitFor(context2);
|
|
@@ -205,7 +241,7 @@ async function waitForReadiness(page, options) {
|
|
|
205
241
|
);
|
|
206
242
|
timeout?.reset();
|
|
207
243
|
} catch (error) {
|
|
208
|
-
const reasons = await
|
|
244
|
+
const reasons = await handler.evaluate(
|
|
209
245
|
(context2) => window.__ARGOS__.getWaitFailureExplanations(
|
|
210
246
|
context2
|
|
211
247
|
),
|
|
@@ -233,7 +269,7 @@ function getScreenshotNames(name, testInfo) {
|
|
|
233
269
|
}
|
|
234
270
|
return { name, baseName: null };
|
|
235
271
|
}
|
|
236
|
-
async function argosScreenshot(
|
|
272
|
+
async function argosScreenshot(handler, name, options = {}) {
|
|
237
273
|
const {
|
|
238
274
|
element,
|
|
239
275
|
has,
|
|
@@ -243,13 +279,13 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
243
279
|
root = DEFAULT_SCREENSHOT_ROOT,
|
|
244
280
|
...playwrightOptions
|
|
245
281
|
} = options;
|
|
246
|
-
if (!
|
|
247
|
-
throw new Error("A Playwright `
|
|
282
|
+
if (!handler) {
|
|
283
|
+
throw new Error("A Playwright `handler` object is required.");
|
|
248
284
|
}
|
|
249
285
|
if (!name) {
|
|
250
286
|
throw new Error("The `name` argument is required.");
|
|
251
287
|
}
|
|
252
|
-
const
|
|
288
|
+
const screenshotTarget = typeof element === "string" ? handler.locator(element, { has, hasText }) : element ?? (checkIsFrame(handler) ? handler.locator("body") : handler);
|
|
253
289
|
const testInfo = await getTestInfo();
|
|
254
290
|
const useArgosReporter = Boolean(
|
|
255
291
|
testInfo && checkIsUsingArgosReporter(testInfo)
|
|
@@ -258,33 +294,33 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
258
294
|
// Create the screenshot folder if it doesn't exist
|
|
259
295
|
useArgosReporter ? null : mkdir(root, { recursive: true }),
|
|
260
296
|
// Inject Argos script into the page
|
|
261
|
-
injectArgos(
|
|
297
|
+
injectArgos(handler)
|
|
262
298
|
]);
|
|
263
|
-
const originalViewportSize = getViewportSize(
|
|
264
|
-
const fullPage = options.fullPage !== void 0 ? options.fullPage :
|
|
265
|
-
const afterAll = await beforeAll(
|
|
299
|
+
const originalViewportSize = checkIsFrame(handler) ? null : getViewportSize(handler);
|
|
300
|
+
const fullPage = options.fullPage !== void 0 ? options.fullPage : screenshotTarget === handler;
|
|
301
|
+
const afterAll = await beforeAll(handler, options);
|
|
266
302
|
const collectMetadata = async (testInfo2) => {
|
|
303
|
+
const overrides = getMetadataOverrides();
|
|
267
304
|
const [colorScheme, mediaType, libMetadata, testMetadata] = await Promise.all([
|
|
268
|
-
|
|
305
|
+
handler.evaluate(
|
|
269
306
|
() => window.__ARGOS__.getColorScheme()
|
|
270
307
|
),
|
|
271
|
-
|
|
308
|
+
handler.evaluate(
|
|
272
309
|
() => window.__ARGOS__.getMediaType()
|
|
273
310
|
),
|
|
274
311
|
getLibraryMetadata(),
|
|
275
|
-
|
|
312
|
+
getTestMetadata(testInfo2)
|
|
276
313
|
]);
|
|
277
|
-
const viewportSize = getViewportSize(
|
|
278
|
-
const browser =
|
|
314
|
+
const viewportSize = checkIsFrame(handler) ? null : getViewportSize(handler);
|
|
315
|
+
const browser = getPage(handler).context().browser();
|
|
279
316
|
if (!browser) {
|
|
280
317
|
throw new Error("Can't take screenshots without a browser.");
|
|
281
318
|
}
|
|
282
319
|
const browserName = browser.browserType().name();
|
|
283
320
|
const browserVersion = browser.version();
|
|
284
|
-
const url =
|
|
321
|
+
const url = overrides?.url ?? handler.url();
|
|
285
322
|
const metadata = {
|
|
286
323
|
url,
|
|
287
|
-
viewport: viewportSize,
|
|
288
324
|
colorScheme,
|
|
289
325
|
mediaType,
|
|
290
326
|
test: testMetadata,
|
|
@@ -294,6 +330,10 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
294
330
|
},
|
|
295
331
|
...libMetadata
|
|
296
332
|
};
|
|
333
|
+
const viewport = viewportSize ?? getMetadataOverrides()?.viewport;
|
|
334
|
+
if (viewport) {
|
|
335
|
+
metadata.viewport = viewport;
|
|
336
|
+
}
|
|
297
337
|
return metadata;
|
|
298
338
|
};
|
|
299
339
|
const stabilizeAndScreenshot = async (name2) => {
|
|
@@ -313,52 +353,74 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
313
353
|
await mkdir(dirname(screenshotPath), { recursive: true });
|
|
314
354
|
}
|
|
315
355
|
await options.beforeScreenshot?.({
|
|
316
|
-
runStabilization: (stabilizationOptions) => waitForReadiness(
|
|
356
|
+
runStabilization: (stabilizationOptions) => waitForReadiness(handler, {
|
|
317
357
|
...options,
|
|
318
358
|
stabilize: stabilizationOptions ?? options.stabilize
|
|
319
359
|
})
|
|
320
360
|
});
|
|
321
|
-
await waitForReadiness(
|
|
322
|
-
const afterEach = await beforeEach(
|
|
361
|
+
await waitForReadiness(handler, options);
|
|
362
|
+
const afterEach = await beforeEach(handler, options);
|
|
363
|
+
await waitForReadiness(handler, options);
|
|
323
364
|
await Promise.all([
|
|
324
|
-
|
|
365
|
+
screenshotTarget.screenshot({
|
|
325
366
|
path: screenshotPath,
|
|
326
367
|
type: "png",
|
|
327
368
|
fullPage,
|
|
328
|
-
mask: [
|
|
369
|
+
mask: [handler.locator('[data-visual-test="blackout"]')],
|
|
329
370
|
animations: "disabled",
|
|
330
371
|
...playwrightOptions
|
|
331
372
|
}),
|
|
332
373
|
writeMetadata(screenshotPath, metadata)
|
|
333
374
|
]);
|
|
375
|
+
const attachments = [
|
|
376
|
+
{
|
|
377
|
+
name: getAttachmentName(names.name, "screenshot"),
|
|
378
|
+
contentType: "image/png",
|
|
379
|
+
path: screenshotPath
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: getAttachmentName(names.name, "metadata"),
|
|
383
|
+
contentType: "application/json",
|
|
384
|
+
path: getMetadataPath(screenshotPath)
|
|
385
|
+
}
|
|
386
|
+
];
|
|
334
387
|
if (useArgosReporter && testInfo) {
|
|
335
|
-
await Promise.all(
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
})
|
|
344
|
-
]);
|
|
388
|
+
await Promise.all(
|
|
389
|
+
attachments.map(
|
|
390
|
+
(attachment) => testInfo.attach(attachment.name, {
|
|
391
|
+
path: attachment.path,
|
|
392
|
+
contentType: attachment.contentType
|
|
393
|
+
})
|
|
394
|
+
)
|
|
395
|
+
);
|
|
345
396
|
}
|
|
346
397
|
await afterEach();
|
|
347
398
|
await options.afterScreenshot?.();
|
|
399
|
+
return attachments;
|
|
348
400
|
};
|
|
401
|
+
const allAttachments = [];
|
|
349
402
|
if (viewports) {
|
|
403
|
+
if (checkIsFrame(handler)) {
|
|
404
|
+
throw new Error(`viewports option is not supported with an iframe`);
|
|
405
|
+
}
|
|
350
406
|
for (const viewport of viewports) {
|
|
351
407
|
const viewportSize = resolveViewport(viewport);
|
|
352
|
-
await setViewportSize(
|
|
353
|
-
await stabilizeAndScreenshot(
|
|
408
|
+
await setViewportSize(handler, viewportSize);
|
|
409
|
+
const attachments = await stabilizeAndScreenshot(
|
|
354
410
|
getScreenshotName(name, { viewportWidth: viewportSize.width })
|
|
355
411
|
);
|
|
412
|
+
allAttachments.push(...attachments);
|
|
413
|
+
}
|
|
414
|
+
if (!originalViewportSize) {
|
|
415
|
+
throw new Error(`Invariant: viewport size must be saved`);
|
|
356
416
|
}
|
|
357
|
-
await setViewportSize(
|
|
417
|
+
await setViewportSize(handler, originalViewportSize);
|
|
358
418
|
} else {
|
|
359
|
-
await stabilizeAndScreenshot(name);
|
|
419
|
+
const attachments = await stabilizeAndScreenshot(name);
|
|
420
|
+
allAttachments.push(...attachments);
|
|
360
421
|
}
|
|
361
422
|
await afterAll();
|
|
423
|
+
return allAttachments;
|
|
362
424
|
}
|
|
363
425
|
|
|
364
426
|
// src/csp.ts
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@argos-ci/playwright",
|
|
3
3
|
"description": "Playwright SDK for visual testing with Argos.",
|
|
4
|
-
"version": "5.0.
|
|
4
|
+
"version": "5.0.10",
|
|
5
5
|
"author": "Smooth Code",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"node": ">=18.16.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@argos-ci/browser": "4.1
|
|
51
|
-
"@argos-ci/core": "3.2.
|
|
52
|
-
"@argos-ci/util": "2.3.
|
|
50
|
+
"@argos-ci/browser": "4.2.1",
|
|
51
|
+
"@argos-ci/core": "3.2.2",
|
|
52
|
+
"@argos-ci/util": "2.3.3",
|
|
53
53
|
"chalk": "^5.4.1",
|
|
54
54
|
"debug": "^4.4.0"
|
|
55
55
|
},
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"check-format": "prettier --check --ignore-unknown --ignore-path=../../.gitignore --ignore-path=../../.prettierignore .",
|
|
68
68
|
"lint": "eslint ."
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "ecab2281c36828d0c43728e3ed98e1eefe227c99"
|
|
71
71
|
}
|