playwright 1.55.0-alpha-1754386682000 → 1.55.0-alpha-2025-08-07

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 playwright might be problematic. Click here for more details.

Files changed (2) hide show
  1. package/lib/index.js +77 -71
  2. package/package.json +2 -2
package/lib/index.js CHANGED
@@ -103,16 +103,12 @@ const playwrightFixtures = {
103
103
  }
104
104
  });
105
105
  await use(browser2);
106
- await browser2._wrapApiCall(async () => {
107
- await browser2.close({ reason: "Test ended." });
108
- }, { internal: true });
106
+ await browser2.close({ reason: "Test ended." });
109
107
  return;
110
108
  }
111
109
  const browser = await playwright[browserName].launch();
112
110
  await use(browser);
113
- await browser._wrapApiCall(async () => {
114
- await browser.close({ reason: "Test ended." });
115
- }, { internal: true });
111
+ await browser.close({ reason: "Test ended." });
116
112
  }, { scope: "worker", timeout: 0 }],
117
113
  acceptDownloads: [({ contextOptions }, use) => use(contextOptions.acceptDownloads ?? true), { option: true }],
118
114
  bypassCSP: [({ contextOptions }, use) => use(contextOptions.bypassCSP ?? false), { option: true }],
@@ -310,6 +306,7 @@ const playwrightFixtures = {
310
306
  const videoMode = normalizeVideoMode(video);
311
307
  const captureVideo = shouldCaptureVideo(videoMode, testInfo) && !_reuseContext;
312
308
  const contexts = /* @__PURE__ */ new Map();
309
+ let counter = 0;
313
310
  await use(async (options) => {
314
311
  const hook = testInfoImpl._currentHookType();
315
312
  if (hook === "beforeAll" || hook === "afterAll") {
@@ -326,10 +323,6 @@ const playwrightFixtures = {
326
323
  }
327
324
  } : {};
328
325
  const context = await browser.newContext({ ...videoOptions, ...options });
329
- const contextData = { pagesWithVideo: [] };
330
- contexts.set(context, contextData);
331
- if (captureVideo)
332
- context.on("page", (page) => contextData.pagesWithVideo.push(page));
333
326
  if (process.env.PW_CLOCK === "frozen") {
334
327
  await context._wrapApiCall(async () => {
335
328
  await context.clock.install({ time: 0 });
@@ -340,30 +333,36 @@ const playwrightFixtures = {
340
333
  await context.clock.install({ time: 0 });
341
334
  }, { internal: true });
342
335
  }
343
- return context;
344
- });
345
- let counter = 0;
346
- const closeReason = testInfo.status === "timedOut" ? "Test timeout of " + testInfo.timeout + "ms exceeded." : "Test ended.";
347
- await Promise.all([...contexts.keys()].map(async (context) => {
348
- await context._wrapApiCall(async () => {
336
+ let closed = false;
337
+ const close = async () => {
338
+ if (closed)
339
+ return;
340
+ closed = true;
341
+ const closeReason = testInfo.status === "timedOut" ? "Test timeout of " + testInfo.timeout + "ms exceeded." : "Test ended.";
349
342
  await context.close({ reason: closeReason });
350
- }, { internal: true });
351
- const testFailed = testInfo.status !== testInfo.expectedStatus;
352
- const preserveVideo = captureVideo && (videoMode === "on" || testFailed && videoMode === "retain-on-failure" || videoMode === "on-first-retry" && testInfo.retry === 1);
353
- if (preserveVideo) {
354
- const { pagesWithVideo: pagesForVideo } = contexts.get(context);
355
- const videos = pagesForVideo.map((p) => p.video()).filter(Boolean);
356
- await Promise.all(videos.map(async (v) => {
357
- try {
358
- const savedPath = testInfo.outputPath(`video${counter ? "-" + counter : ""}.webm`);
359
- ++counter;
360
- await v.saveAs(savedPath);
361
- testInfo.attachments.push({ name: "video", path: savedPath, contentType: "video/webm" });
362
- } catch (e) {
363
- }
364
- }));
365
- }
366
- }));
343
+ const testFailed = testInfo.status !== testInfo.expectedStatus;
344
+ const preserveVideo = captureVideo && (videoMode === "on" || testFailed && videoMode === "retain-on-failure" || videoMode === "on-first-retry" && testInfo.retry === 1);
345
+ if (preserveVideo) {
346
+ const { pagesWithVideo: pagesForVideo } = contexts.get(context);
347
+ const videos = pagesForVideo.map((p) => p.video()).filter((video2) => !!video2);
348
+ await Promise.all(videos.map(async (v) => {
349
+ try {
350
+ const savedPath = testInfo.outputPath(`video${counter ? "-" + counter : ""}.webm`);
351
+ ++counter;
352
+ await v.saveAs(savedPath);
353
+ testInfo.attachments.push({ name: "video", path: savedPath, contentType: "video/webm" });
354
+ } catch (e) {
355
+ }
356
+ }));
357
+ }
358
+ };
359
+ const contextData = { close, pagesWithVideo: [] };
360
+ if (captureVideo)
361
+ context.on("page", (page) => contextData.pagesWithVideo.push(page));
362
+ contexts.set(context, contextData);
363
+ return { context, close };
364
+ });
365
+ await Promise.all([...contexts.values()].map((data) => data.close()));
367
366
  }, { scope: "test", title: "context", box: true }],
368
367
  _optionContextReuseMode: ["none", { scope: "worker", option: true }],
369
368
  _optionConnectOptions: [void 0, { scope: "worker", option: true }],
@@ -374,17 +373,19 @@ const playwrightFixtures = {
374
373
  const reuse = mode === "when-possible" && normalizeVideoMode(video) === "off";
375
374
  await use(reuse);
376
375
  }, { scope: "worker", title: "context", box: true }],
377
- context: async ({ playwright, browser, _reuseContext, _contextFactory }, use, testInfo) => {
378
- attachConnectedHeaderIfNeeded(testInfo, browser);
376
+ context: async ({ browser, _reuseContext, _contextFactory }, use, testInfo) => {
377
+ const browserImpl = browser;
378
+ attachConnectedHeaderIfNeeded(testInfo, browserImpl);
379
379
  if (!_reuseContext) {
380
- await use(await _contextFactory());
380
+ const { context: context2, close } = await _contextFactory();
381
+ await use(context2);
382
+ await close();
381
383
  return;
382
384
  }
383
- const defaultContextOptions = playwright.chromium._defaultContextOptions;
384
- const context = await browser._newContextForReuse(defaultContextOptions);
385
+ const context = await browserImpl._wrapApiCall(() => browserImpl._newContextForReuse(), { internal: true });
385
386
  await use(context);
386
387
  const closeReason = testInfo.status === "timedOut" ? "Test timeout of " + testInfo.timeout + "ms exceeded." : "Test ended.";
387
- await browser._disconnectFromReusedContext(closeReason);
388
+ await browserImpl._wrapApiCall(() => browserImpl._disconnectFromReusedContext(closeReason), { internal: true });
388
389
  },
389
390
  page: async ({ context, _reuseContext }, use) => {
390
391
  if (!_reuseContext) {
@@ -548,7 +549,9 @@ class ArtifactsRecorder {
548
549
  const screenshotOptions = typeof screenshot === "string" ? void 0 : screenshot;
549
550
  this._startedCollectingArtifacts = Symbol("startedCollectingArtifacts");
550
551
  this._screenshotRecorder = new SnapshotRecorder(this, normalizeScreenshotMode(screenshot), "screenshot", "image/png", ".png", async (page, path2) => {
551
- await page.screenshot({ ...screenshotOptions, timeout: 5e3, path: path2, caret: "initial" });
552
+ await page._wrapApiCall(async () => {
553
+ await page.screenshot({ ...screenshotOptions, timeout: 5e3, path: path2, caret: "initial" });
554
+ }, { internal: true });
552
555
  });
553
556
  }
554
557
  async willStartTest(testInfo) {
@@ -560,10 +563,10 @@ class ArtifactsRecorder {
560
563
  await Promise.all(existingApiRequests.map((c) => this.didCreateRequestContext(c)));
561
564
  }
562
565
  async didCreateBrowserContext(context) {
563
- await this._startTraceChunkOnContextCreation(context.tracing);
566
+ await this._startTraceChunkOnContextCreation(context, context.tracing);
564
567
  }
565
568
  async willCloseBrowserContext(context) {
566
- await this._stopTracing(context.tracing);
569
+ await this._stopTracing(context, context.tracing);
567
570
  await this._screenshotRecorder.captureTemporary(context);
568
571
  await this._takePageSnapshot(context);
569
572
  }
@@ -578,17 +581,17 @@ class ArtifactsRecorder {
578
581
  if (!page)
579
582
  return;
580
583
  try {
581
- this._pageSnapshot = await page._snapshotForAI({ timeout: 5e3 });
584
+ await page._wrapApiCall(async () => {
585
+ this._pageSnapshot = await page._snapshotForAI({ timeout: 5e3 });
586
+ }, { internal: true });
582
587
  } catch {
583
588
  }
584
589
  }
585
590
  async didCreateRequestContext(context) {
586
- const tracing2 = context._tracing;
587
- await this._startTraceChunkOnContextCreation(tracing2);
591
+ await this._startTraceChunkOnContextCreation(context, context._tracing);
588
592
  }
589
593
  async willCloseRequestContext(context) {
590
- const tracing2 = context._tracing;
591
- await this._stopTracing(tracing2);
594
+ await this._stopTracing(context, context._tracing);
592
595
  }
593
596
  async didFinishTestFunction() {
594
597
  await this._screenshotRecorder.maybeCapture();
@@ -598,10 +601,9 @@ class ArtifactsRecorder {
598
601
  const leftoverContexts = this._playwright._allContexts();
599
602
  const leftoverApiRequests = Array.from(this._playwright.request._contexts);
600
603
  await Promise.all(leftoverContexts.map(async (context2) => {
601
- await this._stopTracing(context2.tracing);
604
+ await this._stopTracing(context2, context2.tracing);
602
605
  }).concat(leftoverApiRequests.map(async (context2) => {
603
- const tracing2 = context2._tracing;
604
- await this._stopTracing(tracing2);
606
+ await this._stopTracing(context2, context2._tracing);
605
607
  })));
606
608
  await this._screenshotRecorder.persistTemporary();
607
609
  const context = leftoverContexts[0];
@@ -624,30 +626,34 @@ class ArtifactsRecorder {
624
626
  }, void 0);
625
627
  }
626
628
  }
627
- async _startTraceChunkOnContextCreation(tracing2) {
628
- const options = this._testInfo._tracing.traceOptions();
629
- if (options) {
630
- const title = this._testInfo._tracing.traceTitle();
631
- const name = this._testInfo._tracing.generateNextTraceRecordingName();
632
- if (!tracing2[kTracingStarted]) {
633
- await tracing2.start({ ...options, title, name });
634
- tracing2[kTracingStarted] = true;
629
+ async _startTraceChunkOnContextCreation(channelOwner, tracing2) {
630
+ await channelOwner._wrapApiCall(async () => {
631
+ const options = this._testInfo._tracing.traceOptions();
632
+ if (options) {
633
+ const title = this._testInfo._tracing.traceTitle();
634
+ const name = this._testInfo._tracing.generateNextTraceRecordingName();
635
+ if (!tracing2[kTracingStarted]) {
636
+ await tracing2.start({ ...options, title, name });
637
+ tracing2[kTracingStarted] = true;
638
+ } else {
639
+ await tracing2.startChunk({ title, name });
640
+ }
635
641
  } else {
636
- await tracing2.startChunk({ title, name });
637
- }
638
- } else {
639
- if (tracing2[kTracingStarted]) {
640
- tracing2[kTracingStarted] = false;
641
- await tracing2.stop();
642
+ if (tracing2[kTracingStarted]) {
643
+ tracing2[kTracingStarted] = false;
644
+ await tracing2.stop();
645
+ }
642
646
  }
643
- }
647
+ }, { internal: true });
644
648
  }
645
- async _stopTracing(tracing2) {
646
- if (tracing2[this._startedCollectingArtifacts])
647
- return;
648
- tracing2[this._startedCollectingArtifacts] = true;
649
- if (this._testInfo._tracing.traceOptions() && tracing2[kTracingStarted])
650
- await tracing2.stopChunk({ path: this._testInfo._tracing.maybeGenerateNextTraceRecordingPath() });
649
+ async _stopTracing(channelOwner, tracing2) {
650
+ await channelOwner._wrapApiCall(async () => {
651
+ if (tracing2[this._startedCollectingArtifacts])
652
+ return;
653
+ tracing2[this._startedCollectingArtifacts] = true;
654
+ if (this._testInfo._tracing.traceOptions() && tracing2[kTracingStarted])
655
+ await tracing2.stopChunk({ path: this._testInfo._tracing.maybeGenerateNextTraceRecordingPath() });
656
+ }, { internal: true });
651
657
  }
652
658
  }
653
659
  function renderTitle(type, method, params, title) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.55.0-alpha-1754386682000",
3
+ "version": "1.55.0-alpha-2025-08-07",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "license": "Apache-2.0",
58
58
  "dependencies": {
59
- "playwright-core": "1.55.0-alpha-1754386682000"
59
+ "playwright-core": "1.55.0-alpha-2025-08-07"
60
60
  },
61
61
  "optionalDependencies": {
62
62
  "fsevents": "2.3.2"