fix(firefox): make interception, locale and geolocation work on browser context level (#1472)

This commit is contained in:
Dmitry Gozman 2020-03-22 08:56:50 -07:00 committed by GitHub
parent 93954fe919
commit 6e8895fa08
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 25 additions and 17 deletions

View file

@ -9,7 +9,7 @@
"main": "index.js", "main": "index.js",
"playwright": { "playwright": {
"chromium_revision": "751710", "chromium_revision": "751710",
"firefox_revision": "1047", "firefox_revision": "1048",
"webkit_revision": "1182" "webkit_revision": "1182"
}, },
"scripts": { "scripts": {

View file

@ -94,6 +94,7 @@ export class FFBrowser extends platform.EventEmitter implements Browser {
bypassCSP: options.bypassCSP, bypassCSP: options.bypassCSP,
javaScriptDisabled: options.javaScriptEnabled === false ? true : undefined, javaScriptDisabled: options.javaScriptEnabled === false ? true : undefined,
viewport, viewport,
locale: options.locale,
removeOnDetach: true removeOnDetach: true
}); });
// TODO: move ignoreHTTPSErrors to browser context level. // TODO: move ignoreHTTPSErrors to browser context level.
@ -174,6 +175,8 @@ export class FFBrowserContext extends BrowserContextBase {
await this.setOffline(this._options.offline); await this.setOffline(this._options.offline);
if (this._options.httpCredentials) if (this._options.httpCredentials)
await this.setHTTPCredentials(this._options.httpCredentials); await this.setHTTPCredentials(this._options.httpCredentials);
if (this._options.geolocation)
await this.setGeolocation(this._options.geolocation);
} }
_ffPages(): FFPage[] { _ffPages(): FFPage[] {
@ -249,8 +252,7 @@ export class FFBrowserContext extends BrowserContextBase {
if (geolocation) if (geolocation)
geolocation = verifyGeolocation(geolocation); geolocation = verifyGeolocation(geolocation);
this._options.geolocation = geolocation || undefined; this._options.geolocation = geolocation || undefined;
for (const page of this.pages()) await this._browser._connection.send('Browser.setGeolocationOverride', { browserContextId: this._browserContextId || undefined, geolocation });
await (page._delegate as FFPage)._setGeolocation(geolocation);
} }
async setExtraHTTPHeaders(headers: network.Headers): Promise<void> { async setExtraHTTPHeaders(headers: network.Headers): Promise<void> {
@ -292,8 +294,8 @@ export class FFBrowserContext extends BrowserContextBase {
async route(url: types.URLMatch, handler: network.RouteHandler): Promise<void> { async route(url: types.URLMatch, handler: network.RouteHandler): Promise<void> {
this._routes.push({ url, handler }); this._routes.push({ url, handler });
throw new Error('Not implemented'); if (this._routes.length === 1)
// TODO: update interception on the context if this is a first route. await this._browser._connection.send('Browser.setRequestInterception', { browserContextId: this._browserContextId || undefined, enabled: true });
} }
async close() { async close() {

View file

@ -86,8 +86,6 @@ export class FFPage implements PageDelegate {
} }
async _initialize() { async _initialize() {
const geolocation = this._browserContext._options.geolocation;
const language = this._browserContext._options.locale;
try { try {
await Promise.all([ await Promise.all([
// TODO: we should get rid of this call to resolve before any early events arrive, e.g. dialogs. // TODO: we should get rid of this call to resolve before any early events arrive, e.g. dialogs.
@ -95,8 +93,6 @@ export class FFPage implements PageDelegate {
script: '', script: '',
worldName: UTILITY_WORLD_NAME, worldName: UTILITY_WORLD_NAME,
}), }),
geolocation ? this._setGeolocation(geolocation) : Promise.resolve(),
language ? this._session.send('Page.setLanguageOverride', { language }) : Promise.resolve(),
new Promise(f => this._session.once('Page.ready', f)), new Promise(f => this._session.once('Page.ready', f)),
]); ]);
this._pageCallback(this._page); this._pageCallback(this._page);
@ -485,10 +481,6 @@ export class FFPage implements PageDelegate {
throw new Error('Frame has been detached.'); throw new Error('Frame has been detached.');
return result.handle; return result.handle;
} }
async _setGeolocation(geolocation: types.Geolocation | null) {
await this._session.send('Page.setGeolocationOverride', geolocation || {});
}
} }
function toRemoteObject(handle: dom.ElementHandle): Protocol.Runtime.RemoteObject { function toRemoteObject(handle: dom.ElementHandle): Protocol.Runtime.RemoteObject {

View file

@ -1,3 +1,4 @@
<script> <script>
window.result = (1000000.50).toLocaleString().replace(/\s/g, ' '); window.result = (1000000.50).toLocaleString().replace(/\s/g, ' ');
window.initialNavigatorLanguage = navigator.language;
</script> </script>

View file

@ -367,7 +367,7 @@ module.exports.describe = function({testRunner, expect, playwright, CHROMIUM, FF
}); });
}); });
describe.fail(FFOX)('BrowserContext.route', () => { describe('BrowserContext.route', () => {
it('should intercept', async({browser, server}) => { it('should intercept', async({browser, server}) => {
const context = await browser.newContext(); const context = await browser.newContext();
let intercepted = false; let intercepted = false;

View file

@ -342,7 +342,7 @@ module.exports.describe = function({testRunner, expect, playwright, headless, FF
await context.close(); await context.close();
} }
}); });
it.fail(CHROMIUM || FFOX)('should apply to popups', async({browser, server}) => { it.fail(CHROMIUM || FFOX)('should format number in popups', async({browser, server}) => {
const context = await browser.newContext({ locale: 'fr-CH' }); const context = await browser.newContext({ locale: 'fr-CH' });
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);
@ -356,6 +356,19 @@ module.exports.describe = function({testRunner, expect, playwright, headless, FF
expect(result).toBe('1 000 000,5'); expect(result).toBe('1 000 000,5');
await context.close(); await context.close();
}); });
it.fail(CHROMIUM)('should affect navigator.language in popups', async({browser, server}) => {
const context = await browser.newContext({ locale: 'fr-CH' });
const page = await context.newPage();
await page.goto(server.EMPTY_PAGE);
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.evaluate(url => window._popup = window.open(url), server.PREFIX + '/formatted-number.html'),
]);
await popup.waitForLoadState({ waitUntil: 'domcontentloaded' });
const result = await popup.evaluate(() => window.initialNavigatorLanguage);
expect(result).toBe('fr-CH');
await context.close();
});
}); });
describe('focus', function() { describe('focus', function() {

View file

@ -112,7 +112,7 @@ module.exports.describe = function ({ testRunner, expect, FFOX, WEBKIT }) {
expect(allMessages).toContain('lat=20 lng=30'); expect(allMessages).toContain('lat=20 lng=30');
expect(allMessages).toContain('lat=40 lng=50'); expect(allMessages).toContain('lat=40 lng=50');
}); });
it.fail(FFOX)('should use context options for popup', async({page, context, server}) => { it('should use context options for popup', async({page, context, server}) => {
await context.grantPermissions(['geolocation']); await context.grantPermissions(['geolocation']);
await context.setGeolocation({ longitude: 10, latitude: 10 }); await context.setGeolocation({ longitude: 10, latitude: 10 });
const [popup] = await Promise.all([ const [popup] = await Promise.all([

View file

@ -39,7 +39,7 @@ module.exports.describe = function({testRunner, expect, playwright, CHROMIUM, WE
expect(userAgent).toBe('hey'); expect(userAgent).toBe('hey');
expect(request.headers['user-agent']).toBe('hey'); expect(request.headers['user-agent']).toBe('hey');
}); });
it.fail(FFOX)('should respect routes from browser context', async function({browser, server}) { it('should respect routes from browser context', async function({browser, server}) {
const context = await browser.newContext(); const context = await browser.newContext();
const page = await context.newPage(); const page = await context.newPage();
await page.goto(server.EMPTY_PAGE); await page.goto(server.EMPTY_PAGE);