authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-06-15 17:10:28-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-16 00:10:28+00:00
logd0a7d18cdbbb4ebbabf4bebe884e9835feb675a6
tree1188829cc5509a22044e224db155659aea05e405
parent71ea5fa1abcd7a3156a5fe003596b724b9fdc68b
signature Signed by PGP key B5690EEEBB952194

[codex] Fix first browser annotation capture (#3095)

Co-authored-by: Julius Marminge <julius0216@outlook.com> Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 57 insertions(+), 1 deletions(-)

apps/desktop/src/preview/Manager.test.ts+49
......@@ -189,6 +189,55 @@ describe("PreviewManager", () => {
189189 ),
190190 );
191191
192 effectIt.effect("keeps element picking active during subframe navigation", () =>
193 withManager((manager) =>
194 Effect.gen(function* () {
195 const listeners = new Map<string, (...args: unknown[]) => void>();
196 fromId.mockReturnValue({
197 id: 42,
198 isDestroyed: () => false,
199 getType: () => "webview",
200 getURL: () => "https://example.com",
201 getTitle: () => "Example",
202 isLoading: () => false,
203 isFocused: () => true,
204 getZoomFactor: () => 1,
205 setZoomFactor: vi.fn(),
206 on: vi.fn((event: string, listener: (...args: unknown[]) => void) => {
207 listeners.set(event, listener);
208 }),
209 once: vi.fn((event: string, listener: (...args: unknown[]) => void) => {
210 listeners.set(event, listener);
211 }),
212 off: vi.fn(),
213 ipc: { on: vi.fn(), off: vi.fn(), removeListener: vi.fn() },
214 send: webviewSend,
215 navigationHistory: { canGoBack: () => false, canGoForward: () => false },
216 setWindowOpenHandler: vi.fn(),
217 debugger: {
218 isAttached: () => false,
219 attach: vi.fn(),
220 sendCommand: vi.fn(async () => undefined),
221 on: vi.fn(),
222 off: vi.fn(),
223 },
224 } as never);
225
226 yield* manager.createTab("tab_1");
227 yield* manager.registerWebview("tab_1", 42);
228 const pick = yield* manager.pickElement("tab_1").pipe(Effect.forkChild);
229 yield* Effect.yieldNow;
230
231 listeners.get("did-start-navigation")?.({}, "about:blank", false, false);
232 yield* Effect.yieldNow;
233 expect(pick.pollUnsafe()).toBeUndefined();
234
235 listeners.get("did-start-navigation")?.({}, "https://example.com/next", false, true);
236 expect(yield* Fiber.join(pick)).toBeNull();
237 }),
238 ),
239 );
240
192241 effectIt.effect("reveals only files inside the configured browser artifact directory", () =>
193242 withManager((manager) =>
194243 Effect.gen(function* () {
apps/desktop/src/preview/Manager.ts+8-1
......@@ -1344,7 +1344,14 @@ const makeNativeOperations = Effect.fn("PreviewManager.makeOperations")(function
13441344 );
13451345 };
13461346 const onDestroyed = () => settle(null);
1347 const onNavigated = () => settle(null);
1347 const onNavigated = (
1348 _event: Electron.Event,
1349 _url: string,
1350 _isInPlace: boolean,
1351 isMainFrame: boolean,
1352 ) => {
1353 if (isMainFrame) settle(null);
1354 };
13481355 const registerPickElement = Effect.fn("PreviewManager.registerPickElement")(function* () {
13491356 yield* attempt("pickElement.register", () => {
13501357 wc.ipc.on(ELEMENT_PICKED_CHANNEL, onMessage);