Skip to content

Commit bb1bf90

Browse files
csamujuliandescottes
authored andcommitted
refactor: use BiDi navigate for all URLs, not just moz-extension://
Replace isPrivilegedUrl with isCommonScheme (negation check). Navigate always uses BiDi browsingContext.navigate: common schemes (http/https/data/blob/file) get wait:interactive, uncommon schemes (moz-extension:/about:/etc.) get wait:none. sendBiDiCommand is now required. Trim unit tests. Add afterEach reset and tab cleanup to integration tests.
1 parent 9872fbc commit bb1bf90

3 files changed

Lines changed: 199 additions & 196 deletions

File tree

src/firefox/pages.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,51 @@
55
import { WebDriver } from 'selenium-webdriver';
66
import { log, logDebug } from '../utils/logger.js';
77

8-
const PRIVILEGED_URL_SCHEMES = ['moz-extension:'];
8+
const COMMON_URL_SCHEMES = ['http:', 'https:', 'data:', 'blob:', 'file:'];
99

1010
/**
11-
* Check if a URL uses a privileged scheme that requires BiDi navigation.
12-
* @internal Exported for testability only; not a stable public API.
11+
* Check if a URL uses a common scheme that supports load events.
12+
* Non-common schemes = moz-extension:, about:, ...
1313
*/
14-
export function isPrivilegedUrl(url: string): boolean {
14+
export function isCommonScheme(url: string): boolean {
1515
try {
16-
return PRIVILEGED_URL_SCHEMES.includes(new URL(url).protocol);
16+
return COMMON_URL_SCHEMES.includes(new URL(url).protocol);
1717
} catch {
18-
logDebug(`URL parse failed, treating as non-privileged: ${url}`);
1918
return false;
2019
}
2120
}
2221

22+
export type BiDiCommandFn = (method: string, params: Record<string, any>) => Promise<any>;
23+
2324
export class PageManagement {
2425
constructor(
2526
private driver: WebDriver,
2627
private getCurrentContextId: () => string | null,
2728
private setCurrentContextId: (id: string) => void,
28-
private sendBiDiCommand?: (method: string, params: Record<string, any>) => Promise<any>
29+
private sendBiDiCommand: BiDiCommandFn
2930
) {}
3031

3132
/**
32-
* Navigate to URL.
33-
* For moz-extension:// URLs, uses BiDi browsingContext.navigate with
34-
* wait:"none" because geckodriver
35-
* waits for BiDi navigation completion events that the Remote Agent does
36-
* not emit for extension/privileged contexts, causing driver.get() to hang.
33+
* Navigate to URL using BiDi
3734
*/
3835
async navigate(url: string): Promise<void> {
39-
if (isPrivilegedUrl(url) && this.sendBiDiCommand) {
40-
const contextId = this.getCurrentContextId();
41-
if (!contextId) {
42-
throw new Error(`Cannot navigate to privileged URL ${url}: no browsing context ID`);
43-
}
44-
await this.sendBiDiCommand('browsingContext.navigate', {
45-
context: contextId,
46-
url,
47-
wait: 'none',
48-
});
49-
logDebug(`BiDi navigate (wait:none) to: ${url}`);
50-
} else {
51-
await this.driver.get(url);
36+
const contextId = this.getCurrentContextId();
37+
if (!contextId) {
38+
throw new Error(`Cannot navigate: no browsing context ID`);
5239
}
40+
41+
// Default wait time is "interactive" (DOMContentLoaded).
42+
// All uncommon schemes use wait time "none"
43+
const wait = isCommonScheme(url) ? 'interactive' : 'none';
44+
45+
// Navigate using direct BiDi
46+
await this.sendBiDiCommand('browsingContext.navigate', {
47+
context: contextId,
48+
url,
49+
wait,
50+
});
51+
52+
logDebug(`BiDi navigate (wait:${wait}) to: ${url}`);
5353
log(`Navigated to: ${url}`);
5454
}
5555

0 commit comments

Comments
 (0)