chore: use channels types instead of a copy in server (#14874)
This is to avoid duplicating types for no reason.
This commit is contained in:
parent
e00a26a11d
commit
06c8d8e31c
|
|
@ -16,13 +16,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as dom from './dom';
|
import type * as dom from './dom';
|
||||||
import type * as types from './types';
|
import type * as channels from '../protocol/channels';
|
||||||
|
|
||||||
export interface AXNode {
|
export interface AXNode {
|
||||||
isInteresting(insideControl: boolean): boolean;
|
isInteresting(insideControl: boolean): boolean;
|
||||||
isLeafNode(): boolean;
|
isLeafNode(): boolean;
|
||||||
isControl(): boolean;
|
isControl(): boolean;
|
||||||
serialize(): types.SerializedAXNode;
|
serialize(): channels.AXNode;
|
||||||
children(): Iterable<AXNode>;
|
children(): Iterable<AXNode>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ export class Accessibility {
|
||||||
async snapshot(options: {
|
async snapshot(options: {
|
||||||
interestingOnly?: boolean;
|
interestingOnly?: boolean;
|
||||||
root?: dom.ElementHandle;
|
root?: dom.ElementHandle;
|
||||||
} = {}): Promise<types.SerializedAXNode | null> {
|
} = {}): Promise<channels.AXNode | null> {
|
||||||
const {
|
const {
|
||||||
interestingOnly = true,
|
interestingOnly = true,
|
||||||
root = null,
|
root = null,
|
||||||
|
|
@ -65,8 +65,8 @@ function collectInterestingNodes(collection: Set<AXNode>, node: AXNode, insideCo
|
||||||
collectInterestingNodes(collection, child, insideControl);
|
collectInterestingNodes(collection, child, insideControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeTree(node: AXNode, whitelistedNodes?: Set<AXNode>): types.SerializedAXNode[] {
|
function serializeTree(node: AXNode, whitelistedNodes?: Set<AXNode>): channels.AXNode[] {
|
||||||
const children: types.SerializedAXNode[] = [];
|
const children: channels.AXNode[] = [];
|
||||||
for (const child of node.children())
|
for (const child of node.children())
|
||||||
children.push(...serializeTree(child, whitelistedNodes));
|
children.push(...serializeTree(child, whitelistedNodes));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { debug } from '../../utilsBundle';
|
import { debug } from '../../utilsBundle';
|
||||||
import type * as types from '../types';
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
|
|
@ -34,13 +33,13 @@ import { PipeTransport } from '../../protocol/transport';
|
||||||
import { RecentLogsCollector } from '../../common/debugLogger';
|
import { RecentLogsCollector } from '../../common/debugLogger';
|
||||||
import { gracefullyCloseSet } from '../../utils/processLauncher';
|
import { gracefullyCloseSet } from '../../utils/processLauncher';
|
||||||
import { TimeoutSettings } from '../../common/timeoutSettings';
|
import { TimeoutSettings } from '../../common/timeoutSettings';
|
||||||
import type { AndroidWebView } from '../../protocol/channels';
|
import type * as channels from '../../protocol/channels';
|
||||||
import { SdkObject, serverSideCallMetadata } from '../instrumentation';
|
import { SdkObject, serverSideCallMetadata } from '../instrumentation';
|
||||||
|
|
||||||
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||||
|
|
||||||
export interface Backend {
|
export interface Backend {
|
||||||
devices(options: types.AndroidDeviceOptions): Promise<DeviceBackend[]>;
|
devices(options: channels.AndroidDevicesOptions): Promise<DeviceBackend[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeviceBackend {
|
export interface DeviceBackend {
|
||||||
|
|
@ -75,7 +74,7 @@ export class Android extends SdkObject {
|
||||||
this._timeoutSettings.setDefaultTimeout(timeout);
|
this._timeoutSettings.setDefaultTimeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
async devices(options: types.AndroidDeviceOptions): Promise<AndroidDevice[]> {
|
async devices(options: channels.AndroidDevicesOptions): Promise<AndroidDevice[]> {
|
||||||
const devices = (await this._backend.devices(options)).filter(d => d.status === 'device');
|
const devices = (await this._backend.devices(options)).filter(d => d.status === 'device');
|
||||||
const newSerials = new Set<string>();
|
const newSerials = new Set<string>();
|
||||||
for (const d of devices) {
|
for (const d of devices) {
|
||||||
|
|
@ -101,13 +100,13 @@ export class AndroidDevice extends SdkObject {
|
||||||
readonly _backend: DeviceBackend;
|
readonly _backend: DeviceBackend;
|
||||||
readonly model: string;
|
readonly model: string;
|
||||||
readonly serial: string;
|
readonly serial: string;
|
||||||
private _options: types.AndroidDeviceOptions;
|
private _options: channels.AndroidDevicesOptions;
|
||||||
private _driverPromise: Promise<PipeTransport> | undefined;
|
private _driverPromise: Promise<PipeTransport> | undefined;
|
||||||
private _lastId = 0;
|
private _lastId = 0;
|
||||||
private _callbacks = new Map<number, { fulfill: (result: any) => void, reject: (error: Error) => void }>();
|
private _callbacks = new Map<number, { fulfill: (result: any) => void, reject: (error: Error) => void }>();
|
||||||
private _pollingWebViews: NodeJS.Timeout | undefined;
|
private _pollingWebViews: NodeJS.Timeout | undefined;
|
||||||
readonly _timeoutSettings: TimeoutSettings;
|
readonly _timeoutSettings: TimeoutSettings;
|
||||||
private _webViews = new Map<string, AndroidWebView>();
|
private _webViews = new Map<string, channels.AndroidWebView>();
|
||||||
|
|
||||||
static Events = {
|
static Events = {
|
||||||
WebViewAdded: 'webViewAdded',
|
WebViewAdded: 'webViewAdded',
|
||||||
|
|
@ -119,7 +118,7 @@ export class AndroidDevice extends SdkObject {
|
||||||
private _android: Android;
|
private _android: Android;
|
||||||
private _isClosed = false;
|
private _isClosed = false;
|
||||||
|
|
||||||
constructor(android: Android, backend: DeviceBackend, model: string, options: types.AndroidDeviceOptions) {
|
constructor(android: Android, backend: DeviceBackend, model: string, options: channels.AndroidDevicesOptions) {
|
||||||
super(android, 'android-device');
|
super(android, 'android-device');
|
||||||
this._android = android;
|
this._android = android;
|
||||||
this._backend = backend;
|
this._backend = backend;
|
||||||
|
|
@ -129,7 +128,7 @@ export class AndroidDevice extends SdkObject {
|
||||||
this._timeoutSettings = new TimeoutSettings(android._timeoutSettings);
|
this._timeoutSettings = new TimeoutSettings(android._timeoutSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async create(android: Android, backend: DeviceBackend, options: types.AndroidDeviceOptions): Promise<AndroidDevice> {
|
static async create(android: Android, backend: DeviceBackend, options: channels.AndroidDevicesOptions): Promise<AndroidDevice> {
|
||||||
await backend.init();
|
await backend.init();
|
||||||
const model = await backend.runCommand('shell:getprop ro.product.model');
|
const model = await backend.runCommand('shell:getprop ro.product.model');
|
||||||
const device = new AndroidDevice(android, backend, model.toString().trim(), options);
|
const device = new AndroidDevice(android, backend, model.toString().trim(), options);
|
||||||
|
|
@ -244,7 +243,7 @@ export class AndroidDevice extends SdkObject {
|
||||||
this.emit(AndroidDevice.Events.Closed);
|
this.emit(AndroidDevice.Events.Closed);
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchBrowser(pkg: string = 'com.android.chrome', options: types.BrowserContextOptions): Promise<BrowserContext> {
|
async launchBrowser(pkg: string = 'com.android.chrome', options: channels.BrowserNewContextParams): Promise<BrowserContext> {
|
||||||
debug('pw:android')('Force-stopping', pkg);
|
debug('pw:android')('Force-stopping', pkg);
|
||||||
await this._backend.runCommand(`shell:am force-stop ${pkg}`);
|
await this._backend.runCommand(`shell:am force-stop ${pkg}`);
|
||||||
const socketName = isUnderTest() ? 'webview_devtools_remote_playwright_test' : ('playwright-' + createGuid());
|
const socketName = isUnderTest() ? 'webview_devtools_remote_playwright_test' : ('playwright-' + createGuid());
|
||||||
|
|
@ -262,7 +261,7 @@ export class AndroidDevice extends SdkObject {
|
||||||
return await this._connectToBrowser(socketName);
|
return await this._connectToBrowser(socketName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _connectToBrowser(socketName: string, options: types.BrowserContextOptions = {}): Promise<BrowserContext> {
|
private async _connectToBrowser(socketName: string, options: channels.BrowserNewContextParams = {}): Promise<BrowserContext> {
|
||||||
const socket = await this._waitForLocalAbstract(socketName);
|
const socket = await this._waitForLocalAbstract(socketName);
|
||||||
const androidBrowser = new AndroidBrowser(this, socket);
|
const androidBrowser = new AndroidBrowser(this, socket);
|
||||||
await androidBrowser._init();
|
await androidBrowser._init();
|
||||||
|
|
@ -304,7 +303,7 @@ export class AndroidDevice extends SdkObject {
|
||||||
return defaultContext;
|
return defaultContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
webViews(): AndroidWebView[] {
|
webViews(): channels.AndroidWebView[] {
|
||||||
return [...this._webViews.values()];
|
return [...this._webViews.values()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { debug } from '../../utilsBundle';
|
import { debug } from '../../utilsBundle';
|
||||||
import type * as types from '../types';
|
import type * as channels from '../../protocol/channels';
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import type { Backend, DeviceBackend, SocketBackend } from './android';
|
import type { Backend, DeviceBackend, SocketBackend } from './android';
|
||||||
import { assert, createGuid } from '../../utils';
|
import { assert, createGuid } from '../../utils';
|
||||||
|
|
||||||
export class AdbBackend implements Backend {
|
export class AdbBackend implements Backend {
|
||||||
async devices(options: types.AndroidDeviceOptions = {}): Promise<DeviceBackend[]> {
|
async devices(options: channels.AndroidDevicesOptions = {}): Promise<DeviceBackend[]> {
|
||||||
const result = await runCommand('host:devices', options.host, options.port);
|
const result = await runCommand('host:devices', options.host, options.port);
|
||||||
const lines = result.toString().trim().split('\n');
|
const lines = result.toString().trim().split('\n');
|
||||||
return lines.map(line => {
|
return lines.map(line => {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as types from './types';
|
import type * as types from './types';
|
||||||
|
import type * as channels from '../protocol/channels';
|
||||||
import { BrowserContext, validateBrowserContextOptions } from './browserContext';
|
import { BrowserContext, validateBrowserContextOptions } from './browserContext';
|
||||||
import { Page } from './page';
|
import { Page } from './page';
|
||||||
import { Download } from './download';
|
import { Download } from './download';
|
||||||
|
|
@ -48,7 +49,7 @@ export type BrowserOptions = PlaywrightOptions & {
|
||||||
downloadsPath: string,
|
downloadsPath: string,
|
||||||
tracesDir: string,
|
tracesDir: string,
|
||||||
headful?: boolean,
|
headful?: boolean,
|
||||||
persistent?: types.BrowserContextOptions, // Undefined means no persistent context.
|
persistent?: channels.BrowserNewContextParams, // Undefined means no persistent context.
|
||||||
browserProcess: BrowserProcess,
|
browserProcess: BrowserProcess,
|
||||||
customExecutablePath?: string;
|
customExecutablePath?: string;
|
||||||
proxy?: ProxySettings,
|
proxy?: ProxySettings,
|
||||||
|
|
@ -75,13 +76,13 @@ export abstract class Browser extends SdkObject {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract doCreateNewContext(options: types.BrowserContextOptions): Promise<BrowserContext>;
|
abstract doCreateNewContext(options: channels.BrowserNewContextParams): Promise<BrowserContext>;
|
||||||
abstract contexts(): BrowserContext[];
|
abstract contexts(): BrowserContext[];
|
||||||
abstract isConnected(): boolean;
|
abstract isConnected(): boolean;
|
||||||
abstract version(): string;
|
abstract version(): string;
|
||||||
abstract userAgent(): string;
|
abstract userAgent(): string;
|
||||||
|
|
||||||
async newContext(metadata: CallMetadata, options: types.BrowserContextOptions): Promise<BrowserContext> {
|
async newContext(metadata: CallMetadata, options: channels.BrowserNewContextParams): Promise<BrowserContext> {
|
||||||
validateBrowserContextOptions(options, this.options);
|
validateBrowserContextOptions(options, this.options);
|
||||||
const context = await this.doCreateNewContext(options);
|
const context = await this.doCreateNewContext(options);
|
||||||
if (options.storageState)
|
if (options.storageState)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import { Page, PageBinding } from './page';
|
||||||
import type { Progress } from './progress';
|
import type { Progress } from './progress';
|
||||||
import type { Selectors } from './selectors';
|
import type { Selectors } from './selectors';
|
||||||
import type * as types from './types';
|
import type * as types from './types';
|
||||||
|
import type * as channels from '../protocol/channels';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import type { CallMetadata } from './instrumentation';
|
import type { CallMetadata } from './instrumentation';
|
||||||
|
|
@ -54,7 +55,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
|
|
||||||
readonly _timeoutSettings = new TimeoutSettings();
|
readonly _timeoutSettings = new TimeoutSettings();
|
||||||
readonly _pageBindings = new Map<string, PageBinding>();
|
readonly _pageBindings = new Map<string, PageBinding>();
|
||||||
readonly _options: types.BrowserContextOptions;
|
readonly _options: channels.BrowserNewContextParams;
|
||||||
_requestInterceptor?: network.RouteHandler;
|
_requestInterceptor?: network.RouteHandler;
|
||||||
private _isPersistentContext: boolean;
|
private _isPersistentContext: boolean;
|
||||||
private _closedStatus: 'open' | 'closing' | 'closed' = 'open';
|
private _closedStatus: 'open' | 'closing' | 'closed' = 'open';
|
||||||
|
|
@ -74,7 +75,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
private _settingStorageState = false;
|
private _settingStorageState = false;
|
||||||
readonly initScripts: string[] = [];
|
readonly initScripts: string[] = [];
|
||||||
|
|
||||||
constructor(browser: Browser, options: types.BrowserContextOptions, browserContextId: string | undefined) {
|
constructor(browser: Browser, options: channels.BrowserNewContextParams, browserContextId: string | undefined) {
|
||||||
super(browser, 'browser-context');
|
super(browser, 'browser-context');
|
||||||
this.attribution.context = this;
|
this.attribution.context = this;
|
||||||
this._browser = browser;
|
this._browser = browser;
|
||||||
|
|
@ -156,13 +157,13 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
// BrowserContext methods.
|
// BrowserContext methods.
|
||||||
abstract pages(): Page[];
|
abstract pages(): Page[];
|
||||||
abstract newPageDelegate(): Promise<PageDelegate>;
|
abstract newPageDelegate(): Promise<PageDelegate>;
|
||||||
abstract addCookies(cookies: types.SetNetworkCookieParam[]): Promise<void>;
|
abstract addCookies(cookies: channels.SetNetworkCookie[]): Promise<void>;
|
||||||
abstract clearCookies(): Promise<void>;
|
abstract clearCookies(): Promise<void>;
|
||||||
abstract setGeolocation(geolocation?: types.Geolocation): Promise<void>;
|
abstract setGeolocation(geolocation?: types.Geolocation): Promise<void>;
|
||||||
abstract setExtraHTTPHeaders(headers: types.HeadersArray): Promise<void>;
|
abstract setExtraHTTPHeaders(headers: types.HeadersArray): Promise<void>;
|
||||||
abstract setOffline(offline: boolean): Promise<void>;
|
abstract setOffline(offline: boolean): Promise<void>;
|
||||||
abstract cancelDownload(uuid: string): Promise<void>;
|
abstract cancelDownload(uuid: string): Promise<void>;
|
||||||
protected abstract doGetCookies(urls: string[]): Promise<types.NetworkCookie[]>;
|
protected abstract doGetCookies(urls: string[]): Promise<channels.NetworkCookie[]>;
|
||||||
protected abstract doGrantPermissions(origin: string, permissions: string[]): Promise<void>;
|
protected abstract doGrantPermissions(origin: string, permissions: string[]): Promise<void>;
|
||||||
protected abstract doClearPermissions(): Promise<void>;
|
protected abstract doClearPermissions(): Promise<void>;
|
||||||
protected abstract doSetHTTPCredentials(httpCredentials?: types.Credentials): Promise<void>;
|
protected abstract doSetHTTPCredentials(httpCredentials?: types.Credentials): Promise<void>;
|
||||||
|
|
@ -174,7 +175,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
protected abstract doClose(): Promise<void>;
|
protected abstract doClose(): Promise<void>;
|
||||||
protected abstract onClosePersistent(): void;
|
protected abstract onClosePersistent(): void;
|
||||||
|
|
||||||
async cookies(urls: string | string[] | undefined = []): Promise<types.NetworkCookie[]> {
|
async cookies(urls: string | string[] | undefined = []): Promise<channels.NetworkCookie[]> {
|
||||||
if (urls && !Array.isArray(urls))
|
if (urls && !Array.isArray(urls))
|
||||||
urls = [ urls ];
|
urls = [ urls ];
|
||||||
return await this.doGetCookies(urls as string[]);
|
return await this.doGetCookies(urls as string[]);
|
||||||
|
|
@ -374,8 +375,8 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
this._origins.add(origin);
|
this._origins.add(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
async storageState(): Promise<types.StorageState> {
|
async storageState(): Promise<channels.BrowserContextStorageStateResult> {
|
||||||
const result: types.StorageState = {
|
const result: channels.BrowserContextStorageStateResult = {
|
||||||
cookies: await this.cookies(),
|
cookies: await this.cookies(),
|
||||||
origins: []
|
origins: []
|
||||||
};
|
};
|
||||||
|
|
@ -386,7 +387,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
handler.fulfill({ body: '<html></html>' }).catch(() => {});
|
handler.fulfill({ body: '<html></html>' }).catch(() => {});
|
||||||
});
|
});
|
||||||
for (const origin of this._origins) {
|
for (const origin of this._origins) {
|
||||||
const originStorage: types.OriginStorage = { origin, localStorage: [] };
|
const originStorage: channels.OriginStorage = { origin, localStorage: [] };
|
||||||
const frame = page.mainFrame();
|
const frame = page.mainFrame();
|
||||||
await frame.goto(internalMetadata, origin);
|
await frame.goto(internalMetadata, origin);
|
||||||
const storage = await frame.evaluateExpression(`({
|
const storage = await frame.evaluateExpression(`({
|
||||||
|
|
@ -405,7 +406,7 @@ export abstract class BrowserContext extends SdkObject {
|
||||||
return this._settingStorageState;
|
return this._settingStorageState;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setStorageState(metadata: CallMetadata, state: types.SetStorageState) {
|
async setStorageState(metadata: CallMetadata, state: NonNullable<channels.BrowserNewContextParams['storageState']>) {
|
||||||
this._settingStorageState = true;
|
this._settingStorageState = true;
|
||||||
try {
|
try {
|
||||||
if (state.cookies)
|
if (state.cookies)
|
||||||
|
|
@ -450,7 +451,7 @@ export function assertBrowserContextIsNotOwned(context: BrowserContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validateBrowserContextOptions(options: types.BrowserContextOptions, browserOptions: BrowserOptions) {
|
export function validateBrowserContextOptions(options: channels.BrowserNewContextParams, browserOptions: BrowserOptions) {
|
||||||
if (options.noDefaultViewport && options.deviceScaleFactor !== undefined)
|
if (options.noDefaultViewport && options.deviceScaleFactor !== undefined)
|
||||||
throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`);
|
throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`);
|
||||||
if (options.noDefaultViewport && options.isMobile !== undefined)
|
if (options.noDefaultViewport && options.isMobile !== undefined)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import { PipeTransport } from './pipeTransport';
|
||||||
import type { Progress } from './progress';
|
import type { Progress } from './progress';
|
||||||
import { ProgressController } from './progress';
|
import { ProgressController } from './progress';
|
||||||
import type * as types from './types';
|
import type * as types from './types';
|
||||||
|
import type * as channels from '../protocol/channels';
|
||||||
import { DEFAULT_TIMEOUT, TimeoutSettings } from '../common/timeoutSettings';
|
import { DEFAULT_TIMEOUT, TimeoutSettings } from '../common/timeoutSettings';
|
||||||
import { debugMode } from '../utils';
|
import { debugMode } from '../utils';
|
||||||
import { existsAsync } from '../utils/fileUtils';
|
import { existsAsync } from '../utils/fileUtils';
|
||||||
|
|
@ -73,10 +74,10 @@ export abstract class BrowserType extends SdkObject {
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
async launchPersistentContext(metadata: CallMetadata, userDataDir: string, options: types.LaunchPersistentOptions): Promise<BrowserContext> {
|
async launchPersistentContext(metadata: CallMetadata, userDataDir: string, options: channels.BrowserTypeLaunchPersistentContextOptions & { useWebSocket?: boolean }): Promise<BrowserContext> {
|
||||||
options = this._validateLaunchOptions(options);
|
options = this._validateLaunchOptions(options);
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
const persistent: types.BrowserContextOptions = options;
|
const persistent: channels.BrowserNewContextParams = options;
|
||||||
controller.setLogName('browser');
|
controller.setLogName('browser');
|
||||||
const browser = await controller.run(progress => {
|
const browser = await controller.run(progress => {
|
||||||
return this._innerLaunchWithRetries(progress, options, persistent, helper.debugProtocolLogger(), userDataDir).catch(e => { throw this._rewriteStartupError(e); });
|
return this._innerLaunchWithRetries(progress, options, persistent, helper.debugProtocolLogger(), userDataDir).catch(e => { throw this._rewriteStartupError(e); });
|
||||||
|
|
@ -84,7 +85,7 @@ export abstract class BrowserType extends SdkObject {
|
||||||
return browser._defaultContext!;
|
return browser._defaultContext!;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _innerLaunchWithRetries(progress: Progress, options: types.LaunchOptions, persistent: types.BrowserContextOptions | undefined, protocolLogger: types.ProtocolLogger, userDataDir?: string): Promise<Browser> {
|
async _innerLaunchWithRetries(progress: Progress, options: types.LaunchOptions, persistent: channels.BrowserNewContextParams | undefined, protocolLogger: types.ProtocolLogger, userDataDir?: string): Promise<Browser> {
|
||||||
try {
|
try {
|
||||||
return await this._innerLaunch(progress, options, persistent, protocolLogger, userDataDir);
|
return await this._innerLaunch(progress, options, persistent, protocolLogger, userDataDir);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -98,7 +99,7 @@ export abstract class BrowserType extends SdkObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _innerLaunch(progress: Progress, options: types.LaunchOptions, persistent: types.BrowserContextOptions | undefined, protocolLogger: types.ProtocolLogger, maybeUserDataDir?: string): Promise<Browser> {
|
async _innerLaunch(progress: Progress, options: types.LaunchOptions, persistent: channels.BrowserNewContextParams | undefined, protocolLogger: types.ProtocolLogger, maybeUserDataDir?: string): Promise<Browser> {
|
||||||
options.proxy = options.proxy ? normalizeProxySettings(options.proxy) : undefined;
|
options.proxy = options.proxy ? normalizeProxySettings(options.proxy) : undefined;
|
||||||
const browserLogsCollector = new RecentLogsCollector();
|
const browserLogsCollector = new RecentLogsCollector();
|
||||||
const { browserProcess, userDataDir, artifactsDir, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, maybeUserDataDir);
|
const { browserProcess, userDataDir, artifactsDir, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, maybeUserDataDir);
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import { CRDevTools } from './crDevTools';
|
||||||
import type { BrowserOptions, BrowserProcess, PlaywrightOptions } from '../browser';
|
import type { BrowserOptions, BrowserProcess, PlaywrightOptions } from '../browser';
|
||||||
import { Browser } from '../browser';
|
import { Browser } from '../browser';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
import type * as channels from '../../protocol/channels';
|
||||||
import type { HTTPRequestParams } from '../../common/netUtils';
|
import type { HTTPRequestParams } from '../../common/netUtils';
|
||||||
import { fetchData } from '../../common/netUtils';
|
import { fetchData } from '../../common/netUtils';
|
||||||
import { getUserAgent } from '../../common/userAgent';
|
import { getUserAgent } from '../../common/userAgent';
|
||||||
|
|
@ -94,7 +95,7 @@ export class Chromium extends BrowserType {
|
||||||
await cleanedUp;
|
await cleanedUp;
|
||||||
};
|
};
|
||||||
const browserProcess: BrowserProcess = { close: doClose, kill: doClose };
|
const browserProcess: BrowserProcess = { close: doClose, kill: doClose };
|
||||||
const persistent: types.BrowserContextOptions = { noDefaultViewport: true };
|
const persistent: channels.BrowserNewContextParams = { noDefaultViewport: true };
|
||||||
const browserOptions: BrowserOptions = {
|
const browserOptions: BrowserOptions = {
|
||||||
...this._playwrightOptions,
|
...this._playwrightOptions,
|
||||||
slowMo: options.slowMo,
|
slowMo: options.slowMo,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import type { CRSession } from './crConnection';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type * as dom from '../dom';
|
import type * as dom from '../dom';
|
||||||
import type * as accessibility from '../accessibility';
|
import type * as accessibility from '../accessibility';
|
||||||
import type * as types from '../types';
|
import type * as channels from '../../protocol/channels';
|
||||||
|
|
||||||
export async function getAccessibilityTree(client: CRSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
export async function getAccessibilityTree(client: CRSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
||||||
const { nodes } = await client.send('Accessibility.getFullAXTree');
|
const { nodes } = await client.send('Accessibility.getFullAXTree');
|
||||||
|
|
@ -210,19 +210,19 @@ class CRAXNode implements accessibility.AXNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(): types.SerializedAXNode {
|
serialize(): channels.AXNode {
|
||||||
const properties: Map<string, number | string | boolean> = new Map();
|
const properties: Map<string, number | string | boolean> = new Map();
|
||||||
for (const property of this._payload.properties || [])
|
for (const property of this._payload.properties || [])
|
||||||
properties.set(property.name.toLowerCase(), property.value.value);
|
properties.set(property.name.toLowerCase(), property.value.value);
|
||||||
if (this._payload.description)
|
if (this._payload.description)
|
||||||
properties.set('description', this._payload.description.value);
|
properties.set('description', this._payload.description.value);
|
||||||
|
|
||||||
const node: {[x in keyof types.SerializedAXNode]: any} = {
|
const node: {[x in keyof channels.AXNode]: any} = {
|
||||||
role: this.normalizedRole(),
|
role: this.normalizedRole(),
|
||||||
name: this._payload.name ? (this._payload.name.value || '') : '',
|
name: this._payload.name ? (this._payload.name.value || '') : '',
|
||||||
};
|
};
|
||||||
|
|
||||||
const userStringProperties: Array<keyof types.SerializedAXNode> = [
|
const userStringProperties: Array<keyof channels.AXNode> = [
|
||||||
'description',
|
'description',
|
||||||
'keyshortcuts',
|
'keyshortcuts',
|
||||||
'roledescription',
|
'roledescription',
|
||||||
|
|
@ -233,7 +233,7 @@ class CRAXNode implements accessibility.AXNode {
|
||||||
continue;
|
continue;
|
||||||
node[userStringProperty] = properties.get(userStringProperty);
|
node[userStringProperty] = properties.get(userStringProperty);
|
||||||
}
|
}
|
||||||
const booleanProperties: Array<keyof types.SerializedAXNode> = [
|
const booleanProperties: Array<keyof channels.AXNode> = [
|
||||||
'disabled',
|
'disabled',
|
||||||
'expanded',
|
'expanded',
|
||||||
'focused',
|
'focused',
|
||||||
|
|
@ -254,7 +254,7 @@ class CRAXNode implements accessibility.AXNode {
|
||||||
continue;
|
continue;
|
||||||
node[booleanProperty] = value;
|
node[booleanProperty] = value;
|
||||||
}
|
}
|
||||||
const numericalProperties: Array<keyof types.SerializedAXNode> = [
|
const numericalProperties: Array<keyof channels.AXNode> = [
|
||||||
'level',
|
'level',
|
||||||
'valuemax',
|
'valuemax',
|
||||||
'valuemin',
|
'valuemin',
|
||||||
|
|
@ -264,7 +264,7 @@ class CRAXNode implements accessibility.AXNode {
|
||||||
continue;
|
continue;
|
||||||
node[numericalProperty] = properties.get(numericalProperty);
|
node[numericalProperty] = properties.get(numericalProperty);
|
||||||
}
|
}
|
||||||
const tokenProperties: Array<keyof types.SerializedAXNode> = [
|
const tokenProperties: Array<keyof channels.AXNode> = [
|
||||||
'autocomplete',
|
'autocomplete',
|
||||||
'haspopup',
|
'haspopup',
|
||||||
'invalid',
|
'invalid',
|
||||||
|
|
@ -277,7 +277,7 @@ class CRAXNode implements accessibility.AXNode {
|
||||||
node[tokenProperty] = value;
|
node[tokenProperty] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const axNode = node as types.SerializedAXNode;
|
const axNode = node as channels.AXNode;
|
||||||
if (this._payload.value) {
|
if (this._payload.value) {
|
||||||
if (typeof this._payload.value.value === 'string')
|
if (typeof this._payload.value.value === 'string')
|
||||||
axNode.valueString = this._payload.value.value;
|
axNode.valueString = this._payload.value.value;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import { Frame } from '../frames';
|
||||||
import type { Dialog } from '../dialog';
|
import type { Dialog } from '../dialog';
|
||||||
import type { ConnectionTransport } from '../transport';
|
import type { ConnectionTransport } from '../transport';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
import type * as channels from '../../protocol/channels';
|
||||||
import type { CRSession } from './crConnection';
|
import type { CRSession } from './crConnection';
|
||||||
import { ConnectionEvents, CRConnection } from './crConnection';
|
import { ConnectionEvents, CRConnection } from './crConnection';
|
||||||
import { CRPage } from './crPage';
|
import { CRPage } from './crPage';
|
||||||
|
|
@ -95,7 +96,7 @@ export class CRBrowser extends Browser {
|
||||||
this._session.on('Browser.downloadProgress', this._onDownloadProgress.bind(this));
|
this._session.on('Browser.downloadProgress', this._onDownloadProgress.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
async doCreateNewContext(options: types.BrowserContextOptions): Promise<BrowserContext> {
|
async doCreateNewContext(options: channels.BrowserNewContextParams): Promise<BrowserContext> {
|
||||||
let proxyBypassList = undefined;
|
let proxyBypassList = undefined;
|
||||||
if (options.proxy) {
|
if (options.proxy) {
|
||||||
if (process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK)
|
if (process.env.PLAYWRIGHT_DISABLE_FORCED_CHROMIUM_PROXIED_LOOPBACK)
|
||||||
|
|
@ -327,7 +328,7 @@ export class CRBrowserContext extends BrowserContext {
|
||||||
|
|
||||||
declare readonly _browser: CRBrowser;
|
declare readonly _browser: CRBrowser;
|
||||||
|
|
||||||
constructor(browser: CRBrowser, browserContextId: string | undefined, options: types.BrowserContextOptions) {
|
constructor(browser: CRBrowser, browserContextId: string | undefined, options: channels.BrowserNewContextParams) {
|
||||||
super(browser, options, browserContextId);
|
super(browser, options, browserContextId);
|
||||||
this._authenticateProxyViaCredentials();
|
this._authenticateProxyViaCredentials();
|
||||||
}
|
}
|
||||||
|
|
@ -383,7 +384,7 @@ export class CRBrowserContext extends BrowserContext {
|
||||||
return this._browser._crPages.get(targetId)!;
|
return this._browser._crPages.get(targetId)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
async doGetCookies(urls: string[]): Promise<types.NetworkCookie[]> {
|
async doGetCookies(urls: string[]): Promise<channels.NetworkCookie[]> {
|
||||||
const { cookies } = await this._browser._session.send('Storage.getCookies', { browserContextId: this._browserContextId });
|
const { cookies } = await this._browser._session.send('Storage.getCookies', { browserContextId: this._browserContextId });
|
||||||
return network.filterCookies(cookies.map(c => {
|
return network.filterCookies(cookies.map(c => {
|
||||||
const copy: any = { sameSite: 'Lax', ...c };
|
const copy: any = { sameSite: 'Lax', ...c };
|
||||||
|
|
@ -393,11 +394,11 @@ export class CRBrowserContext extends BrowserContext {
|
||||||
delete copy.sameParty;
|
delete copy.sameParty;
|
||||||
delete copy.sourceScheme;
|
delete copy.sourceScheme;
|
||||||
delete copy.sourcePort;
|
delete copy.sourcePort;
|
||||||
return copy as types.NetworkCookie;
|
return copy as channels.NetworkCookie;
|
||||||
}), urls);
|
}), urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addCookies(cookies: types.SetNetworkCookieParam[]) {
|
async addCookies(cookies: channels.SetNetworkCookie[]) {
|
||||||
await this._browser._session.send('Storage.setCookies', { cookies: network.rewriteCookies(cookies), browserContextId: this._browserContextId });
|
await this._browser._session.send('Storage.setCookies', { cookies: network.rewriteCookies(cookies), browserContextId: this._browserContextId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import type { CRSession } from './crConnection';
|
||||||
import type { RegisteredListener } from '../../utils/eventsHelper';
|
import type { RegisteredListener } from '../../utils/eventsHelper';
|
||||||
import { eventsHelper } from '../../utils/eventsHelper';
|
import { eventsHelper } from '../../utils/eventsHelper';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type * as types from '../types';
|
import type * as channels from '../../protocol/channels';
|
||||||
import { assert } from '../../utils';
|
import { assert } from '../../utils';
|
||||||
|
|
||||||
export class CRCoverage {
|
export class CRCoverage {
|
||||||
|
|
@ -31,19 +31,19 @@ export class CRCoverage {
|
||||||
this._cssCoverage = new CSSCoverage(client);
|
this._cssCoverage = new CSSCoverage(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
async startJSCoverage(options?: types.JSCoverageOptions) {
|
async startJSCoverage(options: channels.PageStartJSCoverageParams) {
|
||||||
return await this._jsCoverage.start(options);
|
return await this._jsCoverage.start(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopJSCoverage(): Promise<types.JSCoverageEntry[]> {
|
async stopJSCoverage(): Promise<channels.PageStopJSCoverageResult> {
|
||||||
return await this._jsCoverage.stop();
|
return await this._jsCoverage.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
async startCSSCoverage(options?: types.CSSCoverageOptions) {
|
async startCSSCoverage(options: channels.PageStartCSSCoverageParams) {
|
||||||
return await this._cssCoverage.start(options);
|
return await this._cssCoverage.start(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async stopCSSCoverage(): Promise<types.CSSCoverageEntry[]> {
|
async stopCSSCoverage(): Promise<channels.PageStopCSSCoverageResult> {
|
||||||
return await this._cssCoverage.stop();
|
return await this._cssCoverage.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +66,7 @@ class JSCoverage {
|
||||||
this._resetOnNavigation = false;
|
this._resetOnNavigation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(options: types.JSCoverageOptions = {}) {
|
async start(options: channels.PageStartJSCoverageParams) {
|
||||||
assert(!this._enabled, 'JSCoverage is already enabled');
|
assert(!this._enabled, 'JSCoverage is already enabled');
|
||||||
const {
|
const {
|
||||||
resetOnNavigation = true,
|
resetOnNavigation = true,
|
||||||
|
|
@ -112,7 +112,7 @@ class JSCoverage {
|
||||||
this._scriptSources.set(event.scriptId, response.scriptSource);
|
this._scriptSources.set(event.scriptId, response.scriptSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop(): Promise<types.JSCoverageEntry[]> {
|
async stop(): Promise<channels.PageStopJSCoverageResult> {
|
||||||
assert(this._enabled, 'JSCoverage is not enabled');
|
assert(this._enabled, 'JSCoverage is not enabled');
|
||||||
this._enabled = false;
|
this._enabled = false;
|
||||||
const [profileResponse] = await Promise.all([
|
const [profileResponse] = await Promise.all([
|
||||||
|
|
@ -123,7 +123,7 @@ class JSCoverage {
|
||||||
] as const);
|
] as const);
|
||||||
eventsHelper.removeEventListeners(this._eventListeners);
|
eventsHelper.removeEventListeners(this._eventListeners);
|
||||||
|
|
||||||
const coverage: types.JSCoverageEntry[] = [];
|
const coverage: channels.PageStopJSCoverageResult = { entries: [] };
|
||||||
for (const entry of profileResponse.result) {
|
for (const entry of profileResponse.result) {
|
||||||
if (!this._scriptIds.has(entry.scriptId))
|
if (!this._scriptIds.has(entry.scriptId))
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -131,9 +131,9 @@ class JSCoverage {
|
||||||
continue;
|
continue;
|
||||||
const source = this._scriptSources.get(entry.scriptId);
|
const source = this._scriptSources.get(entry.scriptId);
|
||||||
if (source)
|
if (source)
|
||||||
coverage.push({ ...entry, source });
|
coverage.entries.push({ ...entry, source });
|
||||||
else
|
else
|
||||||
coverage.push(entry);
|
coverage.entries.push(entry);
|
||||||
}
|
}
|
||||||
return coverage;
|
return coverage;
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +156,7 @@ class CSSCoverage {
|
||||||
this._resetOnNavigation = false;
|
this._resetOnNavigation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(options: types.CSSCoverageOptions = {}) {
|
async start(options: channels.PageStartCSSCoverageParams) {
|
||||||
assert(!this._enabled, 'CSSCoverage is already enabled');
|
assert(!this._enabled, 'CSSCoverage is already enabled');
|
||||||
const { resetOnNavigation = true } = options;
|
const { resetOnNavigation = true } = options;
|
||||||
this._resetOnNavigation = resetOnNavigation;
|
this._resetOnNavigation = resetOnNavigation;
|
||||||
|
|
@ -194,7 +194,7 @@ class CSSCoverage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop(): Promise<types.CSSCoverageEntry[]> {
|
async stop(): Promise<channels.PageStopCSSCoverageResult> {
|
||||||
assert(this._enabled, 'CSSCoverage is not enabled');
|
assert(this._enabled, 'CSSCoverage is not enabled');
|
||||||
this._enabled = false;
|
this._enabled = false;
|
||||||
const ruleTrackingResponse = await this._client.send('CSS.stopRuleUsageTracking');
|
const ruleTrackingResponse = await this._client.send('CSS.stopRuleUsageTracking');
|
||||||
|
|
@ -219,12 +219,12 @@ class CSSCoverage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const coverage: types.CSSCoverageEntry[] = [];
|
const coverage: channels.PageStopCSSCoverageResult = { entries: [] };
|
||||||
for (const styleSheetId of this._stylesheetURLs.keys()) {
|
for (const styleSheetId of this._stylesheetURLs.keys()) {
|
||||||
const url = this._stylesheetURLs.get(styleSheetId)!;
|
const url = this._stylesheetURLs.get(styleSheetId)!;
|
||||||
const text = this._stylesheetSources.get(styleSheetId)!;
|
const text = this._stylesheetSources.get(styleSheetId)!;
|
||||||
const ranges = convertToDisjointRanges(styleSheetIdToCoverage.get(styleSheetId) || []);
|
const ranges = convertToDisjointRanges(styleSheetIdToCoverage.get(styleSheetId) || []);
|
||||||
coverage.push({ url, ranges, text });
|
coverage.entries.push({ url, ranges, text });
|
||||||
}
|
}
|
||||||
|
|
||||||
return coverage;
|
return coverage;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import type { PageBinding, PageDelegate } from '../page';
|
||||||
import { Page, Worker } from '../page';
|
import { Page, Worker } from '../page';
|
||||||
import type { Progress } from '../progress';
|
import type { Progress } from '../progress';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
import type * as channels from '../../protocol/channels';
|
||||||
import { getAccessibilityTree } from './crAccessibility';
|
import { getAccessibilityTree } from './crAccessibility';
|
||||||
import { CRBrowserContext } from './crBrowser';
|
import { CRBrowserContext } from './crBrowser';
|
||||||
import type { CRSession } from './crConnection';
|
import type { CRSession } from './crConnection';
|
||||||
|
|
@ -356,7 +357,7 @@ export class CRPage implements PageDelegate {
|
||||||
await this._mainFrameSession._client.send('Page.enable').catch(e => {});
|
await this._mainFrameSession._client.send('Page.enable').catch(e => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
async pdf(options?: types.PDFOptions): Promise<Buffer> {
|
async pdf(options: channels.PagePdfParams): Promise<Buffer> {
|
||||||
return this._pdf.generate(options);
|
return this._pdf.generate(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { assert } from '../../utils';
|
import { assert } from '../../utils';
|
||||||
import type * as types from '../types';
|
import type * as channels from '../../protocol/channels';
|
||||||
import type { CRSession } from './crConnection';
|
import type { CRSession } from './crConnection';
|
||||||
import { readProtocolStream } from './crProtocolHelper';
|
import { readProtocolStream } from './crProtocolHelper';
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ export class CRPDF {
|
||||||
this._client = client;
|
this._client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
async generate(options: types.PDFOptions = {}): Promise<Buffer> {
|
async generate(options: channels.PagePdfParams): Promise<Buffer> {
|
||||||
const {
|
const {
|
||||||
scale = 1,
|
scale = 1,
|
||||||
displayHeaderFooter = false,
|
displayHeaderFooter = false,
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as types from './types';
|
import type * as channels from '../protocol/channels';
|
||||||
|
|
||||||
class Cookie {
|
class Cookie {
|
||||||
private _raw: types.NetworkCookie;
|
private _raw: channels.NetworkCookie;
|
||||||
constructor(data: types.NetworkCookie) {
|
constructor(data: channels.NetworkCookie) {
|
||||||
this._raw = data;
|
this._raw = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ class Cookie {
|
||||||
this._raw.path === other._raw.path;
|
this._raw.path === other._raw.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
networkCookie(): types.NetworkCookie {
|
networkCookie(): channels.NetworkCookie {
|
||||||
return this._raw;
|
return this._raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,12 +61,12 @@ class Cookie {
|
||||||
export class CookieStore {
|
export class CookieStore {
|
||||||
private readonly _nameToCookies: Map<string, Set<Cookie>> = new Map();
|
private readonly _nameToCookies: Map<string, Set<Cookie>> = new Map();
|
||||||
|
|
||||||
addCookies(cookies: types.NetworkCookie[]) {
|
addCookies(cookies: channels.NetworkCookie[]) {
|
||||||
for (const cookie of cookies)
|
for (const cookie of cookies)
|
||||||
this._addCookie(new Cookie(cookie));
|
this._addCookie(new Cookie(cookie));
|
||||||
}
|
}
|
||||||
|
|
||||||
cookies(url: URL): types.NetworkCookie[] {
|
cookies(url: URL): channels.NetworkCookie[] {
|
||||||
const result = [];
|
const result = [];
|
||||||
for (const cookie of this._cookiesIterator()) {
|
for (const cookie of this._cookiesIterator()) {
|
||||||
if (cookie.matches(url))
|
if (cookie.matches(url))
|
||||||
|
|
@ -75,7 +75,7 @@ export class CookieStore {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
allCookies(): types.NetworkCookie[] {
|
allCookies(): channels.NetworkCookie[] {
|
||||||
const result = [];
|
const result = [];
|
||||||
for (const cookie of this._cookiesIterator())
|
for (const cookie of this._cookiesIterator())
|
||||||
result.push(cookie.networkCookie());
|
result.push(cookie.networkCookie());
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel> imple
|
||||||
|
|
||||||
async stopJSCoverage(params: channels.PageStopJSCoverageParams, metadata: CallMetadata): Promise<channels.PageStopJSCoverageResult> {
|
async stopJSCoverage(params: channels.PageStopJSCoverageParams, metadata: CallMetadata): Promise<channels.PageStopJSCoverageResult> {
|
||||||
const coverage = this._page.coverage as CRCoverage;
|
const coverage = this._page.coverage as CRCoverage;
|
||||||
return { entries: await coverage.stopJSCoverage() };
|
return await coverage.stopJSCoverage();
|
||||||
}
|
}
|
||||||
|
|
||||||
async startCSSCoverage(params: channels.PageStartCSSCoverageParams, metadata: CallMetadata): Promise<void> {
|
async startCSSCoverage(params: channels.PageStartCSSCoverageParams, metadata: CallMetadata): Promise<void> {
|
||||||
|
|
@ -284,7 +284,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel> imple
|
||||||
|
|
||||||
async stopCSSCoverage(params: channels.PageStopCSSCoverageParams, metadata: CallMetadata): Promise<channels.PageStopCSSCoverageResult> {
|
async stopCSSCoverage(params: channels.PageStopCSSCoverageParams, metadata: CallMetadata): Promise<channels.PageStopCSSCoverageResult> {
|
||||||
const coverage = this._page.coverage as CRCoverage;
|
const coverage = this._page.coverage as CRCoverage;
|
||||||
return { entries: await coverage.stopCSSCoverage() };
|
return await coverage.stopCSSCoverage();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onFrameAttached(frame: Frame) {
|
_onFrameAttached(frame: Frame) {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ import * as readline from 'readline';
|
||||||
import { RecentLogsCollector } from '../../common/debugLogger';
|
import { RecentLogsCollector } from '../../common/debugLogger';
|
||||||
import { serverSideCallMetadata, SdkObject } from '../instrumentation';
|
import { serverSideCallMetadata, SdkObject } from '../instrumentation';
|
||||||
import type * as channels from '../../protocol/channels';
|
import type * as channels from '../../protocol/channels';
|
||||||
import type { BrowserContextOptions } from '../types';
|
|
||||||
|
|
||||||
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||||
|
|
||||||
|
|
@ -211,7 +210,7 @@ export class Electron extends SdkObject {
|
||||||
close: gracefullyClose,
|
close: gracefullyClose,
|
||||||
kill
|
kill
|
||||||
};
|
};
|
||||||
const contextOptions: BrowserContextOptions = {
|
const contextOptions: channels.BrowserNewContextParams = {
|
||||||
...options,
|
...options,
|
||||||
noDefaultViewport: true,
|
noDefaultViewport: true,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ export type APIRequestEvent = {
|
||||||
url: URL,
|
url: URL,
|
||||||
method: string,
|
method: string,
|
||||||
headers: { [name: string]: string },
|
headers: { [name: string]: string },
|
||||||
cookies: types.NameValueList,
|
cookies: channels.NameValue[],
|
||||||
postData?: Buffer
|
postData?: Buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ export type APIRequestFinishedEvent = {
|
||||||
requestEvent: APIRequestEvent,
|
requestEvent: APIRequestEvent,
|
||||||
httpVersion: string;
|
httpVersion: string;
|
||||||
headers: http.IncomingHttpHeaders;
|
headers: http.IncomingHttpHeaders;
|
||||||
cookies: types.NetworkCookie[];
|
cookies: channels.NetworkCookie[];
|
||||||
rawHeaders: string[];
|
rawHeaders: string[];
|
||||||
statusCode: number;
|
statusCode: number;
|
||||||
statusMessage: string;
|
statusMessage: string;
|
||||||
|
|
@ -110,8 +110,8 @@ export abstract class APIRequestContext extends SdkObject {
|
||||||
abstract dispose(): Promise<void>;
|
abstract dispose(): Promise<void>;
|
||||||
|
|
||||||
abstract _defaultOptions(): FetchRequestOptions;
|
abstract _defaultOptions(): FetchRequestOptions;
|
||||||
abstract _addCookies(cookies: types.NetworkCookie[]): Promise<void>;
|
abstract _addCookies(cookies: channels.NetworkCookie[]): Promise<void>;
|
||||||
abstract _cookies(url: URL): Promise<types.NetworkCookie[]>;
|
abstract _cookies(url: URL): Promise<channels.NetworkCookie[]>;
|
||||||
abstract storageState(): Promise<channels.APIRequestContextStorageStateResult>;
|
abstract storageState(): Promise<channels.APIRequestContextStorageStateResult>;
|
||||||
|
|
||||||
private _storeResponseBody(body: Buffer): string {
|
private _storeResponseBody(body: Buffer): string {
|
||||||
|
|
@ -120,7 +120,7 @@ export abstract class APIRequestContext extends SdkObject {
|
||||||
return uid;
|
return uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch(params: channels.APIRequestContextFetchParams, metadata: CallMetadata): Promise<Omit<types.APIResponse, 'body'> & { fetchUid: string }> {
|
async fetch(params: channels.APIRequestContextFetchParams, metadata: CallMetadata): Promise<channels.APIResponse> {
|
||||||
const headers: { [name: string]: string } = {};
|
const headers: { [name: string]: string } = {};
|
||||||
const defaults = this._defaultOptions();
|
const defaults = this._defaultOptions();
|
||||||
headers['user-agent'] = defaults.userAgent;
|
headers['user-agent'] = defaults.userAgent;
|
||||||
|
|
@ -194,16 +194,16 @@ export abstract class APIRequestContext extends SdkObject {
|
||||||
return { ...fetchResponse, fetchUid };
|
return { ...fetchResponse, fetchUid };
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseSetCookieHeader(responseUrl: string, setCookie: string[] | undefined): types.NetworkCookie[] {
|
private _parseSetCookieHeader(responseUrl: string, setCookie: string[] | undefined): channels.NetworkCookie[] {
|
||||||
if (!setCookie)
|
if (!setCookie)
|
||||||
return [];
|
return [];
|
||||||
const url = new URL(responseUrl);
|
const url = new URL(responseUrl);
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
|
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
|
||||||
const defaultPath = '/' + url.pathname.substr(1).split('/').slice(0, -1).join('/');
|
const defaultPath = '/' + url.pathname.substr(1).split('/').slice(0, -1).join('/');
|
||||||
const cookies: types.NetworkCookie[] = [];
|
const cookies: channels.NetworkCookie[] = [];
|
||||||
for (const header of setCookie) {
|
for (const header of setCookie) {
|
||||||
// Decode cookie value?
|
// Decode cookie value?
|
||||||
const cookie: types.NetworkCookie | null = parseCookie(header);
|
const cookie: channels.NetworkCookie | null = parseCookie(header);
|
||||||
if (!cookie)
|
if (!cookie)
|
||||||
continue;
|
continue;
|
||||||
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3
|
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3
|
||||||
|
|
@ -231,7 +231,7 @@ export abstract class APIRequestContext extends SdkObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _sendRequest(progress: Progress, url: URL, options: https.RequestOptions & { maxRedirects: number, deadline: number }, postData?: Buffer): Promise<types.APIResponse>{
|
private async _sendRequest(progress: Progress, url: URL, options: https.RequestOptions & { maxRedirects: number, deadline: number }, postData?: Buffer): Promise<Omit<channels.APIResponse, 'fetchUid'> & { body: Buffer }>{
|
||||||
await this._updateRequestCookieHeader(url, options);
|
await this._updateRequestCookieHeader(url, options);
|
||||||
|
|
||||||
const requestCookies = (options.headers!['cookie'] as (string | undefined))?.split(';').map(p => {
|
const requestCookies = (options.headers!['cookie'] as (string | undefined))?.split(';').map(p => {
|
||||||
|
|
@ -247,7 +247,7 @@ export abstract class APIRequestContext extends SdkObject {
|
||||||
};
|
};
|
||||||
this.emit(APIRequestContext.Events.Request, requestEvent);
|
this.emit(APIRequestContext.Events.Request, requestEvent);
|
||||||
|
|
||||||
return new Promise<types.APIResponse>((fulfill, reject) => {
|
return new Promise((fulfill, reject) => {
|
||||||
const requestConstructor: ((url: URL, options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void) => http.ClientRequest)
|
const requestConstructor: ((url: URL, options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void) => http.ClientRequest)
|
||||||
= (url.protocol === 'https:' ? https : http).request;
|
= (url.protocol === 'https:' ? https : http).request;
|
||||||
const request = requestConstructor(url, options, async response => {
|
const request = requestConstructor(url, options, async response => {
|
||||||
|
|
@ -455,11 +455,11 @@ export class BrowserContextAPIRequestContext extends APIRequestContext {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async _addCookies(cookies: types.NetworkCookie[]): Promise<void> {
|
async _addCookies(cookies: channels.NetworkCookie[]): Promise<void> {
|
||||||
await this._context.addCookies(cookies);
|
await this._context.addCookies(cookies);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _cookies(url: URL): Promise<types.NetworkCookie[]> {
|
async _cookies(url: URL): Promise<channels.NetworkCookie[]> {
|
||||||
return await this._context.cookies(url.toString());
|
return await this._context.cookies(url.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -519,11 +519,11 @@ export class GlobalAPIRequestContext extends APIRequestContext {
|
||||||
return this._options;
|
return this._options;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _addCookies(cookies: types.NetworkCookie[]): Promise<void> {
|
async _addCookies(cookies: channels.NetworkCookie[]): Promise<void> {
|
||||||
this._cookieStore.addCookies(cookies);
|
this._cookieStore.addCookies(cookies);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _cookies(url: URL): Promise<types.NetworkCookie[]> {
|
async _cookies(url: URL): Promise<channels.NetworkCookie[]> {
|
||||||
return this._cookieStore.cookies(url);
|
return this._cookieStore.cookies(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -544,7 +544,7 @@ function toHeadersArray(rawHeaders: string[]): types.HeadersArray {
|
||||||
|
|
||||||
const redirectStatus = [301, 302, 303, 307, 308];
|
const redirectStatus = [301, 302, 303, 307, 308];
|
||||||
|
|
||||||
function parseCookie(header: string): types.NetworkCookie | null {
|
function parseCookie(header: string): channels.NetworkCookie | null {
|
||||||
const pairs = header.split(';').filter(s => s.trim().length > 0).map(p => {
|
const pairs = header.split(';').filter(s => s.trim().length > 0).map(p => {
|
||||||
let key = '';
|
let key = '';
|
||||||
let value = '';
|
let value = '';
|
||||||
|
|
@ -563,7 +563,7 @@ function parseCookie(header: string): types.NetworkCookie | null {
|
||||||
if (!pairs.length)
|
if (!pairs.length)
|
||||||
return null;
|
return null;
|
||||||
const [name, value] = pairs[0];
|
const [name, value] = pairs[0];
|
||||||
const cookie: types.NetworkCookie = {
|
const cookie: channels.NetworkCookie = {
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
domain: '',
|
domain: '',
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import type * as accessibility from '../accessibility';
|
||||||
import type { FFSession } from './ffConnection';
|
import type { FFSession } from './ffConnection';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type * as dom from '../dom';
|
import type * as dom from '../dom';
|
||||||
import type * as types from '../types';
|
import type * as channels from '../../protocol/channels';
|
||||||
|
|
||||||
export async function getAccessibilityTree(session: FFSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
export async function getAccessibilityTree(session: FFSession, needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}> {
|
||||||
const objectId = needle ? needle._objectId : undefined;
|
const objectId = needle ? needle._objectId : undefined;
|
||||||
|
|
@ -198,12 +198,12 @@ class FFAXNode implements accessibility.AXNode {
|
||||||
return this.isLeafNode() && !!this._name.trim();
|
return this.isLeafNode() && !!this._name.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(): types.SerializedAXNode {
|
serialize(): channels.AXNode {
|
||||||
const node: {[x in keyof types.SerializedAXNode]: any} = {
|
const node: {[x in keyof channels.AXNode]: any} = {
|
||||||
role: FFRoleToARIARole.get(this._role) || this._role,
|
role: FFRoleToARIARole.get(this._role) || this._role,
|
||||||
name: this._name || '',
|
name: this._name || '',
|
||||||
};
|
};
|
||||||
const userStringProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Accessibility.AXTree> = [
|
const userStringProperties: Array<keyof channels.AXNode & keyof Protocol.Accessibility.AXTree> = [
|
||||||
'name',
|
'name',
|
||||||
'description',
|
'description',
|
||||||
'roledescription',
|
'roledescription',
|
||||||
|
|
@ -215,7 +215,7 @@ class FFAXNode implements accessibility.AXNode {
|
||||||
continue;
|
continue;
|
||||||
node[userStringProperty] = this._payload[userStringProperty];
|
node[userStringProperty] = this._payload[userStringProperty];
|
||||||
}
|
}
|
||||||
const booleanProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Accessibility.AXTree> = [
|
const booleanProperties: Array<keyof channels.AXNode & keyof Protocol.Accessibility.AXTree> = [
|
||||||
'disabled',
|
'disabled',
|
||||||
'expanded',
|
'expanded',
|
||||||
'focused',
|
'focused',
|
||||||
|
|
@ -234,7 +234,7 @@ class FFAXNode implements accessibility.AXNode {
|
||||||
continue;
|
continue;
|
||||||
node[booleanProperty] = value;
|
node[booleanProperty] = value;
|
||||||
}
|
}
|
||||||
const numericalProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Accessibility.AXTree> = [
|
const numericalProperties: Array<keyof channels.AXNode & keyof Protocol.Accessibility.AXTree> = [
|
||||||
'level'
|
'level'
|
||||||
];
|
];
|
||||||
for (const numericalProperty of numericalProperties) {
|
for (const numericalProperty of numericalProperties) {
|
||||||
|
|
@ -242,7 +242,7 @@ class FFAXNode implements accessibility.AXNode {
|
||||||
continue;
|
continue;
|
||||||
node[numericalProperty] = this._payload[numericalProperty];
|
node[numericalProperty] = this._payload[numericalProperty];
|
||||||
}
|
}
|
||||||
const tokenProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Accessibility.AXTree> = [
|
const tokenProperties: Array<keyof channels.AXNode & keyof Protocol.Accessibility.AXTree> = [
|
||||||
'autocomplete',
|
'autocomplete',
|
||||||
'haspopup',
|
'haspopup',
|
||||||
'invalid',
|
'invalid',
|
||||||
|
|
@ -255,7 +255,7 @@ class FFAXNode implements accessibility.AXNode {
|
||||||
node[tokenProperty] = value;
|
node[tokenProperty] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const axNode = node as types.SerializedAXNode;
|
const axNode = node as channels.AXNode;
|
||||||
axNode.valueString = this._payload.value;
|
axNode.valueString = this._payload.value;
|
||||||
if ('checked' in this._payload)
|
if ('checked' in this._payload)
|
||||||
axNode.checked = this._payload.checked === true ? 'checked' : this._payload.checked === 'mixed' ? 'mixed' : 'unchecked';
|
axNode.checked = this._payload.checked === true ? 'checked' : this._payload.checked === 'mixed' ? 'mixed' : 'unchecked';
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import * as network from '../network';
|
||||||
import type { Page, PageBinding, PageDelegate } from '../page';
|
import type { Page, PageBinding, PageDelegate } from '../page';
|
||||||
import type { ConnectionTransport } from '../transport';
|
import type { ConnectionTransport } from '../transport';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
import type * as channels from '../../protocol/channels';
|
||||||
import { ConnectionEvents, FFConnection } from './ffConnection';
|
import { ConnectionEvents, FFConnection } from './ffConnection';
|
||||||
import { FFPage } from './ffPage';
|
import { FFPage } from './ffPage';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
|
|
@ -77,7 +78,7 @@ export class FFBrowser extends Browser {
|
||||||
return !this._connection._closed;
|
return !this._connection._closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
async doCreateNewContext(options: types.BrowserContextOptions): Promise<BrowserContext> {
|
async doCreateNewContext(options: channels.BrowserNewContextParams): Promise<BrowserContext> {
|
||||||
if (options.isMobile)
|
if (options.isMobile)
|
||||||
throw new Error('options.isMobile is not supported in Firefox');
|
throw new Error('options.isMobile is not supported in Firefox');
|
||||||
const { browserContextId } = await this._connection.send('Browser.createBrowserContext', { removeOnDetach: true });
|
const { browserContextId } = await this._connection.send('Browser.createBrowserContext', { removeOnDetach: true });
|
||||||
|
|
@ -155,7 +156,7 @@ export class FFBrowser extends Browser {
|
||||||
export class FFBrowserContext extends BrowserContext {
|
export class FFBrowserContext extends BrowserContext {
|
||||||
declare readonly _browser: FFBrowser;
|
declare readonly _browser: FFBrowser;
|
||||||
|
|
||||||
constructor(browser: FFBrowser, browserContextId: string | undefined, options: types.BrowserContextOptions) {
|
constructor(browser: FFBrowser, browserContextId: string | undefined, options: channels.BrowserNewContextParams) {
|
||||||
super(browser, options, browserContextId);
|
super(browser, options, browserContextId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,17 +256,17 @@ export class FFBrowserContext extends BrowserContext {
|
||||||
return this._browser._ffPages.get(targetId)!;
|
return this._browser._ffPages.get(targetId)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
async doGetCookies(urls: string[]): Promise<types.NetworkCookie[]> {
|
async doGetCookies(urls: string[]): Promise<channels.NetworkCookie[]> {
|
||||||
const { cookies } = await this._browser._connection.send('Browser.getCookies', { browserContextId: this._browserContextId });
|
const { cookies } = await this._browser._connection.send('Browser.getCookies', { browserContextId: this._browserContextId });
|
||||||
return network.filterCookies(cookies.map(c => {
|
return network.filterCookies(cookies.map(c => {
|
||||||
const copy: any = { ... c };
|
const copy: any = { ... c };
|
||||||
delete copy.size;
|
delete copy.size;
|
||||||
delete copy.session;
|
delete copy.session;
|
||||||
return copy as types.NetworkCookie;
|
return copy as channels.NetworkCookie;
|
||||||
}), urls);
|
}), urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addCookies(cookies: types.SetNetworkCookieParam[]) {
|
async addCookies(cookies: channels.SetNetworkCookie[]) {
|
||||||
const cc = network.rewriteCookies(cookies).map(c => ({
|
const cc = network.rewriteCookies(cookies).map(c => ({
|
||||||
...c,
|
...c,
|
||||||
expires: c.expires && c.expires !== -1 ? c.expires : undefined,
|
expires: c.expires && c.expires !== -1 ? c.expires : undefined,
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,16 @@ import { Artifact } from '../artifact';
|
||||||
import type { BrowserContext } from '../browserContext';
|
import type { BrowserContext } from '../browserContext';
|
||||||
import type * as har from './har';
|
import type * as har from './har';
|
||||||
import { HarTracer } from './harTracer';
|
import { HarTracer } from './harTracer';
|
||||||
import type { HarOptions } from '../types';
|
import type * as channels from '../../protocol/channels';
|
||||||
|
|
||||||
export class HarRecorder {
|
export class HarRecorder {
|
||||||
private _artifact: Artifact;
|
private _artifact: Artifact;
|
||||||
private _isFlushed: boolean = false;
|
private _isFlushed: boolean = false;
|
||||||
private _options: HarOptions;
|
private _options: channels.RecordHarOptions;
|
||||||
private _tracer: HarTracer;
|
private _tracer: HarTracer;
|
||||||
private _entries: har.Entry[] = [];
|
private _entries: har.Entry[] = [];
|
||||||
|
|
||||||
constructor(context: BrowserContext | APIRequestContext, options: HarOptions) {
|
constructor(context: BrowserContext | APIRequestContext, options: channels.RecordHarOptions) {
|
||||||
this._artifact = new Artifact(context, options.path);
|
this._artifact = new Artifact(context, options.path);
|
||||||
this._options = options;
|
this._options = options;
|
||||||
const urlFilterRe = options.urlRegexSource !== undefined && options.urlRegexFlags !== undefined ? new RegExp(options.urlRegexSource, options.urlRegexFlags) : undefined;
|
const urlFilterRe = options.urlRegexSource !== undefined && options.urlRegexFlags !== undefined ? new RegExp(options.urlRegexSource, options.urlRegexFlags) : undefined;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { SdkObject } from './instrumentation';
|
||||||
import type { NameValue } from '../common/types';
|
import type { NameValue } from '../common/types';
|
||||||
import { APIRequestContext } from './fetch';
|
import { APIRequestContext } from './fetch';
|
||||||
|
|
||||||
export function filterCookies(cookies: types.NetworkCookie[], urls: string[]): types.NetworkCookie[] {
|
export function filterCookies(cookies: channels.NetworkCookie[], urls: string[]): channels.NetworkCookie[] {
|
||||||
const parsedURLs = urls.map(s => new URL(s));
|
const parsedURLs = urls.map(s => new URL(s));
|
||||||
// Chromiums's cookies are missing sameSite when it is 'None'
|
// Chromiums's cookies are missing sameSite when it is 'None'
|
||||||
return cookies.filter(c => {
|
return cookies.filter(c => {
|
||||||
|
|
@ -50,7 +50,7 @@ export function filterCookies(cookies: types.NetworkCookie[], urls: string[]): t
|
||||||
// 253402300800 == Sat, 1 Jan 1000 00:00:00 +0000 (UTC)
|
// 253402300800 == Sat, 1 Jan 1000 00:00:00 +0000 (UTC)
|
||||||
const kMaxCookieExpiresDateInSeconds = 253402300799;
|
const kMaxCookieExpiresDateInSeconds = 253402300799;
|
||||||
|
|
||||||
export function rewriteCookies(cookies: types.SetNetworkCookieParam[]): types.SetNetworkCookieParam[] {
|
export function rewriteCookies(cookies: channels.SetNetworkCookie[]): channels.SetNetworkCookie[] {
|
||||||
return cookies.map(c => {
|
return cookies.map(c => {
|
||||||
assert(c.url || (c.domain && c.path), 'Cookie should have a url or a domain/path pair');
|
assert(c.url || (c.domain && c.path), 'Cookie should have a url or a domain/path pair');
|
||||||
assert(!(c.url && c.domain), 'Cookie should have either url or domain');
|
assert(!(c.url && c.domain), 'Cookie should have either url or domain');
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import * as frames from './frames';
|
||||||
import * as input from './input';
|
import * as input from './input';
|
||||||
import * as js from './javascript';
|
import * as js from './javascript';
|
||||||
import * as network from './network';
|
import * as network from './network';
|
||||||
|
import type * as channels from '../protocol/channels';
|
||||||
import type { ScreenshotOptions } from './screenshotter';
|
import type { ScreenshotOptions } from './screenshotter';
|
||||||
import { Screenshotter, validateScreenshotOptions } from './screenshotter';
|
import { Screenshotter, validateScreenshotOptions } from './screenshotter';
|
||||||
import { TimeoutSettings } from '../common/timeoutSettings';
|
import { TimeoutSettings } from '../common/timeoutSettings';
|
||||||
|
|
@ -86,7 +87,7 @@ export interface PageDelegate {
|
||||||
setScreencastOptions(options: { width: number, height: number, quality: number } | null): Promise<void>;
|
setScreencastOptions(options: { width: number, height: number, quality: number } | null): Promise<void>;
|
||||||
|
|
||||||
getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}>;
|
getAccessibilityTree(needle?: dom.ElementHandle): Promise<{tree: accessibility.AXNode, needle: accessibility.AXNode | null}>;
|
||||||
pdf?: (options?: types.PDFOptions) => Promise<Buffer>;
|
pdf?: (options: channels.PagePdfParams) => Promise<Buffer>;
|
||||||
coverage?: () => any;
|
coverage?: () => any;
|
||||||
|
|
||||||
// Work around WebKit's raf issues on Windows.
|
// Work around WebKit's raf issues on Windows.
|
||||||
|
|
@ -160,7 +161,7 @@ export class Page extends SdkObject {
|
||||||
readonly _frameManager: frames.FrameManager;
|
readonly _frameManager: frames.FrameManager;
|
||||||
readonly accessibility: accessibility.Accessibility;
|
readonly accessibility: accessibility.Accessibility;
|
||||||
private _workers = new Map<string, Worker>();
|
private _workers = new Map<string, Worker>();
|
||||||
readonly pdf: ((options?: types.PDFOptions) => Promise<Buffer>) | undefined;
|
readonly pdf: ((options: channels.PagePdfParams) => Promise<Buffer>) | undefined;
|
||||||
readonly coverage: any;
|
readonly coverage: any;
|
||||||
private _clientRequestInterceptor: network.RouteHandler | undefined;
|
private _clientRequestInterceptor: network.RouteHandler | undefined;
|
||||||
private _serverRequestInterceptor: network.RouteHandler | undefined;
|
private _serverRequestInterceptor: network.RouteHandler | undefined;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
import type { Size, Point, TimeoutOptions } from '../common/types';
|
import type { Size, Point, TimeoutOptions } from '../common/types';
|
||||||
export type { Size, Point, Rect, Quad, URLMatch, TimeoutOptions } from '../common/types';
|
export type { Size, Point, Rect, Quad, URLMatch, TimeoutOptions } from '../common/types';
|
||||||
|
import type * as channels from '../protocol/channels';
|
||||||
|
|
||||||
export type StrictOptions = {
|
export type StrictOptions = {
|
||||||
strict?: boolean,
|
strict?: boolean,
|
||||||
|
|
@ -77,16 +78,12 @@ export type FilePayload = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MediaType = 'screen' | 'print';
|
export type MediaType = 'screen' | 'print';
|
||||||
export const mediaTypes: Set<MediaType> = new Set(['screen', 'print']);
|
|
||||||
|
|
||||||
export type ColorScheme = 'dark' | 'light' | 'no-preference';
|
export type ColorScheme = 'dark' | 'light' | 'no-preference';
|
||||||
export const colorSchemes: Set<ColorScheme> = new Set(['dark', 'light', 'no-preference']);
|
|
||||||
|
|
||||||
export type ReducedMotion = 'no-preference' | 'reduce';
|
export type ReducedMotion = 'no-preference' | 'reduce';
|
||||||
export const reducedMotions: Set<ReducedMotion> = new Set(['no-preference', 'reduce']);
|
|
||||||
|
|
||||||
export type ForcedColors = 'active' | 'none';
|
export type ForcedColors = 'active' | 'none';
|
||||||
export const forcedColors: Set<ForcedColors> = new Set(['active', 'none']);
|
|
||||||
|
|
||||||
export type DeviceDescriptor = {
|
export type DeviceDescriptor = {
|
||||||
userAgent: string,
|
userAgent: string,
|
||||||
|
|
@ -98,56 +95,6 @@ export type DeviceDescriptor = {
|
||||||
};
|
};
|
||||||
export type Devices = { [name: string]: DeviceDescriptor };
|
export type Devices = { [name: string]: DeviceDescriptor };
|
||||||
|
|
||||||
export type PDFOptions = {
|
|
||||||
scale?: number,
|
|
||||||
displayHeaderFooter?: boolean,
|
|
||||||
headerTemplate?: string,
|
|
||||||
footerTemplate?: string,
|
|
||||||
printBackground?: boolean,
|
|
||||||
landscape?: boolean,
|
|
||||||
pageRanges?: string,
|
|
||||||
format?: string,
|
|
||||||
width?: string,
|
|
||||||
height?: string,
|
|
||||||
preferCSSPageSize?: boolean,
|
|
||||||
margin?: {top?: string, bottom?: string, left?: string, right?: string},
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CSSCoverageOptions = {
|
|
||||||
resetOnNavigation?: boolean,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type JSCoverageOptions = {
|
|
||||||
resetOnNavigation?: boolean,
|
|
||||||
reportAnonymousScripts?: boolean,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type JSRange = {
|
|
||||||
startOffset: number,
|
|
||||||
endOffset: number,
|
|
||||||
count: number
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CSSCoverageEntry = {
|
|
||||||
url: string,
|
|
||||||
text?: string,
|
|
||||||
ranges: {
|
|
||||||
start: number,
|
|
||||||
end: number
|
|
||||||
}[]
|
|
||||||
};
|
|
||||||
|
|
||||||
export type JSCoverageEntry = {
|
|
||||||
url: string,
|
|
||||||
scriptId: string,
|
|
||||||
source?: string,
|
|
||||||
functions: {
|
|
||||||
functionName: string,
|
|
||||||
isBlockCoverage: boolean,
|
|
||||||
ranges: JSRange[]
|
|
||||||
}[]
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ProxySettings = {
|
export type ProxySettings = {
|
||||||
server: string,
|
server: string,
|
||||||
bypass?: string,
|
bypass?: string,
|
||||||
|
|
@ -202,180 +149,14 @@ export type NormalizedContinueOverrides = {
|
||||||
postData?: Buffer,
|
postData?: Buffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NetworkCookie = {
|
|
||||||
name: string,
|
|
||||||
value: string,
|
|
||||||
domain: string,
|
|
||||||
path: string,
|
|
||||||
expires: number,
|
|
||||||
httpOnly: boolean,
|
|
||||||
secure: boolean,
|
|
||||||
sameSite: 'Strict' | 'Lax' | 'None'
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SetNetworkCookieParam = {
|
|
||||||
name: string,
|
|
||||||
value: string,
|
|
||||||
url?: string,
|
|
||||||
domain?: string,
|
|
||||||
path?: string,
|
|
||||||
expires?: number,
|
|
||||||
httpOnly?: boolean,
|
|
||||||
secure?: boolean,
|
|
||||||
sameSite?: 'Strict' | 'Lax' | 'None'
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EmulatedSize = { viewport: Size, screen: Size };
|
export type EmulatedSize = { viewport: Size, screen: Size };
|
||||||
|
|
||||||
export type HarOptions = {
|
export type LaunchOptions = channels.BrowserTypeLaunchOptions & { useWebSocket?: boolean };
|
||||||
omitContent?: boolean,
|
|
||||||
path: string,
|
|
||||||
urlGlob?: string,
|
|
||||||
urlRegexSource?: string,
|
|
||||||
urlRegexFlags?: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BrowserContextOptions = {
|
|
||||||
viewport?: Size,
|
|
||||||
screen?: Size,
|
|
||||||
noDefaultViewport?: boolean,
|
|
||||||
ignoreHTTPSErrors?: boolean,
|
|
||||||
javaScriptEnabled?: boolean,
|
|
||||||
bypassCSP?: boolean,
|
|
||||||
userAgent?: string,
|
|
||||||
locale?: string,
|
|
||||||
timezoneId?: string,
|
|
||||||
geolocation?: Geolocation,
|
|
||||||
permissions?: string[],
|
|
||||||
extraHTTPHeaders?: HeadersArray,
|
|
||||||
offline?: boolean,
|
|
||||||
httpCredentials?: Credentials,
|
|
||||||
deviceScaleFactor?: number,
|
|
||||||
isMobile?: boolean,
|
|
||||||
hasTouch?: boolean,
|
|
||||||
colorScheme?: ColorScheme,
|
|
||||||
reducedMotion?: ReducedMotion,
|
|
||||||
forcedColors?: ForcedColors,
|
|
||||||
acceptDownloads?: boolean,
|
|
||||||
recordVideo?: {
|
|
||||||
dir: string,
|
|
||||||
size?: Size,
|
|
||||||
},
|
|
||||||
recordHar?: HarOptions,
|
|
||||||
storageState?: SetStorageState,
|
|
||||||
strictSelectors?: boolean,
|
|
||||||
proxy?: ProxySettings,
|
|
||||||
baseURL?: string,
|
|
||||||
serviceWorkers?: 'allow' | 'block',
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EnvArray = { name: string, value: string }[];
|
|
||||||
|
|
||||||
type LaunchOptionsBase = {
|
|
||||||
channel?: string,
|
|
||||||
executablePath?: string,
|
|
||||||
args?: string[],
|
|
||||||
ignoreDefaultArgs?: string[],
|
|
||||||
ignoreAllDefaultArgs?: boolean,
|
|
||||||
handleSIGINT?: boolean,
|
|
||||||
handleSIGTERM?: boolean,
|
|
||||||
handleSIGHUP?: boolean,
|
|
||||||
timeout?: number,
|
|
||||||
env?: EnvArray,
|
|
||||||
headless?: boolean,
|
|
||||||
devtools?: boolean,
|
|
||||||
proxy?: ProxySettings,
|
|
||||||
downloadsPath?: string,
|
|
||||||
chromiumSandbox?: boolean,
|
|
||||||
slowMo?: number,
|
|
||||||
useWebSocket?: boolean,
|
|
||||||
tracesDir?: string,
|
|
||||||
};
|
|
||||||
export type LaunchOptions = LaunchOptionsBase & {
|
|
||||||
firefoxUserPrefs?: { [key: string]: string | number | boolean },
|
|
||||||
};
|
|
||||||
export type LaunchPersistentOptions = LaunchOptionsBase & BrowserContextOptions;
|
|
||||||
|
|
||||||
export type ProtocolLogger = (direction: 'send' | 'receive', message: object) => void;
|
export type ProtocolLogger = (direction: 'send' | 'receive', message: object) => void;
|
||||||
|
|
||||||
export type SerializedAXNode = {
|
|
||||||
role: string,
|
|
||||||
name: string,
|
|
||||||
valueString?: string,
|
|
||||||
valueNumber?: number,
|
|
||||||
description?: string,
|
|
||||||
|
|
||||||
keyshortcuts?: string,
|
|
||||||
roledescription?: string,
|
|
||||||
valuetext?: string,
|
|
||||||
|
|
||||||
disabled?: boolean,
|
|
||||||
expanded?: boolean,
|
|
||||||
focused?: boolean,
|
|
||||||
modal?: boolean,
|
|
||||||
multiline?: boolean,
|
|
||||||
multiselectable?: boolean,
|
|
||||||
readonly?: boolean,
|
|
||||||
required?: boolean,
|
|
||||||
selected?: boolean,
|
|
||||||
|
|
||||||
checked?: 'checked' | 'unchecked' | 'mixed',
|
|
||||||
pressed?: 'pressed' | 'released' | 'mixed',
|
|
||||||
|
|
||||||
level?: number,
|
|
||||||
valuemin?: number,
|
|
||||||
valuemax?: number,
|
|
||||||
|
|
||||||
autocomplete?: string,
|
|
||||||
haspopup?: string,
|
|
||||||
invalid?: string,
|
|
||||||
orientation?: string,
|
|
||||||
|
|
||||||
children?: SerializedAXNode[]
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ConsoleMessageLocation = {
|
export type ConsoleMessageLocation = {
|
||||||
url: string,
|
url: string,
|
||||||
lineNumber: number,
|
lineNumber: number,
|
||||||
columnNumber: number,
|
columnNumber: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Error = {
|
|
||||||
message: string,
|
|
||||||
name: string,
|
|
||||||
stack?: string,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NameValueList = {
|
|
||||||
name: string;
|
|
||||||
value: string;
|
|
||||||
}[];
|
|
||||||
|
|
||||||
export type OriginStorage = {
|
|
||||||
origin: string;
|
|
||||||
localStorage: NameValueList;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type StorageState = {
|
|
||||||
cookies: NetworkCookie[],
|
|
||||||
origins: OriginStorage[]
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SetStorageState = {
|
|
||||||
cookies?: SetNetworkCookieParam[],
|
|
||||||
origins?: OriginStorage[]
|
|
||||||
};
|
|
||||||
|
|
||||||
export type APIResponse = {
|
|
||||||
url: string,
|
|
||||||
status: number,
|
|
||||||
statusText: string,
|
|
||||||
headers: HeadersArray,
|
|
||||||
body: Buffer,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type AndroidDeviceOptions = {
|
|
||||||
host?: string,
|
|
||||||
port?: number,
|
|
||||||
omitDriverInstall?: boolean,
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import type * as accessibility from '../accessibility';
|
||||||
import type { WKSession } from './wkConnection';
|
import type { WKSession } from './wkConnection';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type * as dom from '../dom';
|
import type * as dom from '../dom';
|
||||||
import type * as types from '../types';
|
import type * as channels from '../../protocol/channels';
|
||||||
|
|
||||||
export async function getAccessibilityTree(session: WKSession, needle?: dom.ElementHandle) {
|
export async function getAccessibilityTree(session: WKSession, needle?: dom.ElementHandle) {
|
||||||
const objectId = needle ? needle._objectId : undefined;
|
const objectId = needle ? needle._objectId : undefined;
|
||||||
|
|
@ -167,8 +167,8 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
serialize(): types.SerializedAXNode {
|
serialize(): channels.AXNode {
|
||||||
const node: types.SerializedAXNode = {
|
const node: channels.AXNode = {
|
||||||
role: WKRoleToARIARole.get(this._payload.role) || this._payload.role,
|
role: WKRoleToARIARole.get(this._payload.role) || this._payload.role,
|
||||||
name: this._name(),
|
name: this._name(),
|
||||||
};
|
};
|
||||||
|
|
@ -195,7 +195,7 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
if ('pressed' in this._payload)
|
if ('pressed' in this._payload)
|
||||||
node.pressed = this._payload.pressed === 'true' ? 'pressed' : this._payload.pressed === 'false' ? 'released' : 'mixed';
|
node.pressed = this._payload.pressed === 'true' ? 'pressed' : this._payload.pressed === 'false' ? 'released' : 'mixed';
|
||||||
|
|
||||||
const userStringProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
const userStringProperties: Array<keyof channels.AXNode & keyof Protocol.Page.AXNode> = [
|
||||||
'keyshortcuts',
|
'keyshortcuts',
|
||||||
'valuetext'
|
'valuetext'
|
||||||
];
|
];
|
||||||
|
|
@ -205,7 +205,7 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
(node as any)[userStringProperty] = this._payload[userStringProperty];
|
(node as any)[userStringProperty] = this._payload[userStringProperty];
|
||||||
}
|
}
|
||||||
|
|
||||||
const booleanProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
const booleanProperties: Array<keyof channels.AXNode & keyof Protocol.Page.AXNode> = [
|
||||||
'disabled',
|
'disabled',
|
||||||
'expanded',
|
'expanded',
|
||||||
'focused',
|
'focused',
|
||||||
|
|
@ -227,7 +227,7 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
(node as any)[booleanProperty] = value;
|
(node as any)[booleanProperty] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numericalProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
const numericalProperties: Array<keyof channels.AXNode & keyof Protocol.Page.AXNode> = [
|
||||||
'level',
|
'level',
|
||||||
'valuemax',
|
'valuemax',
|
||||||
'valuemin',
|
'valuemin',
|
||||||
|
|
@ -237,7 +237,7 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
continue;
|
continue;
|
||||||
(node as any)[numericalProperty] = (this._payload as any)[numericalProperty];
|
(node as any)[numericalProperty] = (this._payload as any)[numericalProperty];
|
||||||
}
|
}
|
||||||
const tokenProperties: Array<keyof types.SerializedAXNode & keyof Protocol.Page.AXNode> = [
|
const tokenProperties: Array<keyof channels.AXNode & keyof Protocol.Page.AXNode> = [
|
||||||
'autocomplete',
|
'autocomplete',
|
||||||
'haspopup',
|
'haspopup',
|
||||||
'invalid',
|
'invalid',
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import * as network from '../network';
|
||||||
import type { Page, PageBinding, PageDelegate } from '../page';
|
import type { Page, PageBinding, PageDelegate } from '../page';
|
||||||
import type { ConnectionTransport } from '../transport';
|
import type { ConnectionTransport } from '../transport';
|
||||||
import type * as types from '../types';
|
import type * as types from '../types';
|
||||||
|
import type * as channels from '../../protocol/channels';
|
||||||
import type { Protocol } from './protocol';
|
import type { Protocol } from './protocol';
|
||||||
import type { PageProxyMessageReceivedPayload } from './wkConnection';
|
import type { PageProxyMessageReceivedPayload } from './wkConnection';
|
||||||
import { kPageProxyMessageReceived, WKConnection, WKSession } from './wkConnection';
|
import { kPageProxyMessageReceived, WKConnection, WKSession } from './wkConnection';
|
||||||
|
|
@ -82,7 +83,7 @@ export class WKBrowser extends Browser {
|
||||||
this._didClose();
|
this._didClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
async doCreateNewContext(options: types.BrowserContextOptions): Promise<BrowserContext> {
|
async doCreateNewContext(options: channels.BrowserNewContextParams): Promise<BrowserContext> {
|
||||||
const createOptions = options.proxy ? {
|
const createOptions = options.proxy ? {
|
||||||
proxyServer: options.proxy.server,
|
proxyServer: options.proxy.server,
|
||||||
proxyBypassList: options.proxy.bypass
|
proxyBypassList: options.proxy.bypass
|
||||||
|
|
@ -206,7 +207,7 @@ export class WKBrowser extends Browser {
|
||||||
export class WKBrowserContext extends BrowserContext {
|
export class WKBrowserContext extends BrowserContext {
|
||||||
declare readonly _browser: WKBrowser;
|
declare readonly _browser: WKBrowser;
|
||||||
|
|
||||||
constructor(browser: WKBrowser, browserContextId: string | undefined, options: types.BrowserContextOptions) {
|
constructor(browser: WKBrowser, browserContextId: string | undefined, options: channels.BrowserNewContextParams) {
|
||||||
super(browser, options, browserContextId);
|
super(browser, options, browserContextId);
|
||||||
this._authenticateProxyViaHeader();
|
this._authenticateProxyViaHeader();
|
||||||
}
|
}
|
||||||
|
|
@ -249,17 +250,17 @@ export class WKBrowserContext extends BrowserContext {
|
||||||
return this._browser._wkPages.get(pageProxyId)!;
|
return this._browser._wkPages.get(pageProxyId)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
async doGetCookies(urls: string[]): Promise<types.NetworkCookie[]> {
|
async doGetCookies(urls: string[]): Promise<channels.NetworkCookie[]> {
|
||||||
const { cookies } = await this._browser._browserSession.send('Playwright.getAllCookies', { browserContextId: this._browserContextId });
|
const { cookies } = await this._browser._browserSession.send('Playwright.getAllCookies', { browserContextId: this._browserContextId });
|
||||||
return network.filterCookies(cookies.map((c: types.NetworkCookie) => {
|
return network.filterCookies(cookies.map((c: channels.NetworkCookie) => {
|
||||||
const copy: any = { ... c };
|
const copy: any = { ... c };
|
||||||
copy.expires = c.expires === -1 ? -1 : c.expires / 1000;
|
copy.expires = c.expires === -1 ? -1 : c.expires / 1000;
|
||||||
delete copy.session;
|
delete copy.session;
|
||||||
return copy as types.NetworkCookie;
|
return copy as channels.NetworkCookie;
|
||||||
}), urls);
|
}), urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addCookies(cookies: types.SetNetworkCookieParam[]) {
|
async addCookies(cookies: channels.SetNetworkCookie[]) {
|
||||||
const cc = network.rewriteCookies(cookies).map(c => ({
|
const cc = network.rewriteCookies(cookies).map(c => ({
|
||||||
...c,
|
...c,
|
||||||
session: c.expires === -1 || c.expires === undefined,
|
session: c.expires === -1 || c.expires === undefined,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue