@argos-ci/playwright 5.0.9 → 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 +110 -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) {
|
|
@@ -150,30 +185,30 @@ function getStabilizationContext(options) {
|
|
|
150
185
|
options: stabilize
|
|
151
186
|
};
|
|
152
187
|
}
|
|
153
|
-
async function beforeAll(
|
|
188
|
+
async function beforeAll(handler, options) {
|
|
154
189
|
const { disableHover = true } = options;
|
|
155
190
|
const context = getStabilizationContext(options);
|
|
156
|
-
await
|
|
191
|
+
await handler.evaluate(
|
|
157
192
|
(context2) => window.__ARGOS__.beforeAll(context2),
|
|
158
193
|
context
|
|
159
194
|
);
|
|
160
195
|
if (disableHover) {
|
|
161
|
-
await
|
|
196
|
+
await getPage(handler).mouse.move(0, 0);
|
|
162
197
|
}
|
|
163
198
|
return async () => {
|
|
164
|
-
await
|
|
199
|
+
await handler.evaluate(
|
|
165
200
|
() => window.__ARGOS__.afterAll()
|
|
166
201
|
);
|
|
167
202
|
};
|
|
168
203
|
}
|
|
169
|
-
async function beforeEach(
|
|
204
|
+
async function beforeEach(handler, options) {
|
|
170
205
|
const context = getStabilizationContext(options);
|
|
171
|
-
await
|
|
206
|
+
await handler.evaluate(
|
|
172
207
|
(context2) => window.__ARGOS__.beforeEach(context2),
|
|
173
208
|
context
|
|
174
209
|
);
|
|
175
210
|
return async () => {
|
|
176
|
-
await
|
|
211
|
+
await handler.evaluate(
|
|
177
212
|
() => window.__ARGOS__.afterEach()
|
|
178
213
|
);
|
|
179
214
|
};
|
|
@@ -192,11 +227,11 @@ async function increaseTimeout() {
|
|
|
192
227
|
}
|
|
193
228
|
return null;
|
|
194
229
|
}
|
|
195
|
-
async function waitForReadiness(
|
|
230
|
+
async function waitForReadiness(handler, options) {
|
|
196
231
|
const context = getStabilizationContext(options);
|
|
197
232
|
const timeout = await increaseTimeout();
|
|
198
233
|
try {
|
|
199
|
-
await
|
|
234
|
+
await handler.waitForFunction(
|
|
200
235
|
(context2) => {
|
|
201
236
|
const argos = window.__ARGOS__;
|
|
202
237
|
return argos.waitFor(context2);
|
|
@@ -206,7 +241,7 @@ async function waitForReadiness(page, options) {
|
|
|
206
241
|
);
|
|
207
242
|
timeout?.reset();
|
|
208
243
|
} catch (error) {
|
|
209
|
-
const reasons = await
|
|
244
|
+
const reasons = await handler.evaluate(
|
|
210
245
|
(context2) => window.__ARGOS__.getWaitFailureExplanations(
|
|
211
246
|
context2
|
|
212
247
|
),
|
|
@@ -234,7 +269,7 @@ function getScreenshotNames(name, testInfo) {
|
|
|
234
269
|
}
|
|
235
270
|
return { name, baseName: null };
|
|
236
271
|
}
|
|
237
|
-
async function argosScreenshot(
|
|
272
|
+
async function argosScreenshot(handler, name, options = {}) {
|
|
238
273
|
const {
|
|
239
274
|
element,
|
|
240
275
|
has,
|
|
@@ -244,13 +279,13 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
244
279
|
root = DEFAULT_SCREENSHOT_ROOT,
|
|
245
280
|
...playwrightOptions
|
|
246
281
|
} = options;
|
|
247
|
-
if (!
|
|
248
|
-
throw new Error("A Playwright `
|
|
282
|
+
if (!handler) {
|
|
283
|
+
throw new Error("A Playwright `handler` object is required.");
|
|
249
284
|
}
|
|
250
285
|
if (!name) {
|
|
251
286
|
throw new Error("The `name` argument is required.");
|
|
252
287
|
}
|
|
253
|
-
const
|
|
288
|
+
const screenshotTarget = typeof element === "string" ? handler.locator(element, { has, hasText }) : element ?? (checkIsFrame(handler) ? handler.locator("body") : handler);
|
|
254
289
|
const testInfo = await getTestInfo();
|
|
255
290
|
const useArgosReporter = Boolean(
|
|
256
291
|
testInfo && checkIsUsingArgosReporter(testInfo)
|
|
@@ -259,33 +294,33 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
259
294
|
// Create the screenshot folder if it doesn't exist
|
|
260
295
|
useArgosReporter ? null : mkdir(root, { recursive: true }),
|
|
261
296
|
// Inject Argos script into the page
|
|
262
|
-
injectArgos(
|
|
297
|
+
injectArgos(handler)
|
|
263
298
|
]);
|
|
264
|
-
const originalViewportSize = getViewportSize(
|
|
265
|
-
const fullPage = options.fullPage !== void 0 ? options.fullPage :
|
|
266
|
-
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);
|
|
267
302
|
const collectMetadata = async (testInfo2) => {
|
|
303
|
+
const overrides = getMetadataOverrides();
|
|
268
304
|
const [colorScheme, mediaType, libMetadata, testMetadata] = await Promise.all([
|
|
269
|
-
|
|
305
|
+
handler.evaluate(
|
|
270
306
|
() => window.__ARGOS__.getColorScheme()
|
|
271
307
|
),
|
|
272
|
-
|
|
308
|
+
handler.evaluate(
|
|
273
309
|
() => window.__ARGOS__.getMediaType()
|
|
274
310
|
),
|
|
275
311
|
getLibraryMetadata(),
|
|
276
|
-
|
|
312
|
+
getTestMetadata(testInfo2)
|
|
277
313
|
]);
|
|
278
|
-
const viewportSize = getViewportSize(
|
|
279
|
-
const browser =
|
|
314
|
+
const viewportSize = checkIsFrame(handler) ? null : getViewportSize(handler);
|
|
315
|
+
const browser = getPage(handler).context().browser();
|
|
280
316
|
if (!browser) {
|
|
281
317
|
throw new Error("Can't take screenshots without a browser.");
|
|
282
318
|
}
|
|
283
319
|
const browserName = browser.browserType().name();
|
|
284
320
|
const browserVersion = browser.version();
|
|
285
|
-
const url =
|
|
321
|
+
const url = overrides?.url ?? handler.url();
|
|
286
322
|
const metadata = {
|
|
287
323
|
url,
|
|
288
|
-
viewport: viewportSize,
|
|
289
324
|
colorScheme,
|
|
290
325
|
mediaType,
|
|
291
326
|
test: testMetadata,
|
|
@@ -295,6 +330,10 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
295
330
|
},
|
|
296
331
|
...libMetadata
|
|
297
332
|
};
|
|
333
|
+
const viewport = viewportSize ?? getMetadataOverrides()?.viewport;
|
|
334
|
+
if (viewport) {
|
|
335
|
+
metadata.viewport = viewport;
|
|
336
|
+
}
|
|
298
337
|
return metadata;
|
|
299
338
|
};
|
|
300
339
|
const stabilizeAndScreenshot = async (name2) => {
|
|
@@ -314,53 +353,74 @@ async function argosScreenshot(page, name, options = {}) {
|
|
|
314
353
|
await mkdir(dirname(screenshotPath), { recursive: true });
|
|
315
354
|
}
|
|
316
355
|
await options.beforeScreenshot?.({
|
|
317
|
-
runStabilization: (stabilizationOptions) => waitForReadiness(
|
|
356
|
+
runStabilization: (stabilizationOptions) => waitForReadiness(handler, {
|
|
318
357
|
...options,
|
|
319
358
|
stabilize: stabilizationOptions ?? options.stabilize
|
|
320
359
|
})
|
|
321
360
|
});
|
|
322
|
-
await waitForReadiness(
|
|
323
|
-
const afterEach = await beforeEach(
|
|
324
|
-
await waitForReadiness(
|
|
361
|
+
await waitForReadiness(handler, options);
|
|
362
|
+
const afterEach = await beforeEach(handler, options);
|
|
363
|
+
await waitForReadiness(handler, options);
|
|
325
364
|
await Promise.all([
|
|
326
|
-
|
|
365
|
+
screenshotTarget.screenshot({
|
|
327
366
|
path: screenshotPath,
|
|
328
367
|
type: "png",
|
|
329
368
|
fullPage,
|
|
330
|
-
mask: [
|
|
369
|
+
mask: [handler.locator('[data-visual-test="blackout"]')],
|
|
331
370
|
animations: "disabled",
|
|
332
371
|
...playwrightOptions
|
|
333
372
|
}),
|
|
334
373
|
writeMetadata(screenshotPath, metadata)
|
|
335
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
|
+
];
|
|
336
387
|
if (useArgosReporter && testInfo) {
|
|
337
|
-
await Promise.all(
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
})
|
|
346
|
-
]);
|
|
388
|
+
await Promise.all(
|
|
389
|
+
attachments.map(
|
|
390
|
+
(attachment) => testInfo.attach(attachment.name, {
|
|
391
|
+
path: attachment.path,
|
|
392
|
+
contentType: attachment.contentType
|
|
393
|
+
})
|
|
394
|
+
)
|
|
395
|
+
);
|
|
347
396
|
}
|
|
348
397
|
await afterEach();
|
|
349
398
|
await options.afterScreenshot?.();
|
|
399
|
+
return attachments;
|
|
350
400
|
};
|
|
401
|
+
const allAttachments = [];
|
|
351
402
|
if (viewports) {
|
|
403
|
+
if (checkIsFrame(handler)) {
|
|
404
|
+
throw new Error(`viewports option is not supported with an iframe`);
|
|
405
|
+
}
|
|
352
406
|
for (const viewport of viewports) {
|
|
353
407
|
const viewportSize = resolveViewport(viewport);
|
|
354
|
-
await setViewportSize(
|
|
355
|
-
await stabilizeAndScreenshot(
|
|
408
|
+
await setViewportSize(handler, viewportSize);
|
|
409
|
+
const attachments = await stabilizeAndScreenshot(
|
|
356
410
|
getScreenshotName(name, { viewportWidth: viewportSize.width })
|
|
357
411
|
);
|
|
412
|
+
allAttachments.push(...attachments);
|
|
413
|
+
}
|
|
414
|
+
if (!originalViewportSize) {
|
|
415
|
+
throw new Error(`Invariant: viewport size must be saved`);
|
|
358
416
|
}
|
|
359
|
-
await setViewportSize(
|
|
417
|
+
await setViewportSize(handler, originalViewportSize);
|
|
360
418
|
} else {
|
|
361
|
-
await stabilizeAndScreenshot(name);
|
|
419
|
+
const attachments = await stabilizeAndScreenshot(name);
|
|
420
|
+
allAttachments.push(...attachments);
|
|
362
421
|
}
|
|
363
422
|
await afterAll();
|
|
423
|
+
return allAttachments;
|
|
364
424
|
}
|
|
365
425
|
|
|
366
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.2.
|
|
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
|
}
|