authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-10-07 13:39:14-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-07 20:39:14+00:00
log538329603352173afe3ae9f4586a4f772c0f3a4f
treee23104c579796b0de22525449493e330fa6a8854
parent8a92ebe413dd9e4569724c94e74a1ed54675eff7
signature Signed by PGP key B5690EEEBB952194

fix(desktop): sign-in and captchas work again in desktop browser tabs (#16939)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

2 files changed, 29 insertions(+), 2 deletions(-)

apps/desktop/src/preview/CdpRelay.test.ts+22
...@@ -75,6 +75,28 @@ describe("CDP relay", () => {...@@ -75,6 +75,28 @@ describe("CDP relay", () => {
75 });75 });
76 });76 });
7777
78 it("resumes paused child frames, so cross-site iframes run", async () => {
79 const send = vi.fn(async () => ({}));
80 const relay = createCdpRelayConnection(makeTarget(send), () => {});
81 // The page's own session is already running; only its children wait.
82 relay.receive(
83 JSON.stringify({
84 id: 1,
85 method: "Runtime.runIfWaitingForDebugger",
86 sessionId: "t3-preview-page",
87 }),
88 );
89 relay.receive(
90 JSON.stringify({
91 id: 2,
92 method: "Runtime.runIfWaitingForDebugger",
93 sessionId: "iframe-session",
94 }),
95 );
96 await settle();
97 expect(send.mock.calls).toEqual([["Runtime.runIfWaitingForDebugger", {}, "iframe-session"]]);
98 });
99
78 it("routes tab events to the page session once the page is announced", async () => {100 it("routes tab events to the page session once the page is announced", async () => {
79 const written: Array<Record<string, unknown>> = [];101 const written: Array<Record<string, unknown>> = [];
80 const relay = createCdpRelayConnection(makeTarget(vi.fn()), (raw) =>102 const relay = createCdpRelayConnection(makeTarget(vi.fn()), (raw) =>
apps/desktop/src/preview/CdpRelay.ts+7-2
...@@ -158,9 +158,14 @@ export function createCdpRelayConnection(...@@ -158,9 +158,14 @@ export function createCdpRelayConnection(
158 };158 };
159159
160 const pageCommand = (command: CdpCommand): Promise<unknown> => {160 const pageCommand = (command: CdpCommand): Promise<unknown> => {
161 // The page is already running; nothing waits for a debugger.
162 if (command.method === "Runtime.runIfWaitingForDebugger") return Promise.resolve({});
163 const child = sessions.get(command.sessionId!) === "page" ? undefined : command.sessionId;161 const child = sessions.get(command.sessionId!) === "page" ? undefined : command.sessionId;
162 // The page itself is already running, but its child frames are not:
163 // Playwright auto-attaches with waitForDebuggerOnStart, so Chromium pauses
164 // every new cross-site iframe and worker until this reaches it. Swallowing
165 // it left sign-in checks and captchas, which run in such frames, frozen.
166 if (command.method === "Runtime.runIfWaitingForDebugger" && child === undefined) {
167 return Promise.resolve({});
168 }
164 return target.send(command.method, command.params ?? {}, child);169 return target.send(command.method, command.params ?? {}, child);
165 };170 };
166171