@smoothdeploy/playwright 1.63.0-beta-1791031101000 → 1.63.0-beta-1794047129000
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.
Potentially problematic release.
This version of @smoothdeploy/playwright might be problematic. Click here for more details.
- package/lib/index.js +47 -18
- package/lib/runner/index.js +51 -43
- package/lib/runner/index.js.txt +2 -2
- package/package.json +3 -3
package/lib/index.js
CHANGED
|
@@ -273,7 +273,7 @@ const playwrightFixtures = {
|
|
|
273
273
|
clientCertificates: [({ contextOptions }, use) => use(contextOptions.clientCertificates), { option: true, box: true }],
|
|
274
274
|
timezoneId: [({ contextOptions }, use) => use(contextOptions.timezoneId), { option: true, box: true }],
|
|
275
275
|
userAgent: [({ contextOptions }, use) => use(contextOptions.userAgent), { option: true, box: true }],
|
|
276
|
-
viewport: [({ contextOptions }, use) => use(contextOptions.viewport === void 0 ?
|
|
276
|
+
viewport: [({ contextOptions }, use) => use(contextOptions.viewport === void 0 ? { width: 1280, height: 720 } : contextOptions.viewport), { option: true, box: true }],
|
|
277
277
|
actionTimeout: [0, { option: true, box: true }],
|
|
278
278
|
navigationTimeout: [0, { option: true, box: true }],
|
|
279
279
|
baseURL: [async ({}, use) => {
|
|
@@ -382,6 +382,7 @@ const playwrightFixtures = {
|
|
|
382
382
|
_contextFactory: [async ({
|
|
383
383
|
browser,
|
|
384
384
|
video,
|
|
385
|
+
resultScreenshots,
|
|
385
386
|
_reuseContext,
|
|
386
387
|
_combinedContextOptions
|
|
387
388
|
/** mitigate dep-via-auto lack of traceability */
|
|
@@ -404,7 +405,8 @@ const playwrightFixtures = {
|
|
|
404
405
|
const videoOptions = captureVideo ? {
|
|
405
406
|
recordVideo: {
|
|
406
407
|
dir: tracing().artifactsDir(),
|
|
407
|
-
size
|
|
408
|
+
// Video locks the shared screencast size, so default it to the viewport to keep result screenshots at full resolution.
|
|
409
|
+
size: (typeof video === "string" ? void 0 : video.size) ?? (resultScreenshots ? options?.viewport ?? _combinedContextOptions.viewport ?? void 0 : void 0),
|
|
408
410
|
showActions: show?.actions
|
|
409
411
|
}
|
|
410
412
|
} : {};
|
|
@@ -752,6 +754,7 @@ class ArtifactsRecorder {
|
|
|
752
754
|
}
|
|
753
755
|
async didFinishTest() {
|
|
754
756
|
await this.didFinishTestFunction();
|
|
757
|
+
await Promise.all(_pendingResultScreenshots.splice(0));
|
|
755
758
|
const leftoverContexts = this._playwright._allContexts();
|
|
756
759
|
const leftoverApiRequests = Array.from(this._playwright.request._contexts);
|
|
757
760
|
await Promise.all(leftoverContexts.map(async (context2) => {
|
|
@@ -814,6 +817,34 @@ class ArtifactsRecorder {
|
|
|
814
817
|
}
|
|
815
818
|
}
|
|
816
819
|
let _capturingResultScreenshot = false;
|
|
820
|
+
const _pendingResultScreenshots = [];
|
|
821
|
+
const _screencastFrames = /* @__PURE__ */ new WeakMap();
|
|
822
|
+
async function latestScreencastFrame(page, size, after) {
|
|
823
|
+
let state = _screencastFrames.get(page);
|
|
824
|
+
if (!state) {
|
|
825
|
+
const s = { timestamp: 0 };
|
|
826
|
+
state = s;
|
|
827
|
+
_screencastFrames.set(page, s);
|
|
828
|
+
await page._wrapApiCall(() => page.screencast.start({
|
|
829
|
+
size: size ?? void 0,
|
|
830
|
+
quality: 90,
|
|
831
|
+
onFrame: (frame) => {
|
|
832
|
+
s.data = frame.data;
|
|
833
|
+
s.timestamp = frame.timestamp;
|
|
834
|
+
s.onFrame?.();
|
|
835
|
+
}
|
|
836
|
+
}), { internal: true });
|
|
837
|
+
}
|
|
838
|
+
const start = Date.now();
|
|
839
|
+
const deadline = () => start + (state.data ? 100 : 2e3);
|
|
840
|
+
while ((!state.data || state.timestamp < after) && Date.now() < deadline()) {
|
|
841
|
+
await new Promise((resolve) => {
|
|
842
|
+
state.onFrame = resolve;
|
|
843
|
+
setTimeout(resolve, deadline() - Date.now());
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
return state.data;
|
|
847
|
+
}
|
|
817
848
|
async function captureResultScreenshot(channel, data, testInfo) {
|
|
818
849
|
if (_capturingResultScreenshot)
|
|
819
850
|
return;
|
|
@@ -840,25 +871,23 @@ async function captureResultScreenshot(channel, data, testInfo) {
|
|
|
840
871
|
const cssViewport = await page._wrapApiCall(async () => {
|
|
841
872
|
return await frame.evaluate(() => ({ width: window.innerWidth, height: window.innerHeight }));
|
|
842
873
|
}, { internal: true }).catch(() => null);
|
|
843
|
-
const
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
animations: "disabled",
|
|
847
|
-
timeout: 5e3,
|
|
848
|
-
style: "x-pw-glass { display: none !important; }"
|
|
849
|
-
});
|
|
850
|
-
}, { internal: true });
|
|
851
|
-
const { full, cropped } = import_coreBundle.server.compositeHighlight(pngBuffer, box, cssViewport);
|
|
874
|
+
const jpeg = await latestScreencastFrame(page, cssViewport, Date.now());
|
|
875
|
+
if (!jpeg)
|
|
876
|
+
return;
|
|
852
877
|
const safeTestId = testInfo.testId.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
853
878
|
const safeStepId = (data.stepId ?? "unknown").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
854
879
|
const screenshotDir = import_path.default.join(process.cwd(), ".smoothdeploy-output", "screenshots", safeTestId);
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
880
|
+
_pendingResultScreenshots.push(new Promise((resolve) => setImmediate(resolve)).then(async () => {
|
|
881
|
+
const { full, cropped } = import_coreBundle.server.compositeHighlight(jpeg, box, cssViewport);
|
|
882
|
+
await import_fs.default.promises.mkdir(screenshotDir, { recursive: true });
|
|
883
|
+
const encode = (image) => {
|
|
884
|
+
const png = new import_utilsBundle.PNG({ width: image.width, height: image.height });
|
|
885
|
+
png.data = image.data;
|
|
886
|
+
return import_utilsBundle.PNG.sync.write(png);
|
|
887
|
+
};
|
|
888
|
+
await import_fs.default.promises.writeFile(import_path.default.join(screenshotDir, `${safeStepId}-page.png`), encode(full));
|
|
889
|
+
await import_fs.default.promises.writeFile(import_path.default.join(screenshotDir, `${safeStepId}-element.png`), encode(cropped));
|
|
890
|
+
}).catch((e) => debugLogger.log("error", `failed to write result screenshot: ${e}`)));
|
|
862
891
|
} catch {
|
|
863
892
|
} finally {
|
|
864
893
|
_capturingResultScreenshot = false;
|
package/lib/runner/index.js
CHANGED
|
@@ -5308,7 +5308,7 @@ var SmoothDeployReporter = class {
|
|
|
5308
5308
|
this._retries = /* @__PURE__ */ new WeakMap();
|
|
5309
5309
|
this._rootCursors = /* @__PURE__ */ new Map();
|
|
5310
5310
|
this._testSteps = /* @__PURE__ */ new Map();
|
|
5311
|
-
this.
|
|
5311
|
+
this._projectNames = [];
|
|
5312
5312
|
this._stepIdMap = /* @__PURE__ */ new Map();
|
|
5313
5313
|
}
|
|
5314
5314
|
version() {
|
|
@@ -5319,6 +5319,7 @@ var SmoothDeployReporter = class {
|
|
|
5319
5319
|
}
|
|
5320
5320
|
onConfigure(config2) {
|
|
5321
5321
|
this._configDir = config2.configFile ? path13.dirname(config2.configFile) : config2.rootDir;
|
|
5322
|
+
this._projectNames = config2.projects.map((p) => p.name);
|
|
5322
5323
|
const manifestPath = path13.join(this._configDir, ".smoothdeploy-manifest.json");
|
|
5323
5324
|
if (fs10.existsSync(manifestPath))
|
|
5324
5325
|
this._manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf-8"));
|
|
@@ -5340,13 +5341,14 @@ var SmoothDeployReporter = class {
|
|
|
5340
5341
|
return void 0;
|
|
5341
5342
|
}
|
|
5342
5343
|
_resolveManifestTest(test) {
|
|
5344
|
+
const projectName = test.parent.project()?.name ?? "";
|
|
5343
5345
|
const manifestTest = this._findManifestTest(test);
|
|
5344
5346
|
if (!manifestTest)
|
|
5345
|
-
return { manifestTest: { id: test.id, title: test.title, steps: [] },
|
|
5346
|
-
const single = manifestTest.
|
|
5347
|
+
return { manifestTest: { id: test.id, title: test.title, steps: [] }, projectName, passthrough: true };
|
|
5348
|
+
const single = manifestTest.steps.length === 1 ? manifestTest.steps[0] : void 0;
|
|
5347
5349
|
if (single && single.action === "script")
|
|
5348
|
-
return {
|
|
5349
|
-
return {
|
|
5350
|
+
return { manifestTest, projectName, passthrough: true, passthroughRootId: single.id };
|
|
5351
|
+
return { manifestTest, projectName, passthrough: false };
|
|
5350
5352
|
}
|
|
5351
5353
|
_findManifestTest(test) {
|
|
5352
5354
|
if (!this._manifest)
|
|
@@ -5367,29 +5369,17 @@ var SmoothDeployReporter = class {
|
|
|
5367
5369
|
currentSuites = suite.suites;
|
|
5368
5370
|
currentTests = suite.tests;
|
|
5369
5371
|
}
|
|
5370
|
-
|
|
5371
|
-
if (exactMatch)
|
|
5372
|
-
return { manifestTest: exactMatch, paramIndex: 0 };
|
|
5373
|
-
for (const mt of currentTests) {
|
|
5374
|
-
if (!mt.params || mt.params < 1 || !test.title.startsWith(mt.title))
|
|
5375
|
-
continue;
|
|
5376
|
-
const suffix = test.title.slice(mt.title.length);
|
|
5377
|
-
const idx = parseInt(suffix, 10);
|
|
5378
|
-
if (String(idx) === suffix && idx >= 0 && idx < mt.params)
|
|
5379
|
-
return { manifestTest: mt, paramIndex: idx };
|
|
5380
|
-
}
|
|
5381
|
-
return null;
|
|
5372
|
+
return currentTests.find((t2) => t2.title === test.title) ?? null;
|
|
5382
5373
|
}
|
|
5383
5374
|
onTestBegin(test, result) {
|
|
5384
5375
|
const resolved = this._resolveManifestTest(test);
|
|
5385
5376
|
this._resolvedTests.set(test.id, resolved);
|
|
5386
|
-
this._testIdMap.set(safeId(test.id), safeId(resolved.manifestTest.id));
|
|
5387
5377
|
this._rootCursors.set(test.id, 0);
|
|
5388
5378
|
this._testSteps.set(test.id, []);
|
|
5389
5379
|
this._emit({
|
|
5390
5380
|
event: "testBegin",
|
|
5391
5381
|
testId: resolved.manifestTest.id,
|
|
5392
|
-
|
|
5382
|
+
projectName: resolved.projectName,
|
|
5393
5383
|
testTitle: test.title,
|
|
5394
5384
|
timestamp: Date.now()
|
|
5395
5385
|
});
|
|
@@ -5397,7 +5387,7 @@ var SmoothDeployReporter = class {
|
|
|
5397
5387
|
this._emit({
|
|
5398
5388
|
event: "stepBegin",
|
|
5399
5389
|
testId: resolved.manifestTest.id,
|
|
5400
|
-
|
|
5390
|
+
projectName: resolved.projectName,
|
|
5401
5391
|
id: resolved.passthroughRootId,
|
|
5402
5392
|
action: "script",
|
|
5403
5393
|
title: test.title,
|
|
@@ -5414,7 +5404,7 @@ var SmoothDeployReporter = class {
|
|
|
5414
5404
|
this._emit({
|
|
5415
5405
|
event: "stepEnd",
|
|
5416
5406
|
testId: resolved.manifestTest.id,
|
|
5417
|
-
|
|
5407
|
+
projectName: resolved.projectName,
|
|
5418
5408
|
id: resolved.passthroughRootId,
|
|
5419
5409
|
action: "script",
|
|
5420
5410
|
title: test.title,
|
|
@@ -5426,7 +5416,7 @@ var SmoothDeployReporter = class {
|
|
|
5426
5416
|
this._emit({
|
|
5427
5417
|
event: "testEnd",
|
|
5428
5418
|
testId: resolved.manifestTest.id,
|
|
5429
|
-
|
|
5419
|
+
projectName: resolved.projectName,
|
|
5430
5420
|
testTitle: test.title,
|
|
5431
5421
|
status: result.status,
|
|
5432
5422
|
duration: result.duration,
|
|
@@ -5521,7 +5511,7 @@ var SmoothDeployReporter = class {
|
|
|
5521
5511
|
this._emit({
|
|
5522
5512
|
event: "stepBegin",
|
|
5523
5513
|
testId: resolved.manifestTest.id,
|
|
5524
|
-
|
|
5514
|
+
projectName: resolved.projectName,
|
|
5525
5515
|
id: manifestStep.id,
|
|
5526
5516
|
action: manifestStep.action,
|
|
5527
5517
|
title: step.title,
|
|
@@ -5530,7 +5520,7 @@ var SmoothDeployReporter = class {
|
|
|
5530
5520
|
}, step);
|
|
5531
5521
|
}
|
|
5532
5522
|
_screenshotsFor(test, step) {
|
|
5533
|
-
const hasScreenshot = step.category === "pw:api" && !NO_SCREENSHOT_PREFIXES.some((prefix) => step.title.startsWith(prefix));
|
|
5523
|
+
const hasScreenshot = (step.category === "pw:api" || step.category === "expect") && !NO_SCREENSHOT_PREFIXES.some((prefix) => step.title.startsWith(prefix));
|
|
5534
5524
|
if (!hasScreenshot)
|
|
5535
5525
|
return null;
|
|
5536
5526
|
const safeStepId = safeId(step._stepId ?? step.title);
|
|
@@ -5578,7 +5568,7 @@ var SmoothDeployReporter = class {
|
|
|
5578
5568
|
this._emit({
|
|
5579
5569
|
event: "stepEnd",
|
|
5580
5570
|
testId: resolved.manifestTest.id,
|
|
5581
|
-
|
|
5571
|
+
projectName: resolved.projectName,
|
|
5582
5572
|
id: matched.manifest.id,
|
|
5583
5573
|
action: matched.manifest.action,
|
|
5584
5574
|
title: step.title,
|
|
@@ -5591,8 +5581,9 @@ var SmoothDeployReporter = class {
|
|
|
5591
5581
|
onEnd(result) {
|
|
5592
5582
|
const outputDir = path13.join(process.cwd(), ".smoothdeploy-output");
|
|
5593
5583
|
const screenshotsDir = path13.join(outputDir, "screenshots");
|
|
5594
|
-
|
|
5595
|
-
|
|
5584
|
+
const screenshotDirs = this._screenshotDirs();
|
|
5585
|
+
for (const testId of screenshotDirs.keys()) {
|
|
5586
|
+
const testDir = path13.join(screenshotsDir, safeId(testId));
|
|
5596
5587
|
if (!fs10.existsSync(testDir))
|
|
5597
5588
|
continue;
|
|
5598
5589
|
for (const [safePwStepId, safeManifestStepId] of this._stepIdMap) {
|
|
@@ -5603,22 +5594,26 @@ var SmoothDeployReporter = class {
|
|
|
5603
5594
|
}
|
|
5604
5595
|
}
|
|
5605
5596
|
}
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
const
|
|
5597
|
+
const byDepth = [...screenshotDirs].sort(([, a], [, b]) => a.split("/").length - b.split("/").length);
|
|
5598
|
+
for (const [testId, dir] of byDepth) {
|
|
5599
|
+
const src = path13.join(screenshotsDir, safeId(testId));
|
|
5600
|
+
const dst = path13.join(screenshotsDir, dir);
|
|
5609
5601
|
if (src !== dst && fs10.existsSync(src)) {
|
|
5610
5602
|
if (fs10.existsSync(dst))
|
|
5611
5603
|
fs10.rmSync(dst, { recursive: true });
|
|
5604
|
+
fs10.mkdirSync(path13.dirname(dst), { recursive: true });
|
|
5612
5605
|
fs10.renameSync(src, dst);
|
|
5613
5606
|
}
|
|
5614
5607
|
}
|
|
5615
|
-
const remapScreenshotPaths = (steps) => {
|
|
5608
|
+
const remapScreenshotPaths = (steps, testId, dir) => {
|
|
5616
5609
|
for (const step of steps) {
|
|
5617
5610
|
if (step.screenshots) {
|
|
5618
|
-
step.screenshots.page = this._remapPath(step.screenshots.page);
|
|
5619
|
-
step.screenshots.element = this._remapPath(step.screenshots.element);
|
|
5611
|
+
step.screenshots.page = this._remapPath(step.screenshots.page, testId, dir);
|
|
5612
|
+
step.screenshots.element = this._remapPath(step.screenshots.element, testId, dir);
|
|
5613
|
+
if (!fs10.existsSync(path13.join(process.cwd(), step.screenshots.page)))
|
|
5614
|
+
step.screenshots = null;
|
|
5620
5615
|
}
|
|
5621
|
-
remapScreenshotPaths(step.children);
|
|
5616
|
+
remapScreenshotPaths(step.children, testId, dir);
|
|
5622
5617
|
}
|
|
5623
5618
|
};
|
|
5624
5619
|
const manifest = {};
|
|
@@ -5626,23 +5621,36 @@ var SmoothDeployReporter = class {
|
|
|
5626
5621
|
const resolved = this._resolvedTests.get(testId);
|
|
5627
5622
|
if (!resolved)
|
|
5628
5623
|
continue;
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
const
|
|
5632
|
-
const failureScreenshot = fs10.existsSync(failurePath) ? `.smoothdeploy-output/screenshots/${safeManifestTestId}/failure.png` : null;
|
|
5624
|
+
const dir = screenshotDirs.get(testId);
|
|
5625
|
+
remapScreenshotPaths(steps, testId, dir);
|
|
5626
|
+
const failureScreenshot = fs10.existsSync(path13.join(screenshotsDir, dir, "failure.png")) ? `.smoothdeploy-output/screenshots/${dir}/failure.png` : null;
|
|
5633
5627
|
const key = resolved.manifestTest.id;
|
|
5634
5628
|
if (!manifest[key])
|
|
5635
5629
|
manifest[key] = [];
|
|
5636
|
-
manifest[key].push({
|
|
5630
|
+
manifest[key].push({ projectName: resolved.projectName, steps, failureScreenshot });
|
|
5637
5631
|
}
|
|
5638
5632
|
fs10.mkdirSync(outputDir, { recursive: true });
|
|
5639
5633
|
fs10.writeFileSync(path13.join(outputDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
5640
5634
|
this._emit({ event: "runEnd", status: result.status, timestamp: Date.now() });
|
|
5641
5635
|
}
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5636
|
+
// The first configured project keeps screenshots/<testId>/, which the console builds remote-run URLs from; other projects get a subfolder.
|
|
5637
|
+
_screenshotDirs() {
|
|
5638
|
+
const primary = /* @__PURE__ */ new Map();
|
|
5639
|
+
for (const [testId, resolved] of this._resolvedTests) {
|
|
5640
|
+
const rank = this._projectNames.indexOf(resolved.projectName);
|
|
5641
|
+
const current = primary.get(resolved.manifestTest.id);
|
|
5642
|
+
if (!current || rank < current.rank)
|
|
5643
|
+
primary.set(resolved.manifestTest.id, { testId, rank });
|
|
5644
|
+
}
|
|
5645
|
+
const dirs = /* @__PURE__ */ new Map();
|
|
5646
|
+
for (const [testId, resolved] of this._resolvedTests) {
|
|
5647
|
+
const base = safeId(resolved.manifestTest.id);
|
|
5648
|
+
dirs.set(testId, primary.get(resolved.manifestTest.id).testId === testId ? base : `${base}/${safeId(resolved.projectName) || "default"}`);
|
|
5649
|
+
}
|
|
5650
|
+
return dirs;
|
|
5651
|
+
}
|
|
5652
|
+
_remapPath(screenshotPath, testId, dir) {
|
|
5653
|
+
let result = screenshotPath.replace(`/${safeId(testId)}/`, `/${dir}/`);
|
|
5646
5654
|
for (const [safePwStepId, safeManifestStepId] of this._stepIdMap)
|
|
5647
5655
|
result = result.replace(`/${safePwStepId}-`, `/${safeManifestStepId}-`);
|
|
5648
5656
|
return result;
|
package/lib/runner/index.js.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# packages/playwright/lib/runner/index.js
|
|
2
|
-
# total:
|
|
2
|
+
# total: 325.4 KB
|
|
3
3
|
|
|
4
4
|
## Inlined (49)
|
|
5
5
|
1.3 KB packages/playwright/src/isomorphic/events.ts
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
3.0 KB packages/playwright/src/reporters/multiplexer.ts
|
|
28
28
|
8.9 KB packages/playwright/src/reporters/perfetto.ts
|
|
29
29
|
2.1 KB packages/playwright/src/reporters/reporterV2.ts
|
|
30
|
-
13.
|
|
30
|
+
13.9 KB packages/playwright/src/reporters/smoothdeploy.ts
|
|
31
31
|
3.1 KB packages/playwright/src/reporters/smoothdeployMatch.ts
|
|
32
32
|
8.8 KB packages/playwright/src/reporters/teleEmitter.ts
|
|
33
33
|
20.6 KB packages/playwright/src/runner/dispatcher.ts
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smoothdeploy/playwright",
|
|
3
|
-
"version": "1.63.0-beta-
|
|
3
|
+
"version": "1.63.0-beta-1794047129000",
|
|
4
4
|
"description": "A high-level API to automate web browsers",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/microsoft/playwright.git"
|
|
8
8
|
},
|
|
9
|
-
"homepage": "https://
|
|
9
|
+
"homepage": "https://smoothdeploy.com",
|
|
10
10
|
"engines": {
|
|
11
11
|
"node": ">=20"
|
|
12
12
|
},
|
|
@@ -50,6 +50,6 @@
|
|
|
50
50
|
},
|
|
51
51
|
"license": "Apache-2.0",
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"playwright-core": "npm:@smoothdeploy/playwright-core@1.63.0-beta-
|
|
53
|
+
"playwright-core": "npm:@smoothdeploy/playwright-core@1.63.0-beta-1794047129000"
|
|
54
54
|
}
|
|
55
55
|
}
|