@roxybrowser/playwright 2.0.2-beta.8 → 2.0.2-beta.9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../../src/protocol/cdp/backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA+D9D,OAAO,KAAK,EAIV,qBAAqB,EASrB,aAAa,EAad,MAAM,wBAAwB,CAAC;AAShC,OAAO,KAAK,EAEV,sBAAsB,EACtB,6BAA6B,EAE7B,sBAAsB,EAMvB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAw6B/D,qBAAa,wBAAyB,YAAW,6BAA6B;IAC5E,MAAM,CAAC,OAAO,EAAE,qBAAqB,GAAG,sBAAsB;CAG/D;AAED,qBAAa,iBAAkB,YAAW,sBAAsB;IAMlD,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,QAAQ,CAAC,QAAQ,EAAG,KAAK,CAAU;IACnC,QAAQ,CAAC,YAAY,uBAAoB;IAEzC,OAAO,CAAC,KAAK,CAA8B;gBAEd,OAAO,EAAE,qBAAqB;IAErD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBxB,OAAO,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAQ1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAc7B;AA2mRD,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,YAAY,EACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAqEjB;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAarF;AAyBD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,gBAAgB,CAAC,EAC1D,QAAQ,SAAoB,EAC5B,YAAY,oBAAa,GACxB,MAAM,EAAE,CAUV;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAAC,EACjD,WAAW,EAAE,MAAM,GAClB,MAAM,EAAE,CAeV;AA0BD,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOzC"}
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../../src/protocol/cdp/backend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA+D9D,OAAO,KAAK,EAIV,qBAAqB,EASrB,aAAa,EAad,MAAM,wBAAwB,CAAC;AAShC,OAAO,KAAK,EAEV,sBAAsB,EACtB,6BAA6B,EAE7B,sBAAsB,EAMvB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AA46B/D,qBAAa,wBAAyB,YAAW,6BAA6B;IAC5E,MAAM,CAAC,OAAO,EAAE,qBAAqB,GAAG,sBAAsB;CAG/D;AAED,qBAAa,iBAAkB,YAAW,sBAAsB;IAMlD,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,QAAQ,CAAC,QAAQ,EAAG,KAAK,CAAU;IACnC,QAAQ,CAAC,YAAY,uBAAoB;IAEzC,OAAO,CAAC,KAAK,CAA8B;gBAEd,OAAO,EAAE,qBAAqB;IAErD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBxB,OAAO,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAQ1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAc7B;AAupRD,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,YAAY,EACxB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAqEjB;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAarF;AAyBD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,gBAAgB,CAAC,EAC1D,QAAQ,SAAoB,EAC5B,YAAY,oBAAa,GACxB,MAAM,EAAE,CAUV;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAAC,EACjD,WAAW,EAAE,MAAM,GAClB,MAAM,EAAE,CAeV;AA0BD,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOzC"}
@@ -544,7 +544,8 @@ export class CdpBrowserAdapter {
544
544
  this.state = {
545
545
  browserClient,
546
546
  version,
547
- connection
547
+ connection,
548
+ isolatedBrowserContextIds: new Set()
548
549
  };
549
550
  }
550
551
  async browser() {
@@ -580,6 +581,9 @@ class CdpBrowserSession {
580
581
  return new CdpBrowserContextAdapter(this.state, undefined, options);
581
582
  }
582
583
  const response = await this.state.browserClient.Target.createBrowserContext({});
584
+ // Track the new isolated context so the default context adapter (reuseDefaultUserContext)
585
+ // can distinguish default-context targets from explicitly isolated ones.
586
+ this.state.isolatedBrowserContextIds.add(response.browserContextId);
583
587
  return new CdpBrowserContextAdapter(this.state, response.browserContextId, options);
584
588
  }
585
589
  async close() { }
@@ -793,6 +797,9 @@ class CdpBrowserContextAdapter {
793
797
  throw error;
794
798
  }
795
799
  }
800
+ // Remove from the shared set so the default context adapter stops
801
+ // excluding targets that belonged to this now-disposed context.
802
+ this.state.isolatedBrowserContextIds.delete(this.browserContextId);
796
803
  }
797
804
  await Promise.allSettled(pendingPages);
798
805
  this.pendingPages.clear();
@@ -831,26 +838,26 @@ class CdpBrowserContextAdapter {
831
838
  waitForDebuggerOnStart: !this.options.reuseDefaultUserContext,
832
839
  flatten: true
833
840
  }).catch(() => { });
834
- // Bug fix: await the initial page-initialization promises that were fired
835
- // synchronously when attachedToTarget events arrived during setAutoAttach.
836
- //
837
- // Node.js CDP clients deliver attachedToTarget events in the same message
838
- // queue as the setAutoAttach response, so by the time setAutoAttach resolves
839
- // all event handlers have already run and pendingPages is fully populated —
840
- // but the individual page setup (Page.enable, Runtime.enable, init scripts…)
841
- // is still in flight. Awaiting here ensures those complete before
842
- // targetDiscoveryReady resolves, so callers who await ready() see pages[]
843
- // populated immediately rather than an empty list.
841
+ // Await pages that were attached synchronously via setAutoAttach events.
842
+ // In practice Chrome does NOT fire attachedToTarget for pre-existing page
843
+ // targets from the browser session, so this batch is usually empty — but
844
+ // it's still needed for targets attached via other mechanisms (workers, etc.).
844
845
  const initialPagePromises = Array.from(this.pendingPages.values());
845
846
  await Promise.allSettled(initialPagePromises);
846
847
  await this.state.browserClient.Target.getTargetInfo?.().catch(() => { });
847
848
  await this.state.browserClient.Target.setDiscoverTargets?.({
848
849
  discover: true
849
850
  });
851
+ // Explicitly discover and attach to any pre-existing page targets that
852
+ // setAutoAttach did not fire attachedToTarget for (Chrome's browser-level
853
+ // setAutoAttach only triggers attachedToTarget for new targets, not for
854
+ // tabs that were already open before our session connected).
855
+ // This is the primary mechanism that populates context.pages() after
856
+ // connectOverCDP — without it, pages() is always empty on connect.
857
+ await this.discoverTargets();
850
858
  this.targetPollTimer = setInterval(() => {
851
859
  void this.discoverTargets().catch(() => { });
852
860
  }, 100);
853
- await this.discoverTargets();
854
861
  }
855
862
  async handleTargetAttached(event) {
856
863
  const { targetInfo } = event;
@@ -916,6 +923,24 @@ class CdpBrowserContextAdapter {
916
923
  if (this.closing || !this.matchesTargetInfo(targetInfo)) {
917
924
  return;
918
925
  }
926
+ // Skip targets that are already known (attached via setAutoAttach or a prior
927
+ // discoverTargets call).
928
+ if (this.pages.has(targetInfo.targetId) || this.pendingPages.has(targetInfo.targetId)) {
929
+ return;
930
+ }
931
+ // Chrome's browser-level setAutoAttach does not fire attachedToTarget for
932
+ // page targets that were already open before our session connected. Attach
933
+ // to them explicitly so we can create Page objects for them.
934
+ let sessionId;
935
+ try {
936
+ const result = await this.state.browserClient.Target.attachToTarget({ targetId: targetInfo.targetId, flatten: true });
937
+ sessionId = result.sessionId;
938
+ }
939
+ catch {
940
+ // Target may have already been attached or closed — skip it.
941
+ return;
942
+ }
943
+ await this.handleTargetAttached({ sessionId, targetInfo, waitingForDebugger: false });
919
944
  }
920
945
  async handleTargetDetached(targetId, sessionId) {
921
946
  const attachedSessionId = this.pageSessionIds.get(targetId);
@@ -948,13 +973,28 @@ class CdpBrowserContextAdapter {
948
973
  if (targetInfo.openerId && this.pendingPages.has(targetInfo.openerId)) {
949
974
  return true;
950
975
  }
951
- return !this.browserContextId && !targetInfo.browserContextId;
976
+ // When we represent the default browser context (no browserContextId), match
977
+ // all page targets that do NOT belong to a known isolated context.
978
+ //
979
+ // Chrome 119+ assigns a non-empty UUID to ALL targets — including those in the
980
+ // default context — so the old check `!targetInfo.browserContextId` incorrectly
981
+ // excluded every tab that had been given a default-context UUID, making
982
+ // context.pages() always empty after connectOverCDP.
983
+ //
984
+ // Isolated contexts are tracked in state.isolatedBrowserContextIds (populated
985
+ // in CdpBrowserSession.newContext when Target.createBrowserContext is called).
986
+ // Any target NOT in that set belongs to the default context.
987
+ return !this.browserContextId &&
988
+ !this.state.isolatedBrowserContextIds.has(targetInfo.browserContextId ?? "");
952
989
  }
953
990
  matchesBrowserContextTarget(targetInfo) {
954
991
  if (targetInfo.browserContextId === this.browserContextId) {
955
992
  return true;
956
993
  }
957
- return !this.browserContextId && !targetInfo.browserContextId;
994
+ // Same reasoning as matchesTargetInfo: default context adapter accepts all
995
+ // non-isolated targets regardless of whether browserContextId is a UUID.
996
+ return !this.browserContextId &&
997
+ !this.state.isolatedBrowserContextIds.has(targetInfo.browserContextId ?? "");
958
998
  }
959
999
  async getOrCreatePage(targetId, options = {}) {
960
1000
  const existing = this.pages.get(targetId);