feat: add allow/block serviceWorkers option (#14714)

Adds cross-browser support for easily allowing/blocking Service Workers via a Context option.

Includes plumbing for Playwright Test's `use`.

Resolves #14522.

Relates #1090.
Supercedes #14321.
This commit is contained in:
Ross Wollman 2022-06-08 18:27:51 -04:00 коммит произвёл GitHub
Родитель 48ab172bda
Коммит 85d03714d9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 117 добавлений и 6 удалений

Просмотреть файл

@ -637,10 +637,18 @@ contexts override the proxy, global proxy will be never used and can be any stri
## context-option-strict
- `strictSelectors` <[boolean]>
It specified, enables strict selectors mode for this context. In the strict selectors mode all operations
If specified, enables strict selectors mode for this context. In the strict selectors mode all operations
on selectors that imply single target DOM element will throw when more than one element matches the selector.
See [Locator] to learn more about the strict mode.
## context-option-service-worker-policy
- `serviceWorkers` <[ServiceWorkerPolicy]<"allow"|"block">>
* `"allow"`: [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) can be registered by sites.
* `"block"`: Playwright will block all registration of Service Workers.
Defaults to `"allow"`.
## select-options-values
* langs: java, js, csharp
- `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>>
@ -796,6 +804,7 @@ An acceptable perceived color difference in the [YIQ color space](https://en.wik
- %%-context-option-recordvideo-dir-%%
- %%-context-option-recordvideo-size-%%
- %%-context-option-strict-%%
- %%-context-option-service-worker-policy-%%
## browser-option-args
- `args` <[Array]<[string]>>
@ -1020,4 +1029,3 @@ When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`,
- %%-screenshot-option-type-%%
- %%-screenshot-option-mask-%%
- %%-input-timeout-%%

Просмотреть файл

@ -215,3 +215,4 @@ Learn more about [recording video](../test-configuration.md#record-video).
## property: TestOptions.viewport = %%-context-option-viewport-%%
## property: TestOptions.serviceWorkers = %%-context-option-service-worker-policy-%%

Просмотреть файл

@ -413,6 +413,7 @@ export async function prepareBrowserContextParams(options: BrowserContextOptions
noDefaultViewport: options.viewport === null,
extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined,
storageState: await prepareStorageState(options),
serviceWorkers: options.serviceWorkers,
recordHar: prepareRecordHarOptions(options.recordHar),
};
if (!contextParams.recordVideo && options.videosPath) {

Просмотреть файл

@ -747,6 +747,7 @@ export type BrowserTypeLaunchPersistentContextParams = {
},
recordHar?: RecordHarOptions,
strictSelectors?: boolean,
serviceWorkers?: 'allow' | 'block',
userDataDir: string,
slowMo?: number,
};
@ -816,6 +817,7 @@ export type BrowserTypeLaunchPersistentContextOptions = {
},
recordHar?: RecordHarOptions,
strictSelectors?: boolean,
serviceWorkers?: 'allow' | 'block',
slowMo?: number,
};
export type BrowserTypeLaunchPersistentContextResult = {
@ -909,6 +911,7 @@ export type BrowserNewContextParams = {
},
recordHar?: RecordHarOptions,
strictSelectors?: boolean,
serviceWorkers?: 'allow' | 'block',
proxy?: {
server: string,
bypass?: string,
@ -965,6 +968,7 @@ export type BrowserNewContextOptions = {
},
recordHar?: RecordHarOptions,
strictSelectors?: boolean,
serviceWorkers?: 'allow' | 'block',
proxy?: {
server: string,
bypass?: string,
@ -3984,6 +3988,7 @@ export type AndroidDeviceLaunchBrowserParams = {
},
recordHar?: RecordHarOptions,
strictSelectors?: boolean,
serviceWorkers?: 'allow' | 'block',
pkg?: string,
proxy?: {
server: string,
@ -4037,6 +4042,7 @@ export type AndroidDeviceLaunchBrowserOptions = {
},
recordHar?: RecordHarOptions,
strictSelectors?: boolean,
serviceWorkers?: 'allow' | 'block',
pkg?: string,
proxy?: {
server: string,

Просмотреть файл

@ -455,6 +455,11 @@ ContextOptions:
height: number
recordHar: RecordHarOptions?
strictSelectors: boolean?
serviceWorkers:
type: enum?
literals:
- allow
- block
LocalUtils:
type: interface

Просмотреть файл

@ -354,6 +354,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
})),
recordHar: tOptional(tType('RecordHarOptions')),
strictSelectors: tOptional(tBoolean),
serviceWorkers: tOptional(tEnum(['allow', 'block'])),
userDataDir: tString,
slowMo: tOptional(tNumber),
});
@ -410,6 +411,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
})),
recordHar: tOptional(tType('RecordHarOptions')),
strictSelectors: tOptional(tBoolean),
serviceWorkers: tOptional(tEnum(['allow', 'block'])),
proxy: tOptional(tObject({
server: tString,
bypass: tOptional(tString),
@ -1441,6 +1443,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
})),
recordHar: tOptional(tType('RecordHarOptions')),
strictSelectors: tOptional(tBoolean),
serviceWorkers: tOptional(tEnum(['allow', 'block'])),
pkg: tOptional(tString),
proxy: tOptional(tObject({
server: tString,

Просмотреть файл

@ -122,6 +122,8 @@ export abstract class BrowserContext extends SdkObject {
if (debugMode() === 'console')
await this.extendInjectedScript(consoleApiSource.source);
if (this._options.serviceWorkers === 'block')
await this.addInitScript(`\nnavigator.serviceWorker.register = () => { console.warn('Service Worker registration blocked by Playwright'); };\n`);
}
async _ensureVideosPath() {

Просмотреть файл

@ -266,6 +266,7 @@ export type BrowserContextOptions = {
strictSelectors?: boolean,
proxy?: ProxySettings,
baseURL?: string,
serviceWorkers?: 'allow' | 'block',
};
export type EnvArray = { name: string, value: string }[];

44
packages/playwright-core/types/types.d.ts поставляемый
Просмотреть файл

@ -10371,13 +10371,22 @@ export interface BrowserType<Unused = {}> {
height: number;
};
/**
* - `"allow"`: [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) can be registered
* by sites.
* - `"block"`: Playwright will block all registration of Service Workers.
*
* Defaults to `"allow"`.
*/
serviceWorkers?: "allow"|"block";
/**
* Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on.
*/
slowMo?: number;
/**
* It specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* If specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* that imply single target DOM element will throw when more than one element matches the selector. See [Locator] to learn
* more about the strict mode.
*/
@ -11528,7 +11537,16 @@ export interface AndroidDevice {
};
/**
* It specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* - `"allow"`: [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) can be registered
* by sites.
* - `"block"`: Playwright will block all registration of Service Workers.
*
* Defaults to `"allow"`.
*/
serviceWorkers?: "allow"|"block";
/**
* If specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* that imply single target DOM element will throw when more than one element matches the selector. See [Locator] to learn
* more about the strict mode.
*/
@ -13060,6 +13078,15 @@ export interface Browser extends EventEmitter {
height: number;
};
/**
* - `"allow"`: [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) can be registered
* by sites.
* - `"block"`: Playwright will block all registration of Service Workers.
*
* Defaults to `"allow"`.
*/
serviceWorkers?: "allow"|"block";
/**
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via
@ -13115,7 +13142,7 @@ export interface Browser extends EventEmitter {
};
/**
* It specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* If specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* that imply single target DOM element will throw when more than one element matches the selector. See [Locator] to learn
* more about the strict mode.
*/
@ -15521,6 +15548,15 @@ export interface BrowserContextOptions {
height: number;
};
/**
* - `"allow"`: [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) can be registered
* by sites.
* - `"block"`: Playwright will block all registration of Service Workers.
*
* Defaults to `"allow"`.
*/
serviceWorkers?: "allow"|"block";
/**
* Populates context with given storage state. This option can be used to initialize context with logged-in information
* obtained via
@ -15576,7 +15612,7 @@ export interface BrowserContextOptions {
};
/**
* It specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* If specified, enables strict selectors mode for this context. In the strict selectors mode all operations on selectors
* that imply single target DOM element will throw when more than one element matches the selector. See [Locator] to learn
* more about the strict mode.
*/

Просмотреть файл

@ -159,6 +159,7 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
baseURL: [ async ({ }, use) => {
await use(process.env.PLAYWRIGHT_TEST_BASE_URL);
}, { option: true } ],
serviceWorkers: [ 'allow', { option: true } ],
contextOptions: [ {}, { option: true } ],
_combinedContextOptions: async ({
@ -183,6 +184,7 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
userAgent,
baseURL,
contextOptions,
serviceWorkers,
}, use) => {
const options: BrowserContextOptions = {};
if (acceptDownloads !== undefined)
@ -225,6 +227,8 @@ export const test = _baseTest.extend<TestFixtures, WorkerFixtures>({
options.viewport = viewport;
if (baseURL !== undefined)
options.baseURL = baseURL;
if (serviceWorkers !== undefined)
options.serviceWorkers = serviceWorkers;
await use({
...contextOptions,
...options,

Просмотреть файл

@ -152,6 +152,7 @@ function contextHash(context: BrowserContextOptions): string {
timezoneId: context.timezoneId,
userAgent: context.userAgent,
deviceScaleFactor: context.deviceScaleFactor,
serviceWorkers: context.serviceWorkers,
};
return JSON.stringify(hash);
}

9
packages/playwright-test/types/test.d.ts поставляемый
Просмотреть файл

@ -2494,6 +2494,7 @@ type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
type ConnectOptions = {
/**
* A browser websocket endpoint to connect to.
@ -2798,6 +2799,14 @@ export interface PlaywrightTestOptions {
* Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts).
*/
navigationTimeout: number | undefined;
/**
* - `"allow"`: [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) can be registered
* by sites.
* - `"block"`: Playwright will block all registration of Service Workers.
*
* Defaults to `"allow"`.
*/
serviceWorkers: ServiceWorkerPolicy | undefined;
}

Просмотреть файл

@ -0,0 +1,32 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { browserTest as it, expect } from '../config/browserTest';
it('should allow service workers by default', async ({ page, server }) => {
await page.goto(server.PREFIX + '/serviceworkers/empty/sw.html');
await expect(page.evaluate(() => window['registrationPromise'])).resolves.toBeTruthy();
});
it.describe('block', () => {
it.use({ serviceWorkers: 'block' });
it('blocks service worker registration', async ({ page, server }) => {
await Promise.all([
page.waitForEvent('console', evt => evt.text() === 'Service Worker registration blocked by Playwright'),
page.goto(server.PREFIX + '/serviceworkers/empty/sw.html'),
]);
});
});

2
utils/generate_types/overrides-test.d.ts поставляемый
Просмотреть файл

@ -175,6 +175,7 @@ type ColorScheme = Exclude<BrowserContextOptions['colorScheme'], undefined>;
type ExtraHTTPHeaders = Exclude<BrowserContextOptions['extraHTTPHeaders'], undefined>;
type Proxy = Exclude<BrowserContextOptions['proxy'], undefined>;
type StorageState = Exclude<BrowserContextOptions['storageState'], undefined>;
type ServiceWorkerPolicy = Exclude<BrowserContextOptions['serviceWorkers'], undefined>;
type ConnectOptions = {
/**
* A browser websocket endpoint to connect to.
@ -231,6 +232,7 @@ export interface PlaywrightTestOptions {
contextOptions: BrowserContextOptions;
actionTimeout: number | undefined;
navigationTimeout: number | undefined;
serviceWorkers: ServiceWorkerPolicy | undefined;
}