playwright-core 1.55.0-alpha-2025-07-29 → 1.55.0-alpha-2025-07-30

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.
Files changed (37) hide show
  1. package/lib/generated/injectedScriptSource.js +1 -1
  2. package/lib/generated/pollingRecorderSource.js +1 -1
  3. package/lib/protocol/validator.js +0 -16
  4. package/lib/server/android/android.js +54 -43
  5. package/lib/server/bidi/bidiPage.js +4 -0
  6. package/lib/server/browser.js +22 -18
  7. package/lib/server/browserContext.js +73 -46
  8. package/lib/server/browserType.js +67 -48
  9. package/lib/server/chromium/chromium.js +34 -28
  10. package/lib/server/chromium/crCoverage.js +3 -4
  11. package/lib/server/chromium/videoRecorder.js +10 -19
  12. package/lib/server/codegen/jsonl.js +2 -1
  13. package/lib/server/debugController.js +2 -18
  14. package/lib/server/dispatchers/debugControllerDispatcher.js +0 -9
  15. package/lib/server/dispatchers/localUtilsDispatcher.js +0 -5
  16. package/lib/server/frames.js +6 -6
  17. package/lib/server/localUtils.js +12 -7
  18. package/lib/server/playwright.js +0 -4
  19. package/lib/server/progress.js +17 -11
  20. package/lib/server/recorder/recorderUtils.js +5 -0
  21. package/lib/server/recorder.js +61 -1
  22. package/lib/server/socksClientCertificatesInterceptor.js +21 -6
  23. package/lib/server/utils/processLauncher.js +4 -1
  24. package/lib/utils/isomorphic/ariaSnapshot.js +58 -4
  25. package/lib/utils/isomorphic/protocolMetainfo.js +1 -5
  26. package/lib/utils/isomorphic/urlMatch.js +0 -2
  27. package/lib/vite/htmlReport/index.html +16 -16
  28. package/lib/vite/recorder/assets/{codeMirrorModule-cgtwtYOb.js → codeMirrorModule-BAFWw0fz.js} +1 -1
  29. package/lib/vite/recorder/assets/{index-KWWSfrzB.js → index-DyMqECqY.js} +28 -28
  30. package/lib/vite/recorder/index.html +1 -1
  31. package/lib/vite/traceViewer/assets/{codeMirrorModule-k_7BpzGX.js → codeMirrorModule-BOjqK4ng.js} +1 -1
  32. package/lib/vite/traceViewer/assets/{defaultSettingsView-CKM53V_K.js → defaultSettingsView-B-LNxb2i.js} +103 -103
  33. package/lib/vite/traceViewer/{index.CCXGYfh2.js → index.CWlPEVCA.js} +1 -1
  34. package/lib/vite/traceViewer/index.html +2 -2
  35. package/lib/vite/traceViewer/{uiMode.CNa3x5Xj.js → uiMode.NUAVc1od.js} +1 -1
  36. package/lib/vite/traceViewer/uiMode.html +2 -2
  37. package/package.json +1 -1
@@ -618,7 +618,7 @@ class Frame extends import_instrumentation.SdkObject {
618
618
  return null;
619
619
  return continuePolling;
620
620
  }
621
- const result = await progress.raceWithCleanup(resolved.injected.evaluateHandle((injected, { info, root }) => {
621
+ const result = await progress.race(resolved.injected.evaluateHandle((injected, { info, root }) => {
622
622
  if (root && !root.isConnected)
623
623
  throw injected.createStacklessError("Element is not attached to the DOM");
624
624
  const elements = injected.querySelectorAll(info.parsed, root || document);
@@ -633,7 +633,7 @@ class Frame extends import_instrumentation.SdkObject {
633
633
  log2 = ` locator resolved to ${visible2 ? "visible" : "hidden"} ${injected.previewNode(element2)}`;
634
634
  }
635
635
  return { log: log2, element: element2, visible: visible2, attached: !!element2 };
636
- }, { info: resolved.info, root: resolved.frame === this ? scope : void 0 }), (handle) => handle.dispose());
636
+ }, { info: resolved.info, root: resolved.frame === this ? scope : void 0 }));
637
637
  const { log, visible, attached } = await progress.race(result.evaluate((r) => ({ log: r.log, visible: r.visible, attached: r.attached })));
638
638
  if (log)
639
639
  progress.log(log);
@@ -898,7 +898,7 @@ class Frame extends import_instrumentation.SdkObject {
898
898
  const resolved = await progress.race(this.selectors.resolveInjectedForSelector(selector, { strict }));
899
899
  if (!resolved)
900
900
  return continuePolling;
901
- const result = await progress.raceWithCleanup(resolved.injected.evaluateHandle((injected, { info, callId }) => {
901
+ const result = await progress.race(resolved.injected.evaluateHandle((injected, { info, callId }) => {
902
902
  const elements = injected.querySelectorAll(info.parsed, document);
903
903
  if (callId)
904
904
  injected.markTargetElements(new Set(elements), callId);
@@ -912,7 +912,7 @@ class Frame extends import_instrumentation.SdkObject {
912
912
  log2 = ` locator resolved to ${injected.previewNode(element2)}`;
913
913
  }
914
914
  return { log: log2, success: !!element2, element: element2 };
915
- }, { info: resolved.info, callId: progress.metadata.id }), (handle) => handle.dispose());
915
+ }, { info: resolved.info, callId: progress.metadata.id }));
916
916
  const { log, success } = await progress.race(result.evaluate((r) => ({ log: r.log, success: r.success })));
917
917
  if (log)
918
918
  progress.log(log);
@@ -982,8 +982,8 @@ class Frame extends import_instrumentation.SdkObject {
982
982
  async blur(progress, selector, options) {
983
983
  dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, true, (handle) => handle._blur(progress)));
984
984
  }
985
- async resolveSelector(progress, selector) {
986
- const element = await progress.race(this.selectors.query(selector));
985
+ async resolveSelector(progress, selector, options = {}) {
986
+ const element = await progress.race(this.selectors.query(selector, options));
987
987
  if (!element)
988
988
  throw new Error(`No element matching ${selector}`);
989
989
  const generated = await progress.race(element.evaluateInUtility(async ([injected, node]) => {
@@ -135,13 +135,18 @@ async function harOpen(progress, harBackends, params) {
135
135
  let harBackend;
136
136
  if (params.file.endsWith(".zip")) {
137
137
  const zipFile = new import_zipFile.ZipFile(params.file);
138
- const entryNames = await zipFile.entries();
139
- const harEntryName = entryNames.find((e) => e.endsWith(".har"));
140
- if (!harEntryName)
141
- return { error: "Specified archive does not have a .har file" };
142
- const har = await progress.raceWithCleanup(zipFile.read(harEntryName), () => zipFile.close());
143
- const harFile = JSON.parse(har.toString());
144
- harBackend = new import_harBackend.HarBackend(harFile, null, zipFile);
138
+ try {
139
+ const entryNames = await progress.race(zipFile.entries());
140
+ const harEntryName = entryNames.find((e) => e.endsWith(".har"));
141
+ if (!harEntryName)
142
+ return { error: "Specified archive does not have a .har file" };
143
+ const har = await progress.race(zipFile.read(harEntryName));
144
+ const harFile = JSON.parse(har.toString());
145
+ harBackend = new import_harBackend.HarBackend(harFile, null, zipFile);
146
+ } catch (error) {
147
+ zipFile.close();
148
+ throw error;
149
+ }
145
150
  } else {
146
151
  const harFile = JSON.parse(await progress.race(import_fs.default.promises.readFile(params.file, "utf-8")));
147
152
  harBackend = new import_harBackend.HarBackend(harFile, import_path.default.dirname(params.file), null);
@@ -58,10 +58,6 @@ class Playwright extends import_instrumentation.SdkObject {
58
58
  this.android = new import_android.Android(this, new import_backendAdb.AdbBackend());
59
59
  this.debugController = new import_debugController.DebugController(this);
60
60
  }
61
- async hideHighlight() {
62
- await Promise.all([...this._allPages].map((p) => p.hideHighlight().catch(() => {
63
- })));
64
- }
65
61
  allBrowsers() {
66
62
  return [...this._allBrowsers];
67
63
  }
@@ -19,7 +19,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var progress_exports = {};
20
20
  __export(progress_exports, {
21
21
  ProgressController: () => ProgressController,
22
- isAbortError: () => isAbortError
22
+ isAbortError: () => isAbortError,
23
+ raceUncancellableOperationWithCleanup: () => raceUncancellableOperationWithCleanup
23
24
  });
24
25
  module.exports = __toCommonJS(progress_exports);
25
26
  var import_errors = require("./errors");
@@ -67,15 +68,6 @@ class ProgressController {
67
68
  const promises = Array.isArray(promise) ? promise : [promise];
68
69
  return Promise.race([...promises, this._forceAbortPromise]);
69
70
  },
70
- raceWithCleanup: (promise, cleanup) => {
71
- return progress.race(promise.then((result) => {
72
- if (this._state !== "running")
73
- cleanup(result);
74
- else
75
- this._cleanups.push(() => cleanup(result));
76
- return result;
77
- }));
78
- },
79
71
  wait: async (timeout2) => {
80
72
  let timer2;
81
73
  const promise = new Promise((f) => timer2 = setTimeout(f, timeout2));
@@ -117,8 +109,22 @@ const kAbortErrorSymbol = Symbol("kAbortError");
117
109
  function isAbortError(error) {
118
110
  return !!error[kAbortErrorSymbol];
119
111
  }
112
+ async function raceUncancellableOperationWithCleanup(progress, run, cleanup) {
113
+ let aborted = false;
114
+ try {
115
+ return await progress.race(run().then(async (t) => {
116
+ if (aborted)
117
+ await cleanup(t);
118
+ return t;
119
+ }));
120
+ } catch (error) {
121
+ aborted = true;
122
+ throw error;
123
+ }
124
+ }
120
125
  // Annotate the CommonJS export names for ESM import in node:
121
126
  0 && (module.exports = {
122
127
  ProgressController,
123
- isAbortError
128
+ isAbortError,
129
+ raceUncancellableOperationWithCleanup
124
130
  });
@@ -22,6 +22,7 @@ __export(recorderUtils_exports, {
22
22
  collapseActions: () => collapseActions,
23
23
  frameForAction: () => frameForAction,
24
24
  generateFrameSelector: () => generateFrameSelector,
25
+ isAssertAction: () => isAssertAction,
25
26
  mainFrameForAction: () => mainFrameForAction,
26
27
  metadataToCallLog: () => metadataToCallLog,
27
28
  shouldMergeAction: () => shouldMergeAction
@@ -75,6 +76,9 @@ async function frameForAction(pageAliases, actionInContext, action) {
75
76
  throw new Error("Internal error: frame not found");
76
77
  return result.frame;
77
78
  }
79
+ function isAssertAction(action) {
80
+ return action.name.startsWith("assert");
81
+ }
78
82
  function isSameAction(a, b) {
79
83
  return a.action.name === b.action.name && a.frame.pageAlias === b.frame.pageAlias && a.frame.framePath.join("|") === b.frame.framePath.join("|");
80
84
  }
@@ -151,6 +155,7 @@ async function generateFrameSelectorInParent(parent, frame) {
151
155
  collapseActions,
152
156
  frameForAction,
153
157
  generateFrameSelector,
158
+ isAssertAction,
154
159
  mainFrameForAction,
155
160
  metadataToCallLog,
156
161
  shouldMergeAction
@@ -48,6 +48,8 @@ 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");
51
53
  const recorderSymbol = Symbol("recorderSymbol");
52
54
  const RecorderEvent = {
53
55
  PausedStateChanged: "pausedStateChanged",
@@ -440,15 +442,66 @@ class Recorder extends import_events.default {
440
442
  };
441
443
  return actionInContext;
442
444
  }
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
+ }
443
490
  async _performAction(frame, action) {
444
491
  const actionInContext = await this._createActionInContext(frame, action);
492
+ const assertActionInContext = await this._maybeGenerateAssertAction(frame, actionInContext);
493
+ if (assertActionInContext)
494
+ this._signalProcessor.addAction(assertActionInContext);
445
495
  this._signalProcessor.addAction(actionInContext);
496
+ setLastFrameAction(frame, actionInContext);
446
497
  if (actionInContext.action.name !== "openPage" && actionInContext.action.name !== "closePage")
447
498
  await (0, import_recorderRunner.performAction)(this._pageAliases, actionInContext);
448
499
  actionInContext.endTime = (0, import_utils2.monotonicTime)();
449
500
  }
450
501
  async _recordAction(frame, action) {
451
- this._signalProcessor.addAction(await this._createActionInContext(frame, action));
502
+ const actionInContext = await this._createActionInContext(frame, action);
503
+ this._signalProcessor.addAction(actionInContext);
504
+ setLastFrameAction(frame, actionInContext);
452
505
  }
453
506
  _onFrameNavigated(frame, page) {
454
507
  const pageAlias = this._pageAliases.get(page);
@@ -482,6 +535,13 @@ function languageForFile(file) {
482
535
  return "csharp";
483
536
  return "javascript";
484
537
  }
538
+ const kLastFrameActionSymbol = Symbol("lastFrameAction");
539
+ function getLastFrameAction(frame) {
540
+ return frame[kLastFrameActionSymbol];
541
+ }
542
+ function setLastFrameAction(frame, action) {
543
+ frame[kLastFrameActionSymbol] = action;
544
+ }
485
545
  // Annotate the CommonJS export names for ESM import in node:
486
546
  0 && (module.exports = {
487
547
  Recorder,
@@ -44,6 +44,7 @@ var import_browserContext = require("./browserContext");
44
44
  var import_network = require("./utils/network");
45
45
  var import_debugLogger = require("./utils/debugLogger");
46
46
  var import_happyEyeballs = require("./utils/happyEyeballs");
47
+ var import_utilsBundle = require("../utilsBundle");
47
48
  let dummyServerTlsOptions = void 0;
48
49
  function loadDummyServerCertsIfNeeded() {
49
50
  if (dummyServerTlsOptions)
@@ -97,8 +98,9 @@ class SocksProxyConnection {
97
98
  };
98
99
  }
99
100
  async connect() {
100
- if (this.socksProxy.proxyAgentFromOptions)
101
- this.target = await this.socksProxy.proxyAgentFromOptions.callback(new import_events.EventEmitter(), { host: rewriteToLocalhostIfNeeded(this.host), port: this.port, secureEndpoint: false });
101
+ const proxyAgent = this.socksProxy.getProxyAgent(this.host, this.port);
102
+ if (proxyAgent)
103
+ this.target = await proxyAgent.callback(new import_events.EventEmitter(), { host: rewriteToLocalhostIfNeeded(this.host), port: this.port, secureEndpoint: false });
102
104
  else
103
105
  this.target = await (0, import_happyEyeballs.createSocket)(rewriteToLocalhostIfNeeded(this.host), this.port);
104
106
  this.target.once("close", this._targetCloseEventListener);
@@ -222,7 +224,7 @@ class ClientCertificatesProxy {
222
224
  (0, import_browserContext.verifyClientCertificates)(contextOptions.clientCertificates);
223
225
  this.alpnCache = new ALPNCache();
224
226
  this.ignoreHTTPSErrors = contextOptions.ignoreHTTPSErrors;
225
- this.proxyAgentFromOptions = (0, import_network.createProxyAgent)(contextOptions.proxy);
227
+ this._proxy = contextOptions.proxy;
226
228
  this._initSecureContexts(contextOptions.clientCertificates);
227
229
  this._socksProxy = new import_socksProxy.SocksProxy();
228
230
  this._socksProxy.setPattern("*");
@@ -245,6 +247,14 @@ class ClientCertificatesProxy {
245
247
  });
246
248
  loadDummyServerCertsIfNeeded();
247
249
  }
250
+ getProxyAgent(host, port) {
251
+ const proxyFromOptions = (0, import_network.createProxyAgent)(this._proxy);
252
+ if (proxyFromOptions)
253
+ return proxyFromOptions;
254
+ const proxyFromEnv = (0, import_utilsBundle.getProxyForUrl)(`https://${host}:${port}`);
255
+ if (proxyFromEnv)
256
+ return (0, import_network.createProxyAgent)({ server: proxyFromEnv });
257
+ }
248
258
  _initSecureContexts(clientCertificates) {
249
259
  const origin2certs = /* @__PURE__ */ new Map();
250
260
  for (const cert of clientCertificates || []) {
@@ -262,10 +272,15 @@ class ClientCertificatesProxy {
262
272
  }
263
273
  }
264
274
  }
265
- static async create(contextOptions) {
275
+ static async create(progress, contextOptions) {
266
276
  const proxy = new ClientCertificatesProxy(contextOptions);
267
- await proxy._socksProxy.listen(0, "127.0.0.1");
268
- return proxy;
277
+ try {
278
+ await progress.race(proxy._socksProxy.listen(0, "127.0.0.1"));
279
+ return proxy;
280
+ } catch (error) {
281
+ await proxy.close();
282
+ throw error;
283
+ }
269
284
  }
270
285
  proxySettings() {
271
286
  return { server: `socks5://127.0.0.1:${this._socksProxy.port()}` };
@@ -132,7 +132,10 @@ async function launchProcess(options) {
132
132
  spawnedProcess.once("error", (error) => {
133
133
  failed(new Error("Failed to launch: " + error));
134
134
  });
135
- return failedPromise.then((e) => Promise.reject(e));
135
+ return failedPromise.then(async (error) => {
136
+ await cleanup();
137
+ throw error;
138
+ });
136
139
  }
137
140
  options.log(`<launched> pid=${spawnedProcess.pid}`);
138
141
  const stdout = readline.createInterface({ input: spawnedProcess.stdout });
@@ -20,13 +20,14 @@ var ariaSnapshot_exports = {};
20
20
  __export(ariaSnapshot_exports, {
21
21
  KeyParser: () => KeyParser,
22
22
  ParserError: () => ParserError,
23
+ findNewElementRef: () => findNewElementRef,
23
24
  parseAriaSnapshot: () => parseAriaSnapshot,
24
25
  parseAriaSnapshotUnsafe: () => parseAriaSnapshotUnsafe,
25
26
  valueOrRegex: () => valueOrRegex
26
27
  });
27
28
  module.exports = __toCommonJS(ariaSnapshot_exports);
28
- function parseAriaSnapshotUnsafe(yaml, text) {
29
- const result = parseAriaSnapshot(yaml, text);
29
+ function parseAriaSnapshotUnsafe(yaml, text, options = {}) {
30
+ const result = parseAriaSnapshot(yaml, text, options);
30
31
  if (result.errors.length)
31
32
  throw new Error(result.errors[0].message);
32
33
  return result.fragment;
@@ -187,7 +188,7 @@ function valueOrRegex(value) {
187
188
  class KeyParser {
188
189
  static parse(text, options, errors) {
189
190
  try {
190
- return new KeyParser(text.value)._parse();
191
+ return new KeyParser(text.value, options)._parse();
191
192
  } catch (e) {
192
193
  if (e instanceof ParserError) {
193
194
  const message = options.prettyErrors === false ? e.message : e.message + ":\n\n" + text.value + "\n" + " ".repeat(e.pos) + "^\n";
@@ -200,10 +201,11 @@ class KeyParser {
200
201
  throw e;
201
202
  }
202
203
  }
203
- constructor(input) {
204
+ constructor(input, options) {
204
205
  this._input = input;
205
206
  this._pos = 0;
206
207
  this._length = input.length;
208
+ this._options = options;
207
209
  }
208
210
  _peek() {
209
211
  return this._input[this._pos] || "";
@@ -331,6 +333,10 @@ class KeyParser {
331
333
  return result;
332
334
  }
333
335
  _applyAttribute(node, key, value, errorPos) {
336
+ if (this._options.allowRef && key === "ref") {
337
+ node.ref = value;
338
+ return;
339
+ }
334
340
  if (key === "checked") {
335
341
  this._assert(value === "true" || value === "false" || value === "mixed", 'Value of "checked" attribute must be a boolean or "mixed"', errorPos);
336
342
  node.checked = value === "true" ? true : value === "false" ? false : "mixed";
@@ -366,6 +372,8 @@ class KeyParser {
366
372
  node.selected = value === "true";
367
373
  return;
368
374
  }
375
+ if (this._options.allowUnknownAttributes)
376
+ return;
369
377
  this._assert(false, `Unsupported attribute [${key}]`, errorPos);
370
378
  }
371
379
  _assert(value, message, valuePos) {
@@ -379,10 +387,56 @@ class ParserError extends Error {
379
387
  this.pos = pos;
380
388
  }
381
389
  }
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
+ }
382
435
  // Annotate the CommonJS export names for ESM import in node:
383
436
  0 && (module.exports = {
384
437
  KeyParser,
385
438
  ParserError,
439
+ findNewElementRef,
386
440
  parseAriaSnapshot,
387
441
  parseAriaSnapshotUnsafe,
388
442
  valueOrRegex
@@ -37,19 +37,15 @@ const methodMetainfo = /* @__PURE__ */ new Map([
37
37
  ["LocalUtils.tracingStarted", { internal: true }],
38
38
  ["LocalUtils.addStackToTracingNoReply", { internal: true }],
39
39
  ["LocalUtils.traceDiscarded", { internal: true }],
40
- ["LocalUtils.globToRegex", { internal: true }],
41
40
  ["Root.initialize", { internal: true }],
42
41
  ["Playwright.newRequest", { title: "Create request context" }],
43
42
  ["DebugController.initialize", { internal: true }],
44
43
  ["DebugController.setReportStateChanged", { internal: true }],
45
- ["DebugController.resetForReuse", { internal: true }],
46
- ["DebugController.navigate", { internal: true }],
47
44
  ["DebugController.setRecorderMode", { internal: true }],
48
45
  ["DebugController.highlight", { internal: true }],
49
46
  ["DebugController.hideHighlight", { internal: true }],
50
47
  ["DebugController.resume", { internal: true }],
51
48
  ["DebugController.kill", { internal: true }],
52
- ["DebugController.closeAllBrowsers", { internal: true }],
53
49
  ["SocksSupport.socksConnected", { internal: true }],
54
50
  ["SocksSupport.socksFailed", { internal: true }],
55
51
  ["SocksSupport.socksData", { internal: true }],
@@ -107,7 +103,7 @@ const methodMetainfo = /* @__PURE__ */ new Map([
107
103
  ["BrowserContext.clockSetFixedTime", { title: 'Set fixed time "{timeNumber}{timeString}"' }],
108
104
  ["BrowserContext.clockSetSystemTime", { title: 'Set system time "{timeNumber}{timeString}"' }],
109
105
  ["Page.addInitScript", {}],
110
- ["Page.close", { title: "Close" }],
106
+ ["Page.close", { title: "Close page" }],
111
107
  ["Page.emulateMedia", { title: "Emulate media", snapshot: true }],
112
108
  ["Page.exposeBinding", { title: "Expose binding" }],
113
109
  ["Page.goBack", { title: "Go back", slowMo: true, snapshot: true }],
@@ -20,7 +20,6 @@ var urlMatch_exports = {};
20
20
  __export(urlMatch_exports, {
21
21
  constructURLBasedOnBaseURL: () => constructURLBasedOnBaseURL,
22
22
  globToRegexPattern: () => globToRegexPattern,
23
- resolveGlobToRegexPattern: () => resolveGlobToRegexPattern,
24
23
  urlMatches: () => urlMatches,
25
24
  urlMatchesEqual: () => urlMatchesEqual
26
25
  });
@@ -162,7 +161,6 @@ function constructURLBasedOnBaseURL(baseURL, givenURL) {
162
161
  0 && (module.exports = {
163
162
  constructURLBasedOnBaseURL,
164
163
  globToRegexPattern,
165
- resolveGlobToRegexPattern,
166
164
  urlMatches,
167
165
  urlMatchesEqual
168
166
  });