chore(bidi): support geolocation emulation (#35624)

This commit is contained in:
Yury Semikhatsky 2025-04-15 14:02:32 -07:00 committed by GitHub
parent 09529e9275
commit 224667e9ff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 102 additions and 4 deletions

View File

@ -16,7 +16,7 @@
import { eventsHelper } from '../utils/eventsHelper';
import { Browser } from '../browser';
import { BrowserContext, assertBrowserContextIsNotOwned } from '../browserContext';
import { BrowserContext, assertBrowserContextIsNotOwned, verifyGeolocation } from '../browserContext';
import * as network from '../network';
import { BidiConnection } from './bidiConnection';
import { bidiBytesValueToString } from './bidiNetworkManager';
@ -230,6 +230,8 @@ export class BidiBrowserContext extends BrowserContext {
userContexts: [this._userContextId()],
}));
}
if (this._options.geolocation)
promises.push(this.setGeolocation(this._options.geolocation));
await Promise.all(promises);
}
@ -312,6 +314,31 @@ export class BidiBrowserContext extends BrowserContext {
}
async setGeolocation(geolocation?: types.Geolocation): Promise<void> {
verifyGeolocation(geolocation);
this._options.geolocation = geolocation;
const promises: Promise<unknown>[] = [
this._browser._browserSession.send('emulation.setGeolocationOverride', {
coordinates: {
latitude: geolocation?.latitude,
longitude: geolocation?.longitude,
accuracy: geolocation?.accuracy,
},
userContexts: [this._browserContextId || 'default'],
}),
];
const pageIds = this.pages().map(page => (page._delegate as BidiPage)._session.sessionId);
if (pageIds.length) {
// TODO: we can't specify userContexts and contexts at the same time in Firefox.
promises.push(this._browser._browserSession.send('emulation.setGeolocationOverride', {
coordinates: {
latitude: geolocation?.latitude,
longitude: geolocation?.longitude,
accuracy: geolocation?.accuracy,
},
contexts: pageIds as [string, ...string[]],
}));
}
await Promise.all(promises);
}
async setExtraHTTPHeaders(headers: types.HeadersArray): Promise<void> {

View File

@ -113,6 +113,11 @@ export interface Commands {
returnType: Bidi.EmptyResult;
};
'emulation.setGeolocationOverride': {
params: Bidi.Emulation.SetGeolocationOverrideParameters;
returnType: Bidi.EmptyResult;
};
'session.end': {
params: Bidi.EmptyParams;
returnType: Bidi.EmptyResult;

View File

@ -35,6 +35,7 @@ export type EventData =
export type CommandData =
| BrowserCommand
| BrowsingContextCommand
| EmulationCommand
| InputCommand
| NetworkCommand
| ScriptCommand
@ -492,13 +493,16 @@ export namespace BrowsingContext {
export type Navigation = string;
}
export namespace BrowsingContext {
export type NavigationInfo = {
export type BaseNavigationInfo = {
context: BrowsingContext.BrowsingContext;
navigation: BrowsingContext.Navigation | null;
timestamp: JsUint;
url: string;
};
}
export namespace BrowsingContext {
export type NavigationInfo = BrowsingContext.BaseNavigationInfo;
}
export namespace BrowsingContext {
export const enum ReadinessState {
None = 'none',
@ -874,9 +878,14 @@ export namespace BrowsingContext {
export namespace BrowsingContext {
export type DownloadWillBegin = {
method: 'browsingContext.downloadWillBegin';
params: BrowsingContext.NavigationInfo;
params: BrowsingContext.DownloadWillBeginParams;
};
}
export namespace BrowsingContext {
export type DownloadWillBeginParams = {
suggestedFilename: string;
} & BrowsingContext.BaseNavigationInfo;
}
export namespace BrowsingContext {
export type NavigationAborted = {
method: 'browsingContext.navigationAborted';
@ -924,6 +933,63 @@ export namespace BrowsingContext {
defaultValue?: string;
};
}
export type EmulationCommand = Emulation.SetGeolocationOverride;
export namespace Emulation {
export type SetGeolocationOverride = {
method: 'emulation.setGeolocationOverride';
params: Emulation.SetGeolocationOverrideParameters;
};
}
export namespace Emulation {
export type SetGeolocationOverrideParameters = {
coordinates: Emulation.GeolocationCoordinates | null;
contexts?: [
BrowsingContext.BrowsingContext,
...BrowsingContext.BrowsingContext[],
];
userContexts?: [Browser.UserContext, ...Browser.UserContext[]];
};
}
export namespace Emulation {
export type GeolocationCoordinates = {
/**
* Must be between `-90` and `90`, inclusive.
*/
latitude: number;
/**
* Must be between `-180` and `180`, inclusive.
*/
longitude: number;
/**
* Must be greater than or equal to `0`.
*
* @defaultValue `1`
*/
accuracy?: number;
/**
* @defaultValue `null`
*/
altitude?: number | null;
/**
* Must be greater than or equal to `0`.
*
* @defaultValue `null`
*/
altitudeAccuracy?: number | null;
/**
* Must be between `0` and `360`.
*
* @defaultValue `null`
*/
heading?: number | null;
/**
* Must be greater than or equal to `0`.
*
* @defaultValue `null`
*/
speed?: number | null;
};
}
export type NetworkCommand =
| Network.AddIntercept
| Network.ContinueRequest

View File

@ -703,7 +703,7 @@ export function validateBrowserContextOptions(options: types.BrowserContextOptio
verifyGeolocation(options.geolocation);
}
export function verifyGeolocation(geolocation?: types.Geolocation) {
export function verifyGeolocation(geolocation?: types.Geolocation): asserts geolocation is types.Geolocation {
if (!geolocation)
return;
geolocation.accuracy = geolocation.accuracy || 0;