mirror of
https://github.com/microsoft/playwright.git
synced 2024-10-27 05:46:28 +03:00
feat(electron): accept BrowserContextOptions in electron.launch (#6621)
This commit is contained in:
parent
972f0ec2b5
commit
754ee13c93
@ -76,3 +76,20 @@ Specifies environment variables that will be visible to Electron. Defaults to `p
|
||||
- `timeout` <[float]>
|
||||
|
||||
Maximum time in milliseconds to wait for the application to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
|
||||
|
||||
### option: Electron.launch.acceptdownloads = %%-context-option-acceptdownloads-%%
|
||||
### option: Electron.launch.bypassCSP = %%-context-option-bypasscsp-%%
|
||||
### option: Electron.launch.colorScheme = %%-context-option-colorscheme-%%
|
||||
### option: Electron.launch.extraHTTPHeaders = %%-context-option-extrahttpheaders-%%
|
||||
### option: Electron.launch.geolocation = %%-context-option-geolocation-%%
|
||||
### option: Electron.launch.httpcredentials = %%-context-option-httpcredentials-%%
|
||||
### option: Electron.launch.ignoreHTTPSErrors = %%-context-option-ignorehttpserrors-%%
|
||||
### option: Electron.launch.locale = %%-context-option-locale-%%
|
||||
### option: Electron.launch.offline = %%-context-option-offline-%%
|
||||
### option: Electron.launch.recordhar = %%-context-option-recordhar-%%
|
||||
### option: Electron.launch.recordhar.path = %%-context-option-recordhar-path-%%
|
||||
### option: Electron.launch.recordhar.recordHarOmitContent = %%-context-option-recordhar-omit-content-%%
|
||||
### option: Electron.launch.recordvideo = %%-context-option-recordvideo-%%
|
||||
### option: Electron.launch.recordvideo.dir = %%-context-option-recordvideo-dir-%%
|
||||
### option: Electron.launch.recordvideo.size = %%-context-option-recordvideo-size-%%
|
||||
### option: Electron.launch.timezoneId = %%-context-option-timezoneid-%%
|
||||
|
@ -19,17 +19,19 @@ import * as structs from '../../types/structs';
|
||||
import * as api from '../../types/types';
|
||||
import * as channels from '../protocol/channels';
|
||||
import { TimeoutSettings } from '../utils/timeoutSettings';
|
||||
import { headersObjectToArray } from '../utils/utils';
|
||||
import { BrowserContext } from './browserContext';
|
||||
import { ChannelOwner } from './channelOwner';
|
||||
import { envObjectToArray } from './clientHelper';
|
||||
import { Events } from './events';
|
||||
import { JSHandle, parseResult, serializeArgument } from './jsHandle';
|
||||
import { Page } from './page';
|
||||
import { Env, WaitForEventOptions } from './types';
|
||||
import { Env, WaitForEventOptions, Headers } from './types';
|
||||
import { Waiter } from './waiter';
|
||||
|
||||
type ElectronOptions = Omit<channels.ElectronLaunchOptions, 'env'> & {
|
||||
type ElectronOptions = Omit<channels.ElectronLaunchOptions, 'env'|'extraHTTPHeaders'> & {
|
||||
env?: Env,
|
||||
extraHTTPHeaders?: Headers,
|
||||
};
|
||||
|
||||
type ElectronAppType = typeof import('electron');
|
||||
@ -48,6 +50,7 @@ export class Electron extends ChannelOwner<channels.ElectronChannel, channels.El
|
||||
const params: channels.ElectronLaunchParams = {
|
||||
sdkLanguage: 'javascript',
|
||||
...options,
|
||||
extraHTTPHeaders: options.extraHTTPHeaders && headersObjectToArray(options.extraHTTPHeaders),
|
||||
env: envObjectToArray(options.env ? options.env : process.env),
|
||||
};
|
||||
return ElectronApplication.from((await channel.launch(params)).electronApplication);
|
||||
|
@ -2555,6 +2555,34 @@ export type ElectronLaunchParams = {
|
||||
cwd?: string,
|
||||
env?: NameValue[],
|
||||
timeout?: number,
|
||||
acceptDownloads?: boolean,
|
||||
bypassCSP?: boolean,
|
||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||
extraHTTPHeaders?: NameValue[],
|
||||
geolocation?: {
|
||||
longitude: number,
|
||||
latitude: number,
|
||||
accuracy?: number,
|
||||
},
|
||||
httpCredentials?: {
|
||||
username: string,
|
||||
password: string,
|
||||
},
|
||||
ignoreHTTPSErrors?: boolean,
|
||||
locale?: string,
|
||||
offline?: boolean,
|
||||
recordHar?: {
|
||||
omitContent?: boolean,
|
||||
path: string,
|
||||
},
|
||||
recordVideo?: {
|
||||
dir: string,
|
||||
size?: {
|
||||
width: number,
|
||||
height: number,
|
||||
},
|
||||
},
|
||||
timezoneId?: string,
|
||||
};
|
||||
export type ElectronLaunchOptions = {
|
||||
executablePath?: string,
|
||||
@ -2562,6 +2590,34 @@ export type ElectronLaunchOptions = {
|
||||
cwd?: string,
|
||||
env?: NameValue[],
|
||||
timeout?: number,
|
||||
acceptDownloads?: boolean,
|
||||
bypassCSP?: boolean,
|
||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||
extraHTTPHeaders?: NameValue[],
|
||||
geolocation?: {
|
||||
longitude: number,
|
||||
latitude: number,
|
||||
accuracy?: number,
|
||||
},
|
||||
httpCredentials?: {
|
||||
username: string,
|
||||
password: string,
|
||||
},
|
||||
ignoreHTTPSErrors?: boolean,
|
||||
locale?: string,
|
||||
offline?: boolean,
|
||||
recordHar?: {
|
||||
omitContent?: boolean,
|
||||
path: string,
|
||||
},
|
||||
recordVideo?: {
|
||||
dir: string,
|
||||
size?: {
|
||||
width: number,
|
||||
height: number,
|
||||
},
|
||||
},
|
||||
timezoneId?: string,
|
||||
};
|
||||
export type ElectronLaunchResult = {
|
||||
electronApplication: ElectronApplicationChannel,
|
||||
|
@ -2094,6 +2094,47 @@ Electron:
|
||||
type: array?
|
||||
items: NameValue
|
||||
timeout: number?
|
||||
acceptDownloads: boolean?
|
||||
bypassCSP: boolean?
|
||||
colorScheme:
|
||||
type: enum?
|
||||
literals:
|
||||
- dark
|
||||
- light
|
||||
- no-preference
|
||||
extraHTTPHeaders:
|
||||
type: array?
|
||||
items: NameValue
|
||||
geolocation:
|
||||
type: object?
|
||||
properties:
|
||||
longitude: number
|
||||
latitude: number
|
||||
accuracy: number?
|
||||
httpCredentials:
|
||||
type: object?
|
||||
properties:
|
||||
username: string
|
||||
password: string
|
||||
ignoreHTTPSErrors: boolean?
|
||||
locale: string?
|
||||
offline: boolean?
|
||||
recordHar:
|
||||
type: object?
|
||||
properties:
|
||||
omitContent: boolean?
|
||||
path: string
|
||||
recordVideo:
|
||||
type: object?
|
||||
properties:
|
||||
dir: string
|
||||
size:
|
||||
type: object?
|
||||
properties:
|
||||
width: number
|
||||
height: number
|
||||
timezoneId: string?
|
||||
|
||||
returns:
|
||||
electronApplication: ElectronApplication
|
||||
|
||||
|
@ -973,6 +973,34 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||
cwd: tOptional(tString),
|
||||
env: tOptional(tArray(tType('NameValue'))),
|
||||
timeout: tOptional(tNumber),
|
||||
acceptDownloads: tOptional(tBoolean),
|
||||
bypassCSP: tOptional(tBoolean),
|
||||
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
|
||||
extraHTTPHeaders: tOptional(tArray(tType('NameValue'))),
|
||||
geolocation: tOptional(tObject({
|
||||
longitude: tNumber,
|
||||
latitude: tNumber,
|
||||
accuracy: tOptional(tNumber),
|
||||
})),
|
||||
httpCredentials: tOptional(tObject({
|
||||
username: tString,
|
||||
password: tString,
|
||||
})),
|
||||
ignoreHTTPSErrors: tOptional(tBoolean),
|
||||
locale: tOptional(tString),
|
||||
offline: tOptional(tBoolean),
|
||||
recordHar: tOptional(tObject({
|
||||
omitContent: tOptional(tBoolean),
|
||||
path: tString,
|
||||
})),
|
||||
recordVideo: tOptional(tObject({
|
||||
dir: tString,
|
||||
size: tOptional(tObject({
|
||||
width: tNumber,
|
||||
height: tNumber,
|
||||
})),
|
||||
})),
|
||||
timezoneId: tOptional(tString),
|
||||
});
|
||||
scheme.ElectronApplicationBrowserWindowParams = tObject({
|
||||
page: tChannel('Page'),
|
||||
|
@ -22,7 +22,6 @@ import * as js from '../javascript';
|
||||
import { Page } from '../page';
|
||||
import { TimeoutSettings } from '../../utils/timeoutSettings';
|
||||
import { WebSocketTransport } from '../transport';
|
||||
import * as types from '../types';
|
||||
import { launchProcess, envArrayToObject } from '../processLauncher';
|
||||
import { BrowserContext } from '../browserContext';
|
||||
import type {BrowserWindow} from 'electron';
|
||||
@ -33,15 +32,7 @@ import * as childProcess from 'child_process';
|
||||
import * as readline from 'readline';
|
||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||
import { internalCallMetadata, SdkObject } from '../instrumentation';
|
||||
|
||||
export type ElectronLaunchOptionsBase = {
|
||||
sdkLanguage: string,
|
||||
executablePath?: string,
|
||||
args?: string[],
|
||||
cwd?: string,
|
||||
env?: types.EnvArray,
|
||||
timeout?: number,
|
||||
};
|
||||
import * as channels from '../../protocol/channels';
|
||||
|
||||
export class ElectronApplication extends SdkObject {
|
||||
static Events = {
|
||||
@ -112,7 +103,7 @@ export class Electron extends SdkObject {
|
||||
this._playwrightOptions = playwrightOptions;
|
||||
}
|
||||
|
||||
async launch(options: ElectronLaunchOptionsBase): Promise<ElectronApplication> {
|
||||
async launch(options: channels.ElectronLaunchParams): Promise<ElectronApplication> {
|
||||
const {
|
||||
args = [],
|
||||
} = options;
|
||||
@ -164,7 +155,22 @@ export class Electron extends SdkObject {
|
||||
name: 'electron',
|
||||
isChromium: true,
|
||||
headful: true,
|
||||
persistent: { sdkLanguage: options.sdkLanguage, noDefaultViewport: true },
|
||||
persistent: {
|
||||
sdkLanguage: options.sdkLanguage,
|
||||
noDefaultViewport: true,
|
||||
acceptDownloads: options.acceptDownloads,
|
||||
bypassCSP: options.bypassCSP,
|
||||
colorScheme: options.colorScheme,
|
||||
extraHTTPHeaders: options.extraHTTPHeaders,
|
||||
geolocation: options.geolocation,
|
||||
httpCredentials: options.httpCredentials,
|
||||
ignoreHTTPSErrors: options.ignoreHTTPSErrors,
|
||||
locale: options.locale,
|
||||
offline: options.offline,
|
||||
recordHar: options.recordHar,
|
||||
recordVideo: options.recordVideo,
|
||||
timezoneId: options.timezoneId,
|
||||
},
|
||||
browserProcess,
|
||||
protocolLogger: helper.debugProtocolLogger(),
|
||||
browserLogsCollector,
|
||||
|
@ -107,3 +107,22 @@ test('should return browser window', async ({ playwright }) => {
|
||||
expect(await bwHandle.evaluate((bw: BrowserWindow) => bw.title)).toBe('Electron');
|
||||
await electronApp.close();
|
||||
});
|
||||
|
||||
test('should bypass csp', async ({playwright, server}) => {
|
||||
const app = await playwright._electron.launch({
|
||||
args: [require('path').join(__dirname, 'electron-app.js')],
|
||||
bypassCSP: true,
|
||||
});
|
||||
await app.evaluate(electron => {
|
||||
const window = new electron.BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
});
|
||||
window.loadURL('about:blank');
|
||||
});
|
||||
const page = await app.firstWindow();
|
||||
await page.goto(server.PREFIX + '/csp.html');
|
||||
await page.addScriptTag({content: 'window["__injected"] = 42;'});
|
||||
expect(await page.evaluate('window["__injected"]')).toBe(42);
|
||||
await app.close();
|
||||
});
|
||||
|
118
types/types.d.ts
vendored
118
types/types.d.ts
vendored
@ -9617,11 +9617,28 @@ export interface Electron {
|
||||
* @param options
|
||||
*/
|
||||
launch(options?: {
|
||||
/**
|
||||
* Whether to automatically download all the attachments. Defaults to `false` where all the downloads are canceled.
|
||||
*/
|
||||
acceptDownloads?: boolean;
|
||||
|
||||
/**
|
||||
* Additional arguments to pass to the application when launching. You typically pass the main script name here.
|
||||
*/
|
||||
args?: Array<string>;
|
||||
|
||||
/**
|
||||
* Toggles bypassing page's Content-Security-Policy.
|
||||
*/
|
||||
bypassCSP?: boolean;
|
||||
|
||||
/**
|
||||
* Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. See
|
||||
* [page.emulateMedia([options])](https://playwright.dev/docs/api/class-page#pageemulatemediaoptions) for more details.
|
||||
* Defaults to `'light'`.
|
||||
*/
|
||||
colorScheme?: "light"|"dark"|"no-preference";
|
||||
|
||||
/**
|
||||
* Current working directory to launch application from.
|
||||
*/
|
||||
@ -9637,6 +9654,107 @@ export interface Electron {
|
||||
* package, located at `node_modules/.bin/electron`.
|
||||
*/
|
||||
executablePath?: string;
|
||||
|
||||
/**
|
||||
* An object containing additional HTTP headers to be sent with every request. All header values must be strings.
|
||||
*/
|
||||
extraHTTPHeaders?: { [key: string]: string; };
|
||||
|
||||
geolocation?: {
|
||||
/**
|
||||
* Latitude between -90 and 90.
|
||||
*/
|
||||
latitude: number;
|
||||
|
||||
/**
|
||||
* Longitude between -180 and 180.
|
||||
*/
|
||||
longitude: number;
|
||||
|
||||
/**
|
||||
* Non-negative accuracy value. Defaults to `0`.
|
||||
*/
|
||||
accuracy?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
|
||||
*/
|
||||
httpCredentials?: {
|
||||
username: string;
|
||||
|
||||
password: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether to ignore HTTPS errors during navigation. Defaults to `false`.
|
||||
*/
|
||||
ignoreHTTPSErrors?: boolean;
|
||||
|
||||
/**
|
||||
* Specify user locale, for example `en-GB`, `de-DE`, etc. Locale will affect `navigator.language` value, `Accept-Language`
|
||||
* request header value as well as number and date formatting rules.
|
||||
*/
|
||||
locale?: string;
|
||||
|
||||
/**
|
||||
* Whether to emulate network being offline. Defaults to `false`.
|
||||
*/
|
||||
offline?: boolean;
|
||||
|
||||
/**
|
||||
* Enables [HAR](http://www.softwareishard.com/blog/har-12-spec) recording for all pages into `recordHar.path` file. If not
|
||||
* specified, the HAR is not recorded. Make sure to await
|
||||
* [browserContext.close()](https://playwright.dev/docs/api/class-browsercontext#browsercontextclose) for the HAR to be
|
||||
* saved.
|
||||
*/
|
||||
recordHar?: {
|
||||
/**
|
||||
* Optional setting to control whether to omit request content from the HAR. Defaults to `false`.
|
||||
*/
|
||||
omitContent?: boolean;
|
||||
|
||||
/**
|
||||
* Path on the filesystem to write the HAR file to.
|
||||
*/
|
||||
path: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables video recording for all pages into `recordVideo.dir` directory. If not specified videos are not recorded. Make
|
||||
* sure to await [browserContext.close()](https://playwright.dev/docs/api/class-browsercontext#browsercontextclose) for
|
||||
* videos to be saved.
|
||||
*/
|
||||
recordVideo?: {
|
||||
/**
|
||||
* Path to the directory to put videos into.
|
||||
*/
|
||||
dir: string;
|
||||
|
||||
/**
|
||||
* Optional dimensions of the recorded videos. If not specified the size will be equal to `viewport` scaled down to fit
|
||||
* into 800x800. If `viewport` is not configured explicitly the video size defaults to 800x450. Actual picture of each page
|
||||
* will be scaled down if necessary to fit the specified size.
|
||||
*/
|
||||
size?: {
|
||||
/**
|
||||
* Video frame width.
|
||||
*/
|
||||
width: number;
|
||||
|
||||
/**
|
||||
* Video frame height.
|
||||
*/
|
||||
height: number;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes the timezone of the context. See
|
||||
* [ICU's metaZones.txt](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1)
|
||||
* for a list of supported timezone IDs.
|
||||
*/
|
||||
timezoneId?: string;
|
||||
}): Promise<ElectronApplication>;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user