fix(browser): keep input blocker active across navigations (#22562)

Co-authored-by: cynthialong0-0 <82900738+cynthialong0-0@users.noreply.github.com>
This commit is contained in:
Aditya Bijalwan
2026-03-26 22:24:49 +05:30
committed by GitHub
parent a3c1c659fd
commit 5755ec2dcf
6 changed files with 163 additions and 31 deletions
@@ -5,7 +5,12 @@
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { injectInputBlocker, removeInputBlocker } from './inputBlocker.js';
import {
injectInputBlocker,
removeInputBlocker,
suspendInputBlocker,
resumeInputBlocker,
} from './inputBlocker.js';
import type { BrowserManager } from './browserManager.js';
describe('inputBlocker', () => {
@@ -28,6 +33,7 @@ describe('inputBlocker', () => {
{
function: expect.stringContaining('__gemini_input_blocker'),
},
undefined,
);
});
@@ -77,6 +83,29 @@ describe('inputBlocker', () => {
injectInputBlocker(mockBrowserManager),
).resolves.toBeUndefined();
});
it('should be safe to call multiple times (idempotent injection)', async () => {
await injectInputBlocker(mockBrowserManager);
await injectInputBlocker(mockBrowserManager);
expect(mockBrowserManager.callTool).toHaveBeenCalledTimes(2);
expect(mockBrowserManager.callTool).toHaveBeenNthCalledWith(
1,
'evaluate_script',
expect.objectContaining({
function: expect.stringContaining('__gemini_input_blocker'),
}),
undefined,
);
expect(mockBrowserManager.callTool).toHaveBeenNthCalledWith(
2,
'evaluate_script',
expect.objectContaining({
function: expect.stringContaining('__gemini_input_blocker'),
}),
undefined,
);
});
});
describe('removeInputBlocker', () => {
@@ -88,6 +117,7 @@ describe('inputBlocker', () => {
{
function: expect.stringContaining('__gemini_input_blocker'),
},
undefined,
);
});
@@ -110,4 +140,38 @@ describe('inputBlocker', () => {
).resolves.toBeUndefined();
});
});
describe('suspendInputBlocker and resumeInputBlocker', () => {
it('should not throw when blocker element is missing', async () => {
// Simulate evaluate_script resolving successfully even if the DOM element is absent.
mockBrowserManager.callTool = vi.fn().mockResolvedValue({
content: [{ type: 'text', text: 'Script ran on page and returned:' }],
});
await expect(
suspendInputBlocker(mockBrowserManager),
).resolves.toBeUndefined();
await expect(
resumeInputBlocker(mockBrowserManager),
).resolves.toBeUndefined();
expect(mockBrowserManager.callTool).toHaveBeenCalledTimes(2);
expect(mockBrowserManager.callTool).toHaveBeenNthCalledWith(
1,
'evaluate_script',
expect.objectContaining({
function: expect.stringContaining('__gemini_input_blocker'),
}),
undefined,
);
expect(mockBrowserManager.callTool).toHaveBeenNthCalledWith(
2,
'evaluate_script',
expect.objectContaining({
function: expect.stringContaining('__gemini_input_blocker'),
}),
undefined,
);
});
});
});