playwright-core 1.55.0-alpha-2025-08-04 → 1.55.0-alpha-2025-08-05
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/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +1 -1
- package/lib/remote/playwrightServer.js +13 -13
- package/lib/server/bidi/bidiBrowser.js +2 -20
- package/lib/server/bidi/bidiPage.js +1 -5
- package/lib/server/browserContext.js +19 -13
- package/lib/server/chromium/crBrowser.js +2 -5
- package/lib/server/chromium/crPage.js +3 -4
- package/lib/server/codegen/language.js +22 -1
- package/lib/server/debugController.js +1 -5
- package/lib/server/dispatchers/browserContextDispatcher.js +1 -5
- package/lib/server/dom.js +4 -5
- package/lib/server/firefox/ffBrowser.js +2 -5
- package/lib/server/frames.js +29 -21
- package/lib/server/page.js +42 -27
- package/lib/server/progress.js +1 -19
- package/lib/server/recorder/recorderUtils.js +0 -5
- package/lib/server/recorder.js +0 -59
- package/lib/server/socksClientCertificatesInterceptor.js +1 -3
- package/lib/server/webkit/wkBrowser.js +2 -5
- package/lib/server/webkit/wkPage.js +2 -2
- package/lib/utils/isomorphic/ariaSnapshot.js +0 -53
- package/lib/vite/recorder/assets/{codeMirrorModule-B5Ye5Cij.js → codeMirrorModule-DcLx_Mux.js} +1 -1
- package/lib/vite/recorder/assets/{index-B5VmX9JT.js → index-DDUAfY0e.js} +28 -28
- package/lib/vite/recorder/index.html +1 -1
- package/lib/vite/traceViewer/assets/{codeMirrorModule-Chakc5qh.js → codeMirrorModule-DieI-Eix.js} +1 -1
- package/lib/vite/traceViewer/assets/{defaultSettingsView-COxW9YdO.js → defaultSettingsView-D3X2EJQX.js} +140 -140
- package/lib/vite/traceViewer/{index.BRvvuaPn.js → index.Dloe-aCz.js} +1 -1
- package/lib/vite/traceViewer/index.html +2 -2
- package/lib/vite/traceViewer/{uiMode.CBXoasNF.js → uiMode.DEbRpPOO.js} +1 -1
- package/lib/vite/traceViewer/uiMode.html +2 -2
- package/package.json +1 -1
package/lib/server/dom.js
CHANGED
|
@@ -377,11 +377,6 @@ class ElementHandle extends js.JSHandle {
|
|
|
377
377
|
return { hitTargetDescription: error };
|
|
378
378
|
}
|
|
379
379
|
hitTargetInterceptionHandle = handle;
|
|
380
|
-
progress.cleanupWhenAborted(() => {
|
|
381
|
-
hitTargetInterceptionHandle.evaluate((h) => h.stop()).catch((e) => {
|
|
382
|
-
});
|
|
383
|
-
hitTargetInterceptionHandle.dispose();
|
|
384
|
-
});
|
|
385
380
|
}
|
|
386
381
|
const actionResult = await this._page.frameManager.waitForSignalsCreatedBy(progress, options.waitAfter === true, async () => {
|
|
387
382
|
if (options.__testHookBeforePointerAction)
|
|
@@ -410,6 +405,10 @@ class ElementHandle extends js.JSHandle {
|
|
|
410
405
|
if (options.__testHookAfterPointerAction)
|
|
411
406
|
await progress.race(options.__testHookAfterPointerAction());
|
|
412
407
|
return "done";
|
|
408
|
+
}).finally(() => {
|
|
409
|
+
const stopPromise = hitTargetInterceptionHandle?.evaluate((h) => h.stop()).catch(() => {
|
|
410
|
+
});
|
|
411
|
+
stopPromise?.then(() => hitTargetInterceptionHandle?.dispose());
|
|
413
412
|
});
|
|
414
413
|
if (actionResult !== "done")
|
|
415
414
|
return actionResult;
|
|
@@ -225,7 +225,7 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
|
|
|
225
225
|
possiblyUninitializedPages() {
|
|
226
226
|
return this._ffPages().map((ffPage) => ffPage._page);
|
|
227
227
|
}
|
|
228
|
-
async doCreateNewPage(
|
|
228
|
+
async doCreateNewPage() {
|
|
229
229
|
const { targetId } = await this._browser.session.send("Browser.newPage", {
|
|
230
230
|
browserContextId: this._browserContextId
|
|
231
231
|
}).catch((e) => {
|
|
@@ -233,10 +233,7 @@ class FFBrowserContext extends import_browserContext.BrowserContext {
|
|
|
233
233
|
throw new Error(`Invalid timezone ID: ${this._options.timezoneId}`);
|
|
234
234
|
throw e;
|
|
235
235
|
});
|
|
236
|
-
|
|
237
|
-
if (markAsServerSideOnly)
|
|
238
|
-
page.markAsServerSideOnly();
|
|
239
|
-
return page;
|
|
236
|
+
return this._browser._ffPages.get(targetId)._page;
|
|
240
237
|
}
|
|
241
238
|
async doGetCookies(urls) {
|
|
242
239
|
const { cookies } = await this._browser.session.send("Browser.getCookies", { browserContextId: this._browserContextId });
|
package/lib/server/frames.js
CHANGED
|
@@ -119,13 +119,15 @@ class FrameManager {
|
|
|
119
119
|
return action();
|
|
120
120
|
const barrier = new SignalBarrier(progress);
|
|
121
121
|
this._signalBarriers.add(barrier);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
122
|
+
try {
|
|
123
|
+
const result = await action();
|
|
124
|
+
await progress.race(this._page.delegate.inputActionEpilogue());
|
|
125
|
+
await barrier.waitFor();
|
|
126
|
+
await new Promise((0, import_utils.makeWaitForNextTask)());
|
|
127
|
+
return result;
|
|
128
|
+
} finally {
|
|
129
|
+
this._signalBarriers.delete(barrier);
|
|
130
|
+
}
|
|
129
131
|
}
|
|
130
132
|
frameWillPotentiallyRequestNavigation() {
|
|
131
133
|
for (const barrier of this._signalBarriers)
|
|
@@ -711,17 +713,16 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
711
713
|
}
|
|
712
714
|
}
|
|
713
715
|
async setContent(progress, html, options) {
|
|
716
|
+
const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;
|
|
714
717
|
await this.raceNavigationAction(progress, async () => {
|
|
715
718
|
const waitUntil = options.waitUntil === void 0 ? "load" : options.waitUntil;
|
|
716
719
|
progress.log(`setting frame content, waiting until "${waitUntil}"`);
|
|
717
|
-
const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;
|
|
718
720
|
const context = await progress.race(this._utilityContext());
|
|
719
721
|
const tagPromise = new import_manualPromise.ManualPromise();
|
|
720
722
|
this._page.frameManager._consoleMessageTags.set(tag, () => {
|
|
721
723
|
this._onClearLifecycle();
|
|
722
724
|
tagPromise.resolve();
|
|
723
725
|
});
|
|
724
|
-
progress.cleanupWhenAborted(() => this._page.frameManager._consoleMessageTags.delete(tag));
|
|
725
726
|
const lifecyclePromise = progress.race(tagPromise).then(() => this._waitForLoadState(progress, waitUntil));
|
|
726
727
|
const contentPromise = progress.race(context.evaluate(({ html: html2, tag: tag2 }) => {
|
|
727
728
|
document.open();
|
|
@@ -731,6 +732,8 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
731
732
|
}, { html, tag }));
|
|
732
733
|
await Promise.all([contentPromise, lifecyclePromise]);
|
|
733
734
|
return null;
|
|
735
|
+
}).finally(() => {
|
|
736
|
+
this._page.frameManager._consoleMessageTags.delete(tag);
|
|
734
737
|
});
|
|
735
738
|
}
|
|
736
739
|
name() {
|
|
@@ -1202,21 +1205,21 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1202
1205
|
const injectedScript = await progress.race(context.injectedScript());
|
|
1203
1206
|
const handle = await progress.race(injectedScript.evaluateHandle((injected, { expression: expression2, isFunction: isFunction2, polling, arg: arg2 }) => {
|
|
1204
1207
|
const predicate = () => {
|
|
1205
|
-
let
|
|
1208
|
+
let result2 = globalThis.eval(expression2);
|
|
1206
1209
|
if (isFunction2 === true) {
|
|
1207
|
-
|
|
1210
|
+
result2 = result2(arg2);
|
|
1208
1211
|
} else if (isFunction2 === false) {
|
|
1209
|
-
|
|
1212
|
+
result2 = result2;
|
|
1210
1213
|
} else {
|
|
1211
|
-
if (typeof
|
|
1212
|
-
|
|
1214
|
+
if (typeof result2 === "function")
|
|
1215
|
+
result2 = result2(arg2);
|
|
1213
1216
|
}
|
|
1214
|
-
return
|
|
1217
|
+
return result2;
|
|
1215
1218
|
};
|
|
1216
1219
|
let fulfill;
|
|
1217
1220
|
let reject;
|
|
1218
1221
|
let aborted = false;
|
|
1219
|
-
const
|
|
1222
|
+
const result = new Promise((f, r) => {
|
|
1220
1223
|
fulfill = f;
|
|
1221
1224
|
reject = r;
|
|
1222
1225
|
});
|
|
@@ -1238,12 +1241,17 @@ class Frame extends import_instrumentation.SdkObject {
|
|
|
1238
1241
|
}
|
|
1239
1242
|
};
|
|
1240
1243
|
next();
|
|
1241
|
-
return { result
|
|
1244
|
+
return { result, abort: () => aborted = true };
|
|
1242
1245
|
}, { expression, isFunction, polling: options.pollingInterval, arg }));
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1246
|
+
try {
|
|
1247
|
+
return await progress.race(handle.evaluateHandle((h) => h.result));
|
|
1248
|
+
} catch (error) {
|
|
1249
|
+
await handle.evaluate((h) => h.abort()).catch(() => {
|
|
1250
|
+
});
|
|
1251
|
+
throw error;
|
|
1252
|
+
} finally {
|
|
1253
|
+
handle.dispose();
|
|
1254
|
+
}
|
|
1247
1255
|
});
|
|
1248
1256
|
}
|
|
1249
1257
|
async waitForFunctionValueInUtility(progress, pageFunction) {
|
package/lib/server/page.js
CHANGED
|
@@ -70,7 +70,6 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
70
70
|
this._workers = /* @__PURE__ */ new Map();
|
|
71
71
|
this.requestInterceptors = [];
|
|
72
72
|
this.video = null;
|
|
73
|
-
this._isServerSideOnly = false;
|
|
74
73
|
this._locatorHandlers = /* @__PURE__ */ new Map();
|
|
75
74
|
this._lastLocatorHandlerUid = 0;
|
|
76
75
|
this._locatorHandlerRunningCounter = 0;
|
|
@@ -90,6 +89,7 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
90
89
|
if (delegate.pdf)
|
|
91
90
|
this.pdf = delegate.pdf.bind(delegate);
|
|
92
91
|
this.coverage = delegate.coverage ? delegate.coverage() : null;
|
|
92
|
+
this.isStorageStatePage = browserContext.isCreatingStorageStatePage();
|
|
93
93
|
}
|
|
94
94
|
static {
|
|
95
95
|
this.Events = {
|
|
@@ -140,12 +140,12 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
140
140
|
return this._initializedPromise;
|
|
141
141
|
}
|
|
142
142
|
emitOnContext(event, ...args) {
|
|
143
|
-
if (this.
|
|
143
|
+
if (this.isStorageStatePage)
|
|
144
144
|
return;
|
|
145
145
|
this.browserContext.emit(event, ...args);
|
|
146
146
|
}
|
|
147
147
|
emitOnContextOnceInitialized(event, ...args) {
|
|
148
|
-
if (this.
|
|
148
|
+
if (this.isStorageStatePage)
|
|
149
149
|
return;
|
|
150
150
|
if (this._initialized)
|
|
151
151
|
this.browserContext.emit(event, ...args);
|
|
@@ -213,10 +213,14 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
213
213
|
await progress.race(this.browserContext.exposePlaywrightBindingIfNeeded());
|
|
214
214
|
const binding = new PageBinding(name, playwrightBinding, needsHandle);
|
|
215
215
|
this._pageBindings.set(name, binding);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
try {
|
|
217
|
+
await progress.race(this.delegate.addInitScript(binding.initScript));
|
|
218
|
+
await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, "main"));
|
|
219
|
+
return binding;
|
|
220
|
+
} catch (error) {
|
|
221
|
+
this._pageBindings.delete(name);
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
220
224
|
}
|
|
221
225
|
async removeExposedBindings(bindings) {
|
|
222
226
|
bindings = bindings.filter((binding) => this._pageBindings.get(binding.name) === binding);
|
|
@@ -229,12 +233,15 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
229
233
|
}
|
|
230
234
|
async setExtraHTTPHeaders(progress, headers) {
|
|
231
235
|
const oldHeaders = this._extraHTTPHeaders;
|
|
232
|
-
|
|
233
|
-
|
|
236
|
+
try {
|
|
237
|
+
this._extraHTTPHeaders = headers;
|
|
238
|
+
await progress.race(this.delegate.updateExtraHTTPHeaders());
|
|
239
|
+
} catch (error) {
|
|
234
240
|
this._extraHTTPHeaders = oldHeaders;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
241
|
+
this.delegate.updateExtraHTTPHeaders().catch(() => {
|
|
242
|
+
});
|
|
243
|
+
throw error;
|
|
244
|
+
}
|
|
238
245
|
}
|
|
239
246
|
extraHTTPHeaders() {
|
|
240
247
|
return this._extraHTTPHeaders;
|
|
@@ -369,10 +376,6 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
369
376
|
}
|
|
370
377
|
async emulateMedia(progress, options) {
|
|
371
378
|
const oldEmulatedMedia = { ...this._emulatedMedia };
|
|
372
|
-
progress.cleanupWhenAborted(async () => {
|
|
373
|
-
this._emulatedMedia = oldEmulatedMedia;
|
|
374
|
-
await this.delegate.updateEmulateMedia();
|
|
375
|
-
});
|
|
376
379
|
if (options.media !== void 0)
|
|
377
380
|
this._emulatedMedia.media = options.media;
|
|
378
381
|
if (options.colorScheme !== void 0)
|
|
@@ -383,7 +386,14 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
383
386
|
this._emulatedMedia.forcedColors = options.forcedColors;
|
|
384
387
|
if (options.contrast !== void 0)
|
|
385
388
|
this._emulatedMedia.contrast = options.contrast;
|
|
386
|
-
|
|
389
|
+
try {
|
|
390
|
+
await progress.race(this.delegate.updateEmulateMedia());
|
|
391
|
+
} catch (error) {
|
|
392
|
+
this._emulatedMedia = oldEmulatedMedia;
|
|
393
|
+
this.delegate.updateEmulateMedia().catch(() => {
|
|
394
|
+
});
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
387
397
|
}
|
|
388
398
|
emulatedMedia() {
|
|
389
399
|
const contextOptions = this.browserContext._options;
|
|
@@ -397,12 +407,15 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
397
407
|
}
|
|
398
408
|
async setViewportSize(progress, viewportSize) {
|
|
399
409
|
const oldEmulatedSize = this._emulatedSize;
|
|
400
|
-
|
|
410
|
+
try {
|
|
411
|
+
this._setEmulatedSize({ viewport: { ...viewportSize }, screen: { ...viewportSize } });
|
|
412
|
+
await progress.race(this.delegate.updateEmulatedViewportSize());
|
|
413
|
+
} catch (error) {
|
|
401
414
|
this._emulatedSize = oldEmulatedSize;
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
415
|
+
this.delegate.updateEmulatedViewportSize().catch(() => {
|
|
416
|
+
});
|
|
417
|
+
throw error;
|
|
418
|
+
}
|
|
406
419
|
}
|
|
407
420
|
setEmulatedSizeFromWindowOpen(emulatedSize) {
|
|
408
421
|
this._setEmulatedSize(emulatedSize);
|
|
@@ -423,8 +436,13 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
423
436
|
async addInitScript(progress, source) {
|
|
424
437
|
const initScript = new InitScript(source);
|
|
425
438
|
this.initScripts.push(initScript);
|
|
426
|
-
|
|
427
|
-
|
|
439
|
+
try {
|
|
440
|
+
await progress.race(this.delegate.addInitScript(initScript));
|
|
441
|
+
} catch (error) {
|
|
442
|
+
this.removeInitScripts([initScript]).catch(() => {
|
|
443
|
+
});
|
|
444
|
+
throw error;
|
|
445
|
+
}
|
|
428
446
|
return initScript;
|
|
429
447
|
}
|
|
430
448
|
async removeInitScripts(initScripts) {
|
|
@@ -630,9 +648,6 @@ class Page extends import_instrumentation.SdkObject {
|
|
|
630
648
|
await Promise.all(this.frames().map((frame) => frame.hideHighlight().catch(() => {
|
|
631
649
|
})));
|
|
632
650
|
}
|
|
633
|
-
markAsServerSideOnly() {
|
|
634
|
-
this._isServerSideOnly = true;
|
|
635
|
-
}
|
|
636
651
|
async snapshotForAI(progress) {
|
|
637
652
|
this.lastSnapshotFrameIds = [];
|
|
638
653
|
const snapshot = await snapshotFrameForAI(progress, this.mainFrame(), 0, this.lastSnapshotFrameIds);
|
package/lib/server/progress.js
CHANGED
|
@@ -30,17 +30,11 @@ class ProgressController {
|
|
|
30
30
|
constructor(metadata, sdkObject) {
|
|
31
31
|
this._forceAbortPromise = new import_manualPromise.ManualPromise();
|
|
32
32
|
this._donePromise = new import_manualPromise.ManualPromise();
|
|
33
|
-
// Cleanups to be run only in the case of abort.
|
|
34
|
-
this._cleanups = [];
|
|
35
33
|
this._state = "before";
|
|
36
34
|
this.metadata = metadata;
|
|
37
35
|
this._sdkObject = sdkObject;
|
|
38
|
-
this._logName = sdkObject.logName || "api";
|
|
39
36
|
this._forceAbortPromise.catch((e) => null);
|
|
40
37
|
}
|
|
41
|
-
setLogName(logName) {
|
|
42
|
-
this._logName = logName;
|
|
43
|
-
}
|
|
44
38
|
async abort(error) {
|
|
45
39
|
if (this._state === "running") {
|
|
46
40
|
error[kAbortErrorSymbol] = true;
|
|
@@ -56,12 +50,7 @@ class ProgressController {
|
|
|
56
50
|
log: (message) => {
|
|
57
51
|
if (this._state === "running")
|
|
58
52
|
this.metadata.log.push(message);
|
|
59
|
-
this._sdkObject.instrumentation.onCallLog(this._sdkObject, this.metadata, this.
|
|
60
|
-
},
|
|
61
|
-
cleanupWhenAborted: (cleanup) => {
|
|
62
|
-
if (this._state !== "running")
|
|
63
|
-
throw new Error("Internal error: cannot register cleanup after operation has finished.");
|
|
64
|
-
this._cleanups.push(cleanup);
|
|
53
|
+
this._sdkObject.instrumentation.onCallLog(this._sdkObject, this.metadata, this._sdkObject.logName || "api", message);
|
|
65
54
|
},
|
|
66
55
|
metadata: this.metadata,
|
|
67
56
|
race: (promise) => {
|
|
@@ -91,7 +80,6 @@ class ProgressController {
|
|
|
91
80
|
return result;
|
|
92
81
|
} catch (error) {
|
|
93
82
|
this._state = { error };
|
|
94
|
-
await Promise.all(this._cleanups.splice(0).map((cleanup) => runCleanup(error, cleanup)));
|
|
95
83
|
throw error;
|
|
96
84
|
} finally {
|
|
97
85
|
clearTimeout(timer);
|
|
@@ -99,12 +87,6 @@ class ProgressController {
|
|
|
99
87
|
}
|
|
100
88
|
}
|
|
101
89
|
}
|
|
102
|
-
async function runCleanup(error, cleanup) {
|
|
103
|
-
try {
|
|
104
|
-
await cleanup(error);
|
|
105
|
-
} catch (e) {
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
90
|
const kAbortErrorSymbol = Symbol("kAbortError");
|
|
109
91
|
function isAbortError(error) {
|
|
110
92
|
return !!error[kAbortErrorSymbol];
|
|
@@ -22,7 +22,6 @@ __export(recorderUtils_exports, {
|
|
|
22
22
|
collapseActions: () => collapseActions,
|
|
23
23
|
frameForAction: () => frameForAction,
|
|
24
24
|
generateFrameSelector: () => generateFrameSelector,
|
|
25
|
-
isAssertAction: () => isAssertAction,
|
|
26
25
|
mainFrameForAction: () => mainFrameForAction,
|
|
27
26
|
metadataToCallLog: () => metadataToCallLog,
|
|
28
27
|
shouldMergeAction: () => shouldMergeAction
|
|
@@ -76,9 +75,6 @@ async function frameForAction(pageAliases, actionInContext, action) {
|
|
|
76
75
|
throw new Error("Internal error: frame not found");
|
|
77
76
|
return result.frame;
|
|
78
77
|
}
|
|
79
|
-
function isAssertAction(action) {
|
|
80
|
-
return action.name.startsWith("assert");
|
|
81
|
-
}
|
|
82
78
|
function isSameAction(a, b) {
|
|
83
79
|
return a.action.name === b.action.name && a.frame.pageAlias === b.frame.pageAlias && a.frame.framePath.join("|") === b.frame.framePath.join("|");
|
|
84
80
|
}
|
|
@@ -155,7 +151,6 @@ async function generateFrameSelectorInParent(parent, frame) {
|
|
|
155
151
|
collapseActions,
|
|
156
152
|
frameForAction,
|
|
157
153
|
generateFrameSelector,
|
|
158
|
-
isAssertAction,
|
|
159
154
|
mainFrameForAction,
|
|
160
155
|
metadataToCallLog,
|
|
161
156
|
shouldMergeAction
|
package/lib/server/recorder.js
CHANGED
|
@@ -48,8 +48,6 @@ var import_utils2 = require("./../utils");
|
|
|
48
48
|
var import_frames = require("./frames");
|
|
49
49
|
var import_page = require("./page");
|
|
50
50
|
var import_recorderRunner = require("./recorder/recorderRunner");
|
|
51
|
-
var import_ariaSnapshot = require("../utils/isomorphic/ariaSnapshot");
|
|
52
|
-
var import_utilsBundle = require("../utilsBundle");
|
|
53
51
|
const recorderSymbol = Symbol("recorderSymbol");
|
|
54
52
|
const RecorderEvent = {
|
|
55
53
|
PausedStateChanged: "pausedStateChanged",
|
|
@@ -442,58 +440,9 @@ class Recorder extends import_events.default {
|
|
|
442
440
|
};
|
|
443
441
|
return actionInContext;
|
|
444
442
|
}
|
|
445
|
-
async _maybeGenerateAssertAction(frame, actionInContext) {
|
|
446
|
-
const lastAction = getLastFrameAction(frame);
|
|
447
|
-
if ((0, import_recorderUtils.isAssertAction)(actionInContext.action))
|
|
448
|
-
return;
|
|
449
|
-
if (lastAction && ((0, import_recorderUtils.isAssertAction)(lastAction.action) || (0, import_recorderUtils.shouldMergeAction)(actionInContext, lastAction)))
|
|
450
|
-
return;
|
|
451
|
-
const newSnapshot = actionInContext.action.ariaSnapshot;
|
|
452
|
-
if (!newSnapshot)
|
|
453
|
-
return;
|
|
454
|
-
const lastSnapshot = lastAction?.action.ariaSnapshot || `- document [ref=e1]
|
|
455
|
-
`;
|
|
456
|
-
if (!lastSnapshot)
|
|
457
|
-
return;
|
|
458
|
-
const callMetadata = (0, import_instrumentation.serverSideCallMetadata)();
|
|
459
|
-
const controller = new import_progress.ProgressController(callMetadata, frame);
|
|
460
|
-
const selector = await controller.run(async (progress) => {
|
|
461
|
-
const ref = (0, import_ariaSnapshot.findNewElementRef)(import_utilsBundle.yaml, lastSnapshot, newSnapshot);
|
|
462
|
-
if (!ref)
|
|
463
|
-
return;
|
|
464
|
-
const { resolvedSelector } = await frame.resolveSelector(progress, `aria-ref=${ref}`, { mainWorld: true }).catch(() => ({ resolvedSelector: void 0 }));
|
|
465
|
-
if (!resolvedSelector)
|
|
466
|
-
return;
|
|
467
|
-
const isVisible = await frame._page.mainFrame().isVisible(progress, resolvedSelector, { strict: true }).catch(() => false);
|
|
468
|
-
return isVisible ? resolvedSelector : void 0;
|
|
469
|
-
}).catch(() => void 0);
|
|
470
|
-
if (!selector)
|
|
471
|
-
return;
|
|
472
|
-
if (!actionInContext.frame.framePath.length && "selector" in actionInContext.action && actionInContext.action.selector === selector)
|
|
473
|
-
return;
|
|
474
|
-
const assertActionInContext = {
|
|
475
|
-
frame: {
|
|
476
|
-
pageGuid: actionInContext.frame.pageGuid,
|
|
477
|
-
pageAlias: actionInContext.frame.pageAlias,
|
|
478
|
-
framePath: []
|
|
479
|
-
},
|
|
480
|
-
action: {
|
|
481
|
-
name: "assertVisible",
|
|
482
|
-
selector,
|
|
483
|
-
signals: []
|
|
484
|
-
},
|
|
485
|
-
startTime: actionInContext.startTime,
|
|
486
|
-
endTime: actionInContext.startTime
|
|
487
|
-
};
|
|
488
|
-
return assertActionInContext;
|
|
489
|
-
}
|
|
490
443
|
async _performAction(frame, action) {
|
|
491
444
|
const actionInContext = await this._createActionInContext(frame, action);
|
|
492
|
-
const assertActionInContext = await this._maybeGenerateAssertAction(frame, actionInContext);
|
|
493
|
-
if (assertActionInContext)
|
|
494
|
-
this._signalProcessor.addAction(assertActionInContext);
|
|
495
445
|
this._signalProcessor.addAction(actionInContext);
|
|
496
|
-
setLastFrameAction(frame, actionInContext);
|
|
497
446
|
if (actionInContext.action.name !== "openPage" && actionInContext.action.name !== "closePage")
|
|
498
447
|
await (0, import_recorderRunner.performAction)(this._pageAliases, actionInContext);
|
|
499
448
|
actionInContext.endTime = (0, import_utils2.monotonicTime)();
|
|
@@ -501,7 +450,6 @@ class Recorder extends import_events.default {
|
|
|
501
450
|
async _recordAction(frame, action) {
|
|
502
451
|
const actionInContext = await this._createActionInContext(frame, action);
|
|
503
452
|
this._signalProcessor.addAction(actionInContext);
|
|
504
|
-
setLastFrameAction(frame, actionInContext);
|
|
505
453
|
}
|
|
506
454
|
_onFrameNavigated(frame, page) {
|
|
507
455
|
const pageAlias = this._pageAliases.get(page);
|
|
@@ -535,13 +483,6 @@ function languageForFile(file) {
|
|
|
535
483
|
return "csharp";
|
|
536
484
|
return "javascript";
|
|
537
485
|
}
|
|
538
|
-
const kLastFrameActionSymbol = Symbol("lastFrameAction");
|
|
539
|
-
function getLastFrameAction(frame) {
|
|
540
|
-
return frame[kLastFrameActionSymbol];
|
|
541
|
-
}
|
|
542
|
-
function setLastFrameAction(frame, action) {
|
|
543
|
-
frame[kLastFrameActionSymbol] = action;
|
|
544
|
-
}
|
|
545
486
|
// Annotate the CommonJS export names for ESM import in node:
|
|
546
487
|
0 && (module.exports = {
|
|
547
488
|
Recorder,
|
|
@@ -210,12 +210,9 @@ class WKBrowserContext extends import_browserContext.BrowserContext {
|
|
|
210
210
|
possiblyUninitializedPages() {
|
|
211
211
|
return this._wkPages().map((wkPage) => wkPage._page);
|
|
212
212
|
}
|
|
213
|
-
async doCreateNewPage(
|
|
213
|
+
async doCreateNewPage() {
|
|
214
214
|
const { pageProxyId } = await this._browser._browserSession.send("Playwright.createPage", { browserContextId: this._browserContextId });
|
|
215
|
-
|
|
216
|
-
if (markAsServerSideOnly)
|
|
217
|
-
page.markAsServerSideOnly();
|
|
218
|
-
return page;
|
|
215
|
+
return this._browser._wkPages.get(pageProxyId)._page;
|
|
219
216
|
}
|
|
220
217
|
async doGetCookies(urls) {
|
|
221
218
|
const { cookies } = await this._browser._browserSession.send("Playwright.getAllCookies", { browserContextId: this._browserContextId });
|
|
@@ -100,7 +100,7 @@ class WKPage {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
async _initializePageProxySession() {
|
|
103
|
-
if (this._page.
|
|
103
|
+
if (this._page.isStorageStatePage)
|
|
104
104
|
return;
|
|
105
105
|
const promises = [
|
|
106
106
|
this._pageProxySession.send("Dialog.enable"),
|
|
@@ -169,7 +169,7 @@ class WKPage {
|
|
|
169
169
|
promises.push(session.send("Network.setResourceCachingDisabled", { disabled: true }));
|
|
170
170
|
promises.push(session.send("Network.addInterception", { url: ".*", stage: "request", isRegex: true }));
|
|
171
171
|
}
|
|
172
|
-
if (this._page.
|
|
172
|
+
if (this._page.isStorageStatePage) {
|
|
173
173
|
await Promise.all(promises);
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
@@ -20,7 +20,6 @@ var ariaSnapshot_exports = {};
|
|
|
20
20
|
__export(ariaSnapshot_exports, {
|
|
21
21
|
KeyParser: () => KeyParser,
|
|
22
22
|
ParserError: () => ParserError,
|
|
23
|
-
findNewElementRef: () => findNewElementRef,
|
|
24
23
|
parseAriaSnapshot: () => parseAriaSnapshot,
|
|
25
24
|
parseAriaSnapshotUnsafe: () => parseAriaSnapshotUnsafe,
|
|
26
25
|
valueOrRegex: () => valueOrRegex
|
|
@@ -333,10 +332,6 @@ class KeyParser {
|
|
|
333
332
|
return result;
|
|
334
333
|
}
|
|
335
334
|
_applyAttribute(node, key, value, errorPos) {
|
|
336
|
-
if (this._options.allowRef && key === "ref") {
|
|
337
|
-
node.ref = value;
|
|
338
|
-
return;
|
|
339
|
-
}
|
|
340
335
|
if (key === "checked") {
|
|
341
336
|
this._assert(value === "true" || value === "false" || value === "mixed", 'Value of "checked" attribute must be a boolean or "mixed"', errorPos);
|
|
342
337
|
node.checked = value === "true" ? true : value === "false" ? false : "mixed";
|
|
@@ -372,8 +367,6 @@ class KeyParser {
|
|
|
372
367
|
node.selected = value === "true";
|
|
373
368
|
return;
|
|
374
369
|
}
|
|
375
|
-
if (this._options.allowUnknownAttributes)
|
|
376
|
-
return;
|
|
377
370
|
this._assert(false, `Unsupported attribute [${key}]`, errorPos);
|
|
378
371
|
}
|
|
379
372
|
_assert(value, message, valuePos) {
|
|
@@ -387,56 +380,10 @@ class ParserError extends Error {
|
|
|
387
380
|
this.pos = pos;
|
|
388
381
|
}
|
|
389
382
|
}
|
|
390
|
-
function findNewElementRef(yaml, fromSnapshot, toSnapshot) {
|
|
391
|
-
function fillMap(root, map, position) {
|
|
392
|
-
let size = 1;
|
|
393
|
-
let childPosition = position + size;
|
|
394
|
-
for (const child of root.children || []) {
|
|
395
|
-
if (child.kind === "role") {
|
|
396
|
-
size += fillMap(child, map, childPosition);
|
|
397
|
-
childPosition += size;
|
|
398
|
-
} else {
|
|
399
|
-
size++;
|
|
400
|
-
childPosition++;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (!["none", "presentation", "fragment", "iframe", "generic"].includes(root.role) && typeof root.name === "string" && root.name) {
|
|
404
|
-
let byRole = map.get(root.role);
|
|
405
|
-
if (!byRole) {
|
|
406
|
-
byRole = /* @__PURE__ */ new Map();
|
|
407
|
-
map.set(root.role, byRole);
|
|
408
|
-
}
|
|
409
|
-
const existing = byRole.get(root.name);
|
|
410
|
-
const sizeAndPosition = size * 100 - position;
|
|
411
|
-
if (!existing || existing.sizeAndPosition < sizeAndPosition)
|
|
412
|
-
byRole.set(root.name, { node: root, sizeAndPosition });
|
|
413
|
-
}
|
|
414
|
-
return size;
|
|
415
|
-
}
|
|
416
|
-
const fromMap = /* @__PURE__ */ new Map();
|
|
417
|
-
const from = parseAriaSnapshotUnsafe(yaml, fromSnapshot, { allowRef: true, allowUnknownAttributes: true });
|
|
418
|
-
if (from.kind === "role")
|
|
419
|
-
fillMap(from, fromMap, 0);
|
|
420
|
-
const toMap = /* @__PURE__ */ new Map();
|
|
421
|
-
const to = parseAriaSnapshotUnsafe(yaml, toSnapshot, { allowRef: true, allowUnknownAttributes: true });
|
|
422
|
-
if (to.kind === "role")
|
|
423
|
-
fillMap(to, toMap, 0);
|
|
424
|
-
const result = [];
|
|
425
|
-
for (const [role, byRole] of toMap) {
|
|
426
|
-
for (const [name, byName] of byRole) {
|
|
427
|
-
const inFrom = fromMap.get(role)?.get(name);
|
|
428
|
-
if (!inFrom)
|
|
429
|
-
result.push(byName);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
result.sort((a, b) => b.sizeAndPosition - a.sizeAndPosition);
|
|
433
|
-
return result.find((r) => r.node.ref)?.node.ref;
|
|
434
|
-
}
|
|
435
383
|
// Annotate the CommonJS export names for ESM import in node:
|
|
436
384
|
0 && (module.exports = {
|
|
437
385
|
KeyParser,
|
|
438
386
|
ParserError,
|
|
439
|
-
findNewElementRef,
|
|
440
387
|
parseAriaSnapshot,
|
|
441
388
|
parseAriaSnapshotUnsafe,
|
|
442
389
|
valueOrRegex
|