chore: make tracing zero config (#6859)
This commit is contained in:
parent
837ee08a53
commit
b2143a951b
|
|
@ -7,41 +7,40 @@ Playwright script runs.
|
||||||
Start with specifying the folder traces will be stored in:
|
Start with specifying the folder traces will be stored in:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const browser = await chromium.launch({ traceDir: 'traces' });
|
const browser = await chromium.launch();
|
||||||
const context = await browser.newContext();
|
const context = await browser.newContext();
|
||||||
await context.tracing.start({ name: 'trace', screenshots: true, snapshots: true });
|
await context.tracing.start({ screenshots: true, snapshots: true });
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
await page.goto('https://playwright.dev');
|
await page.goto('https://playwright.dev');
|
||||||
await context.tracing.stop({ path: 'trace.zip' });
|
await context.tracing.stop({ path: 'trace.zip' });
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
Browser browser = chromium.launch(new BrowserType.LaunchOptions().setTraceDir("trace"));
|
Browser browser = chromium.launch();
|
||||||
BrowserContext context = browser.newContext();
|
BrowserContext context = browser.newContext();
|
||||||
context.tracing.start(page, new Tracing.StartOptions()
|
context.tracing.start(page, new Tracing.StartOptions()
|
||||||
.setName("trace")
|
|
||||||
.setScreenshots(true)
|
.setScreenshots(true)
|
||||||
.setSnapshots(true);
|
.setSnapshots(true);
|
||||||
Page page = context.newPage();
|
Page page = context.newPage();
|
||||||
page.goto("https://playwright.dev");
|
page.goto("https://playwright.dev");
|
||||||
context.tracing.stop(new Tracing.StopOptions()
|
context.tracing.stop(new Tracing.StopOptions()
|
||||||
.setSaveAs(Paths.get("trace.zip")));
|
.setPath(Paths.get("trace.zip")));
|
||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
browser = await chromium.launch(traceDir='traces')
|
browser = await chromium.launch()
|
||||||
context = await browser.new_context()
|
context = await browser.new_context()
|
||||||
await context.tracing.start(name="trace", screenshots=True, snapshots=True)
|
await context.tracing.start(screenshots=True, snapshots=True)
|
||||||
await page.goto("https://playwright.dev")
|
await page.goto("https://playwright.dev")
|
||||||
await context.tracing.stop(save_as = "trace.zip")
|
await context.tracing.stop(path = "trace.zip")
|
||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
browser = chromium.launch(traceDir='traces')
|
browser = chromium.launch()
|
||||||
context = browser.new_context()
|
context = browser.new_context()
|
||||||
context.tracing.start(name="trace", screenshots=True, snapshots=True)
|
context.tracing.start(screenshots=True, snapshots=True)
|
||||||
page.goto("https://playwright.dev")
|
page.goto("https://playwright.dev")
|
||||||
context.tracing.stop(save_as = "trace.zip")
|
context.tracing.stop(path = "trace.zip")
|
||||||
```
|
```
|
||||||
|
|
||||||
## async method: Tracing.start
|
## async method: Tracing.start
|
||||||
|
|
@ -49,43 +48,41 @@ context.tracing.stop(save_as = "trace.zip")
|
||||||
Start tracing.
|
Start tracing.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await context.tracing.start({ name: 'trace', screenshots: true, snapshots: true });
|
await context.tracing.start({ screenshots: true, snapshots: true });
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
await page.goto('https://playwright.dev');
|
await page.goto('https://playwright.dev');
|
||||||
await context.tracing.stop();
|
await context.tracing.stop({ path: 'trace.zip' });
|
||||||
await context.tracing.export('trace.zip');
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```java
|
```java
|
||||||
context.tracing.start(page, new Tracing.StartOptions()
|
context.tracing.start(page, new Tracing.StartOptions()
|
||||||
.setName("trace")
|
|
||||||
.setScreenshots(true)
|
.setScreenshots(true)
|
||||||
.setSnapshots(true);
|
.setSnapshots(true);
|
||||||
Page page = context.newPage();
|
Page page = context.newPage();
|
||||||
page.goto('https://playwright.dev');
|
page.goto('https://playwright.dev');
|
||||||
context.tracing.stop();
|
context.tracing.stop(new Tracing.StopOptions()
|
||||||
context.tracing.export(Paths.get("trace.zip")))
|
.setPath(Paths.get("trace.zip")));
|
||||||
```
|
```
|
||||||
|
|
||||||
```python async
|
```python async
|
||||||
await context.tracing.start(name="trace", screenshots=True, snapshots=True)
|
await context.tracing.start(name="trace", screenshots=True, snapshots=True)
|
||||||
await page.goto("https://playwright.dev")
|
await page.goto("https://playwright.dev")
|
||||||
await context.tracing.stop()
|
await context.tracing.stop()
|
||||||
await context.tracing.export("trace.zip")
|
await context.tracing.stop(path = "trace.zip")
|
||||||
```
|
```
|
||||||
|
|
||||||
```python sync
|
```python sync
|
||||||
context.tracing.start(name="trace", screenshots=True, snapshots=True)
|
context.tracing.start(name="trace", screenshots=True, snapshots=True)
|
||||||
page.goto("https://playwright.dev")
|
page.goto("https://playwright.dev")
|
||||||
context.tracing.stop()
|
context.tracing.stop()
|
||||||
context.tracing.export("trace.zip")
|
context.tracing.stop(path = "trace.zip")
|
||||||
```
|
```
|
||||||
|
|
||||||
### option: Tracing.start.name
|
### option: Tracing.start.name
|
||||||
- `name` <[string]>
|
- `name` <[string]>
|
||||||
|
|
||||||
If specified, the trace is going to be saved into the file with the
|
If specified, the trace is going to be saved into the file with the
|
||||||
given name inside the [`option: traceDir`] folder specified in [`method: BrowserType.launch`].
|
given name inside the [`option: tracesDir`] folder specified in [`method: BrowserType.launch`].
|
||||||
|
|
||||||
### option: Tracing.start.screenshots
|
### option: Tracing.start.screenshots
|
||||||
- `screenshots` <[boolean]>
|
- `screenshots` <[boolean]>
|
||||||
|
|
|
||||||
|
|
@ -675,9 +675,9 @@ Logger sink for Playwright logging.
|
||||||
Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to
|
Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to
|
||||||
disable timeout.
|
disable timeout.
|
||||||
|
|
||||||
## browser-option-tracedir
|
## browser-option-tracesdir
|
||||||
* langs: js, python, java
|
* langs: js, python, java
|
||||||
- `traceDir` <[path]>
|
- `tracesDir` <[path]>
|
||||||
|
|
||||||
If specified, traces are saved into this directory.
|
If specified, traces are saved into this directory.
|
||||||
|
|
||||||
|
|
@ -708,4 +708,4 @@ Slows down Playwright operations by the specified amount of milliseconds. Useful
|
||||||
- %%-browser-option-ignoredefaultargs-%%
|
- %%-browser-option-ignoredefaultargs-%%
|
||||||
- %%-browser-option-proxy-%%
|
- %%-browser-option-proxy-%%
|
||||||
- %%-browser-option-timeout-%%
|
- %%-browser-option-timeout-%%
|
||||||
- %%-browser-option-tracedir-%%
|
- %%-browser-option-tracesdir-%%
|
||||||
|
|
|
||||||
|
|
@ -107,10 +107,8 @@ class ConnectedBrowserDispatcher extends Dispatcher<Browser, channels.BrowserIni
|
||||||
}
|
}
|
||||||
|
|
||||||
async newContext(params: channels.BrowserNewContextParams, metadata: CallMetadata): Promise<channels.BrowserNewContextResult> {
|
async newContext(params: channels.BrowserNewContextParams, metadata: CallMetadata): Promise<channels.BrowserNewContextResult> {
|
||||||
if (params.recordVideo) {
|
if (params.recordVideo)
|
||||||
// TODO: we should create a separate temp directory or accept a launchServer parameter.
|
params.recordVideo.dir = this._object.options.artifactsDir;
|
||||||
params.recordVideo.dir = this._object.options.downloadsPath!;
|
|
||||||
}
|
|
||||||
const context = await this._object.newContext(params);
|
const context = await this._object.newContext(params);
|
||||||
this._contexts.add(context);
|
this._contexts.add(context);
|
||||||
context._setSelectors(this._selectors);
|
context._setSelectors(this._selectors);
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ export type BrowserTypeLaunchParams = {
|
||||||
password?: string,
|
password?: string,
|
||||||
},
|
},
|
||||||
downloadsPath?: string,
|
downloadsPath?: string,
|
||||||
traceDir?: string,
|
tracesDir?: string,
|
||||||
chromiumSandbox?: boolean,
|
chromiumSandbox?: boolean,
|
||||||
firefoxUserPrefs?: any,
|
firefoxUserPrefs?: any,
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
|
|
@ -263,7 +263,7 @@ export type BrowserTypeLaunchOptions = {
|
||||||
password?: string,
|
password?: string,
|
||||||
},
|
},
|
||||||
downloadsPath?: string,
|
downloadsPath?: string,
|
||||||
traceDir?: string,
|
tracesDir?: string,
|
||||||
chromiumSandbox?: boolean,
|
chromiumSandbox?: boolean,
|
||||||
firefoxUserPrefs?: any,
|
firefoxUserPrefs?: any,
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
|
|
@ -291,7 +291,7 @@ export type BrowserTypeLaunchPersistentContextParams = {
|
||||||
password?: string,
|
password?: string,
|
||||||
},
|
},
|
||||||
downloadsPath?: string,
|
downloadsPath?: string,
|
||||||
traceDir?: string,
|
tracesDir?: string,
|
||||||
chromiumSandbox?: boolean,
|
chromiumSandbox?: boolean,
|
||||||
sdkLanguage: string,
|
sdkLanguage: string,
|
||||||
noDefaultViewport?: boolean,
|
noDefaultViewport?: boolean,
|
||||||
|
|
@ -362,7 +362,7 @@ export type BrowserTypeLaunchPersistentContextOptions = {
|
||||||
password?: string,
|
password?: string,
|
||||||
},
|
},
|
||||||
downloadsPath?: string,
|
downloadsPath?: string,
|
||||||
traceDir?: string,
|
tracesDir?: string,
|
||||||
chromiumSandbox?: boolean,
|
chromiumSandbox?: boolean,
|
||||||
noDefaultViewport?: boolean,
|
noDefaultViewport?: boolean,
|
||||||
viewport?: {
|
viewport?: {
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ LaunchOptions:
|
||||||
username: string?
|
username: string?
|
||||||
password: string?
|
password: string?
|
||||||
downloadsPath: string?
|
downloadsPath: string?
|
||||||
traceDir: string?
|
tracesDir: string?
|
||||||
chromiumSandbox: boolean?
|
chromiumSandbox: boolean?
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||||
password: tOptional(tString),
|
password: tOptional(tString),
|
||||||
})),
|
})),
|
||||||
downloadsPath: tOptional(tString),
|
downloadsPath: tOptional(tString),
|
||||||
traceDir: tOptional(tString),
|
tracesDir: tOptional(tString),
|
||||||
chromiumSandbox: tOptional(tBoolean),
|
chromiumSandbox: tOptional(tBoolean),
|
||||||
firefoxUserPrefs: tOptional(tAny),
|
firefoxUserPrefs: tOptional(tAny),
|
||||||
slowMo: tOptional(tNumber),
|
slowMo: tOptional(tNumber),
|
||||||
|
|
@ -200,7 +200,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||||
password: tOptional(tString),
|
password: tOptional(tString),
|
||||||
})),
|
})),
|
||||||
downloadsPath: tOptional(tString),
|
downloadsPath: tOptional(tString),
|
||||||
traceDir: tOptional(tString),
|
tracesDir: tOptional(tString),
|
||||||
chromiumSandbox: tOptional(tBoolean),
|
chromiumSandbox: tOptional(tBoolean),
|
||||||
sdkLanguage: tString,
|
sdkLanguage: tString,
|
||||||
noDefaultViewport: tOptional(tBoolean),
|
noDefaultViewport: tOptional(tBoolean),
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,9 @@ export class AndroidDevice extends SdkObject {
|
||||||
isChromium: true,
|
isChromium: true,
|
||||||
slowMo: 0,
|
slowMo: 0,
|
||||||
persistent: { ...options, noDefaultViewport: true },
|
persistent: { ...options, noDefaultViewport: true },
|
||||||
downloadsPath: undefined,
|
artifactsDir: '',
|
||||||
|
downloadsPath: '',
|
||||||
|
tracesDir: '',
|
||||||
browserProcess: new ClankBrowserProcess(androidBrowser),
|
browserProcess: new ClankBrowserProcess(androidBrowser),
|
||||||
proxy: options.proxy,
|
proxy: options.proxy,
|
||||||
protocolLogger: helper.debugProtocolLogger(),
|
protocolLogger: helper.debugProtocolLogger(),
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,9 @@ export type BrowserOptions = PlaywrightOptions & {
|
||||||
name: string,
|
name: string,
|
||||||
isChromium: boolean,
|
isChromium: boolean,
|
||||||
channel?: string,
|
channel?: string,
|
||||||
downloadsPath?: string,
|
artifactsDir: string;
|
||||||
traceDir?: string,
|
downloadsPath: string,
|
||||||
|
tracesDir: string,
|
||||||
headful?: boolean,
|
headful?: boolean,
|
||||||
persistent?: types.BrowserContextOptions, // Undefined means no persistent context.
|
persistent?: types.BrowserContextOptions, // Undefined means no persistent context.
|
||||||
browserProcess: BrowserProcess,
|
browserProcess: BrowserProcess,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import { CallMetadata, SdkObject } from './instrumentation';
|
||||||
const mkdirAsync = util.promisify(fs.mkdir);
|
const mkdirAsync = util.promisify(fs.mkdir);
|
||||||
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
||||||
const existsAsync = (path: string): Promise<boolean> => new Promise(resolve => fs.stat(path, err => resolve(!err)));
|
const existsAsync = (path: string): Promise<boolean> => new Promise(resolve => fs.stat(path, err => resolve(!err)));
|
||||||
const DOWNLOADS_FOLDER = path.join(os.tmpdir(), 'playwright_downloads-');
|
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||||
|
|
||||||
export abstract class BrowserType extends SdkObject {
|
export abstract class BrowserType extends SdkObject {
|
||||||
private _name: registry.BrowserName;
|
private _name: registry.BrowserName;
|
||||||
|
|
@ -97,7 +97,7 @@ export abstract class BrowserType extends SdkObject {
|
||||||
async _innerLaunch(progress: Progress, options: types.LaunchOptions, persistent: types.BrowserContextOptions | undefined, protocolLogger: types.ProtocolLogger, userDataDir?: string): Promise<Browser> {
|
async _innerLaunch(progress: Progress, options: types.LaunchOptions, persistent: types.BrowserContextOptions | undefined, protocolLogger: types.ProtocolLogger, userDataDir?: 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, downloadsPath, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, userDataDir);
|
const { browserProcess, artifactsDir, transport } = await this._launchProcess(progress, options, !!persistent, browserLogsCollector, userDataDir);
|
||||||
if ((options as any).__testHookBeforeCreateBrowser)
|
if ((options as any).__testHookBeforeCreateBrowser)
|
||||||
await (options as any).__testHookBeforeCreateBrowser();
|
await (options as any).__testHookBeforeCreateBrowser();
|
||||||
const browserOptions: BrowserOptions = {
|
const browserOptions: BrowserOptions = {
|
||||||
|
|
@ -108,14 +108,15 @@ export abstract class BrowserType extends SdkObject {
|
||||||
slowMo: options.slowMo,
|
slowMo: options.slowMo,
|
||||||
persistent,
|
persistent,
|
||||||
headful: !options.headless,
|
headful: !options.headless,
|
||||||
downloadsPath,
|
artifactsDir,
|
||||||
|
downloadsPath: (options.downloadsPath || artifactsDir)!,
|
||||||
|
tracesDir: (options.tracesDir || artifactsDir)!,
|
||||||
browserProcess,
|
browserProcess,
|
||||||
customExecutablePath: options.executablePath,
|
customExecutablePath: options.executablePath,
|
||||||
proxy: options.proxy,
|
proxy: options.proxy,
|
||||||
protocolLogger,
|
protocolLogger,
|
||||||
browserLogsCollector,
|
browserLogsCollector,
|
||||||
wsEndpoint: options.useWebSocket ? (transport as WebSocketTransport).wsEndpoint : undefined,
|
wsEndpoint: options.useWebSocket ? (transport as WebSocketTransport).wsEndpoint : undefined,
|
||||||
traceDir: options.traceDir,
|
|
||||||
};
|
};
|
||||||
if (persistent)
|
if (persistent)
|
||||||
validateBrowserContextOptions(persistent, browserOptions);
|
validateBrowserContextOptions(persistent, browserOptions);
|
||||||
|
|
@ -127,7 +128,7 @@ export abstract class BrowserType extends SdkObject {
|
||||||
return browser;
|
return browser;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _launchProcess(progress: Progress, options: types.LaunchOptions, isPersistent: boolean, browserLogsCollector: RecentLogsCollector, userDataDir?: string): Promise<{ browserProcess: BrowserProcess, downloadsPath: string, transport: ConnectionTransport }> {
|
private async _launchProcess(progress: Progress, options: types.LaunchOptions, isPersistent: boolean, browserLogsCollector: RecentLogsCollector, userDataDir?: string): Promise<{ browserProcess: BrowserProcess, artifactsDir: string, transport: ConnectionTransport }> {
|
||||||
const {
|
const {
|
||||||
ignoreDefaultArgs,
|
ignoreDefaultArgs,
|
||||||
ignoreAllDefaultArgs,
|
ignoreAllDefaultArgs,
|
||||||
|
|
@ -141,19 +142,13 @@ export abstract class BrowserType extends SdkObject {
|
||||||
const env = options.env ? envArrayToObject(options.env) : process.env;
|
const env = options.env ? envArrayToObject(options.env) : process.env;
|
||||||
|
|
||||||
const tempDirectories = [];
|
const tempDirectories = [];
|
||||||
const ensurePath = async (tmpPrefix: string, pathFromOptions?: string) => {
|
if (options.downloadsPath)
|
||||||
let dir;
|
await mkdirAsync(options.downloadsPath, { recursive: true });
|
||||||
if (pathFromOptions) {
|
if (options.tracesDir)
|
||||||
dir = pathFromOptions;
|
await mkdirAsync(options.tracesDir, { recursive: true });
|
||||||
await mkdirAsync(pathFromOptions, { recursive: true });
|
|
||||||
} else {
|
const artifactsDir = await mkdtempAsync(ARTIFACTS_FOLDER);
|
||||||
dir = await mkdtempAsync(tmpPrefix);
|
tempDirectories.push(artifactsDir);
|
||||||
tempDirectories.push(dir);
|
|
||||||
}
|
|
||||||
return dir;
|
|
||||||
};
|
|
||||||
// TODO: add downloadsPath to newContext().
|
|
||||||
const downloadsPath = await ensurePath(DOWNLOADS_FOLDER, options.downloadsPath);
|
|
||||||
|
|
||||||
if (!userDataDir) {
|
if (!userDataDir) {
|
||||||
userDataDir = await mkdtempAsync(path.join(os.tmpdir(), `playwright_${this._name}dev_profile-`));
|
userDataDir = await mkdtempAsync(path.join(os.tmpdir(), `playwright_${this._name}dev_profile-`));
|
||||||
|
|
@ -252,7 +247,7 @@ export abstract class BrowserType extends SdkObject {
|
||||||
const stdio = launchedProcess.stdio as unknown as [NodeJS.ReadableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.ReadableStream];
|
const stdio = launchedProcess.stdio as unknown as [NodeJS.ReadableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.ReadableStream];
|
||||||
transport = new PipeTransport(stdio[3], stdio[4]);
|
transport = new PipeTransport(stdio[3], stdio[4]);
|
||||||
}
|
}
|
||||||
return { browserProcess, downloadsPath, transport };
|
return { browserProcess, artifactsDir, transport };
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectOverCDP(metadata: CallMetadata, endpointURL: string, options: { slowMo?: number, sdkLanguage: string }, timeout?: number): Promise<Browser> {
|
async connectOverCDP(metadata: CallMetadata, endpointURL: string, options: { slowMo?: number, sdkLanguage: string }, timeout?: number): Promise<Browser> {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import util from 'util';
|
||||||
import { CRBrowser } from './crBrowser';
|
import { CRBrowser } from './crBrowser';
|
||||||
import { Env } from '../processLauncher';
|
import { Env } from '../processLauncher';
|
||||||
import { kBrowserCloseMessageId } from './crConnection';
|
import { kBrowserCloseMessageId } from './crConnection';
|
||||||
|
|
@ -25,7 +28,7 @@ import { ConnectionTransport, ProtocolRequest, WebSocketTransport } from '../tra
|
||||||
import { CRDevTools } from './crDevTools';
|
import { CRDevTools } from './crDevTools';
|
||||||
import { BrowserOptions, BrowserProcess, PlaywrightOptions } from '../browser';
|
import { BrowserOptions, BrowserProcess, PlaywrightOptions } from '../browser';
|
||||||
import * as types from '../types';
|
import * as types from '../types';
|
||||||
import { debugMode, headersArrayToObject } from '../../utils/utils';
|
import { debugMode, headersArrayToObject, removeFolders } from '../../utils/utils';
|
||||||
import { RecentLogsCollector } from '../../utils/debugLogger';
|
import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
import { ProgressController } from '../progress';
|
import { ProgressController } from '../progress';
|
||||||
import { TimeoutSettings } from '../../utils/timeoutSettings';
|
import { TimeoutSettings } from '../../utils/timeoutSettings';
|
||||||
|
|
@ -34,6 +37,9 @@ import { CallMetadata } from '../instrumentation';
|
||||||
import { findChromiumChannel } from './findChromiumChannel';
|
import { findChromiumChannel } from './findChromiumChannel';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
|
|
||||||
|
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
||||||
|
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||||
|
|
||||||
export class Chromium extends BrowserType {
|
export class Chromium extends BrowserType {
|
||||||
private _devtools: CRDevTools | undefined;
|
private _devtools: CRDevTools | undefined;
|
||||||
|
|
||||||
|
|
@ -58,12 +64,17 @@ export class Chromium extends BrowserType {
|
||||||
let headersMap: { [key: string]: string; } | undefined;
|
let headersMap: { [key: string]: string; } | undefined;
|
||||||
if (options.headers)
|
if (options.headers)
|
||||||
headersMap = headersArrayToObject(options.headers, false);
|
headersMap = headersArrayToObject(options.headers, false);
|
||||||
|
|
||||||
|
const artifactsDir = await mkdtempAsync(ARTIFACTS_FOLDER);
|
||||||
|
|
||||||
const chromeTransport = await WebSocketTransport.connect(progress, await urlToWSEndpoint(endpointURL), headersMap);
|
const chromeTransport = await WebSocketTransport.connect(progress, await urlToWSEndpoint(endpointURL), headersMap);
|
||||||
const browserProcess: BrowserProcess = {
|
const browserProcess: BrowserProcess = {
|
||||||
close: async () => {
|
close: async () => {
|
||||||
|
await removeFolders([ artifactsDir ]);
|
||||||
await chromeTransport.closeAndWait();
|
await chromeTransport.closeAndWait();
|
||||||
},
|
},
|
||||||
kill: async () => {
|
kill: async () => {
|
||||||
|
await removeFolders([ artifactsDir ]);
|
||||||
await chromeTransport.closeAndWait();
|
await chromeTransport.closeAndWait();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -76,6 +87,9 @@ export class Chromium extends BrowserType {
|
||||||
browserProcess,
|
browserProcess,
|
||||||
protocolLogger: helper.debugProtocolLogger(),
|
protocolLogger: helper.debugProtocolLogger(),
|
||||||
browserLogsCollector,
|
browserLogsCollector,
|
||||||
|
artifactsDir,
|
||||||
|
downloadsPath: artifactsDir,
|
||||||
|
tracesDir: artifactsDir
|
||||||
};
|
};
|
||||||
return await CRBrowser.connect(chromeTransport, browserOptions);
|
return await CRBrowser.connect(chromeTransport, browserOptions);
|
||||||
}, TimeoutSettings.timeout({timeout}));
|
}, TimeoutSettings.timeout({timeout}));
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ export class CRBrowserContext extends BrowserContext {
|
||||||
async _initialize() {
|
async _initialize() {
|
||||||
assert(!Array.from(this._browser._crPages.values()).some(page => page._browserContext === this));
|
assert(!Array.from(this._browser._crPages.values()).some(page => page._browserContext === this));
|
||||||
const promises: Promise<any>[] = [ super._initialize() ];
|
const promises: Promise<any>[] = [ super._initialize() ];
|
||||||
if (this._browser.options.downloadsPath) {
|
if (this._browser.options.name !== 'electron') {
|
||||||
promises.push(this._browser._session.send('Browser.setDownloadBehavior', {
|
promises.push(this._browser._session.send('Browser.setDownloadBehavior', {
|
||||||
behavior: this._options.acceptDownloads ? 'allowAndName' : 'deny',
|
behavior: this._options.acceptDownloads ? 'allowAndName' : 'deny',
|
||||||
browserContextId: this._browserContextId,
|
browserContextId: this._browserContextId,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import * as os from 'os';
|
import fs from 'fs';
|
||||||
|
import os from 'os';
|
||||||
|
import path from 'path';
|
||||||
|
import util from 'util';
|
||||||
import { CRBrowser, CRBrowserContext } from '../chromium/crBrowser';
|
import { CRBrowser, CRBrowserContext } from '../chromium/crBrowser';
|
||||||
import { CRConnection, CRSession } from '../chromium/crConnection';
|
import { CRConnection, CRSession } from '../chromium/crConnection';
|
||||||
import { CRExecutionContext } from '../chromium/crExecutionContext';
|
import { CRExecutionContext } from '../chromium/crExecutionContext';
|
||||||
|
|
@ -34,6 +37,9 @@ import { RecentLogsCollector } from '../../utils/debugLogger';
|
||||||
import { internalCallMetadata, SdkObject } from '../instrumentation';
|
import { internalCallMetadata, SdkObject } from '../instrumentation';
|
||||||
import * as channels from '../../protocol/channels';
|
import * as channels from '../../protocol/channels';
|
||||||
|
|
||||||
|
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
||||||
|
const ARTIFACTS_FOLDER = path.join(os.tmpdir(), 'playwright-artifacts-');
|
||||||
|
|
||||||
export class ElectronApplication extends SdkObject {
|
export class ElectronApplication extends SdkObject {
|
||||||
static Events = {
|
static Events = {
|
||||||
Close: 'close',
|
Close: 'close',
|
||||||
|
|
@ -119,6 +125,8 @@ export class Electron extends SdkObject {
|
||||||
electronArguments.push('--no-sandbox');
|
electronArguments.push('--no-sandbox');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const artifactsDir = await mkdtempAsync(ARTIFACTS_FOLDER);
|
||||||
|
|
||||||
const browserLogsCollector = new RecentLogsCollector();
|
const browserLogsCollector = new RecentLogsCollector();
|
||||||
const { launchedProcess, gracefullyClose, kill } = await launchProcess({
|
const { launchedProcess, gracefullyClose, kill } = await launchProcess({
|
||||||
executablePath: options.executablePath || require('electron/index.js'),
|
executablePath: options.executablePath || require('electron/index.js'),
|
||||||
|
|
@ -130,7 +138,7 @@ export class Electron extends SdkObject {
|
||||||
},
|
},
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
cwd: options.cwd,
|
cwd: options.cwd,
|
||||||
tempDirectories: [],
|
tempDirectories: [ artifactsDir ],
|
||||||
attemptToGracefullyClose: () => app!.close(),
|
attemptToGracefullyClose: () => app!.close(),
|
||||||
handleSIGINT: true,
|
handleSIGINT: true,
|
||||||
handleSIGTERM: true,
|
handleSIGTERM: true,
|
||||||
|
|
@ -174,6 +182,9 @@ export class Electron extends SdkObject {
|
||||||
browserProcess,
|
browserProcess,
|
||||||
protocolLogger: helper.debugProtocolLogger(),
|
protocolLogger: helper.debugProtocolLogger(),
|
||||||
browserLogsCollector,
|
browserLogsCollector,
|
||||||
|
artifactsDir,
|
||||||
|
downloadsPath: artifactsDir,
|
||||||
|
tracesDir: artifactsDir,
|
||||||
};
|
};
|
||||||
const browser = await CRBrowser.connect(chromeTransport, browserOptions);
|
const browser = await CRBrowser.connect(chromeTransport, browserOptions);
|
||||||
app = new ElectronApplication(this, browser, nodeConnection);
|
app = new ElectronApplication(this, browser, nodeConnection);
|
||||||
|
|
|
||||||
|
|
@ -158,15 +158,13 @@ export class FFBrowserContext extends BrowserContext {
|
||||||
assert(!this._ffPages().length);
|
assert(!this._ffPages().length);
|
||||||
const browserContextId = this._browserContextId;
|
const browserContextId = this._browserContextId;
|
||||||
const promises: Promise<any>[] = [ super._initialize() ];
|
const promises: Promise<any>[] = [ super._initialize() ];
|
||||||
if (this._browser.options.downloadsPath) {
|
promises.push(this._browser._connection.send('Browser.setDownloadOptions', {
|
||||||
promises.push(this._browser._connection.send('Browser.setDownloadOptions', {
|
browserContextId,
|
||||||
browserContextId,
|
downloadOptions: {
|
||||||
downloadOptions: {
|
behavior: this._options.acceptDownloads ? 'saveToDisk' : 'cancel',
|
||||||
behavior: this._options.acceptDownloads ? 'saveToDisk' : 'cancel',
|
downloadsDir: this._browser.options.downloadsPath,
|
||||||
downloadsDir: this._browser.options.downloadsPath,
|
},
|
||||||
},
|
}));
|
||||||
}));
|
|
||||||
}
|
|
||||||
if (this._options.viewport) {
|
if (this._options.viewport) {
|
||||||
const viewport = {
|
const viewport = {
|
||||||
viewportSize: { width: this._options.viewport.width, height: this._options.viewport.height },
|
viewportSize: { width: this._options.viewport.width, height: this._options.viewport.height },
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,10 @@ export class TraceSnapshotter extends EventEmitter implements SnapshotterDelegat
|
||||||
await this._snapshotter.start();
|
await this._snapshotter.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async stop(): Promise<void> {
|
||||||
|
await this._snapshotter.stop();
|
||||||
|
}
|
||||||
|
|
||||||
async dispose() {
|
async dispose() {
|
||||||
this._snapshotter.dispose();
|
this._snapshotter.dispose();
|
||||||
await this._writeArtifactChain;
|
await this._writeArtifactChain;
|
||||||
|
|
|
||||||
|
|
@ -48,23 +48,23 @@ export class Tracing implements InstrumentationListener {
|
||||||
private _resourcesDir: string;
|
private _resourcesDir: string;
|
||||||
private _sha1s: string[] = [];
|
private _sha1s: string[] = [];
|
||||||
private _started = false;
|
private _started = false;
|
||||||
private _traceDir: string | undefined;
|
private _tracesDir: string | undefined;
|
||||||
|
|
||||||
constructor(context: BrowserContext) {
|
constructor(context: BrowserContext) {
|
||||||
this._context = context;
|
this._context = context;
|
||||||
this._traceDir = context._browser.options.traceDir;
|
this._tracesDir = context._browser.options.tracesDir;
|
||||||
this._resourcesDir = path.join(this._traceDir || '', 'resources');
|
this._resourcesDir = path.join(this._tracesDir, 'resources');
|
||||||
this._snapshotter = new TraceSnapshotter(this._context, this._resourcesDir, traceEvent => this._appendTraceEvent(traceEvent));
|
this._snapshotter = new TraceSnapshotter(this._context, this._resourcesDir, traceEvent => this._appendTraceEvent(traceEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(options: TracerOptions): Promise<void> {
|
async start(options: TracerOptions): Promise<void> {
|
||||||
// context + page must be the first events added, this method can't have awaits before them.
|
// context + page must be the first events added, this method can't have awaits before them.
|
||||||
if (!this._traceDir)
|
if (!this._tracesDir)
|
||||||
throw new Error('Tracing directory is not specified when launching the browser');
|
throw new Error('Tracing directory is not specified when launching the browser');
|
||||||
if (this._started)
|
if (this._started)
|
||||||
throw new Error('Tracing has already been started');
|
throw new Error('Tracing has already been started');
|
||||||
this._started = true;
|
this._started = true;
|
||||||
this._traceFile = path.join(this._traceDir, (options.name || createGuid()) + '.trace');
|
this._traceFile = path.join(this._tracesDir, (options.name || createGuid()) + '.trace');
|
||||||
|
|
||||||
this._appendEventChain = mkdirIfNeeded(this._traceFile);
|
this._appendEventChain = mkdirIfNeeded(this._traceFile);
|
||||||
const event: trace.ContextCreatedTraceEvent = {
|
const event: trace.ContextCreatedTraceEvent = {
|
||||||
|
|
@ -91,6 +91,7 @@ export class Tracing implements InstrumentationListener {
|
||||||
if (!this._started)
|
if (!this._started)
|
||||||
return;
|
return;
|
||||||
this._started = false;
|
this._started = false;
|
||||||
|
await this._snapshotter.stop();
|
||||||
this._context.instrumentation.removeListener(this);
|
this._context.instrumentation.removeListener(this);
|
||||||
helper.removeEventListeners(this._eventListeners);
|
helper.removeEventListeners(this._eventListeners);
|
||||||
for (const { sdkObject, metadata } of this._pendingCalls.values())
|
for (const { sdkObject, metadata } of this._pendingCalls.values())
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ export class TraceViewer {
|
||||||
private _server: HttpServer;
|
private _server: HttpServer;
|
||||||
private _browserName: string;
|
private _browserName: string;
|
||||||
|
|
||||||
constructor(traceDir: string, browserName: string) {
|
constructor(tracesDir: string, browserName: string) {
|
||||||
this._browserName = browserName;
|
this._browserName = browserName;
|
||||||
const resourcesDir = path.join(traceDir, 'resources');
|
const resourcesDir = path.join(tracesDir, 'resources');
|
||||||
|
|
||||||
// Served by TraceServer
|
// Served by TraceServer
|
||||||
// - "/tracemodel" - json with trace model.
|
// - "/tracemodel" - json with trace model.
|
||||||
|
|
@ -51,9 +51,9 @@ export class TraceViewer {
|
||||||
// - "/snapshot/pageId/..." - actual snapshot html.
|
// - "/snapshot/pageId/..." - actual snapshot html.
|
||||||
// - "/snapshot/service-worker.js" - service worker that intercepts snapshot resources
|
// - "/snapshot/service-worker.js" - service worker that intercepts snapshot resources
|
||||||
// and translates them into "/resources/<resourceId>".
|
// and translates them into "/resources/<resourceId>".
|
||||||
const actionTraces = fs.readdirSync(traceDir).filter(name => name.endsWith('.trace'));
|
const actionTraces = fs.readdirSync(tracesDir).filter(name => name.endsWith('.trace'));
|
||||||
const debugNames = actionTraces.map(name => {
|
const debugNames = actionTraces.map(name => {
|
||||||
const tracePrefix = path.join(traceDir, name.substring(0, name.indexOf('.trace')));
|
const tracePrefix = path.join(tracesDir, name.substring(0, name.indexOf('.trace')));
|
||||||
return path.basename(tracePrefix);
|
return path.basename(tracePrefix);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ export class TraceViewer {
|
||||||
|
|
||||||
const traceModelHandler: ServerRouteHandler = (request, response) => {
|
const traceModelHandler: ServerRouteHandler = (request, response) => {
|
||||||
const debugName = request.url!.substring('/context/'.length);
|
const debugName = request.url!.substring('/context/'.length);
|
||||||
const tracePrefix = path.join(traceDir, debugName);
|
const tracePrefix = path.join(tracesDir, debugName);
|
||||||
snapshotStorage.clear();
|
snapshotStorage.clear();
|
||||||
response.statusCode = 200;
|
response.statusCode = 200;
|
||||||
response.setHeader('Content-Type', 'application/json');
|
response.setHeader('Content-Type', 'application/json');
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ type LaunchOptionsBase = {
|
||||||
chromiumSandbox?: boolean,
|
chromiumSandbox?: boolean,
|
||||||
slowMo?: number,
|
slowMo?: number,
|
||||||
useWebSocket?: boolean,
|
useWebSocket?: boolean,
|
||||||
traceDir?: string,
|
tracesDir?: string,
|
||||||
};
|
};
|
||||||
export type LaunchOptions = LaunchOptionsBase & {
|
export type LaunchOptions = LaunchOptionsBase & {
|
||||||
firefoxUserPrefs?: { [key: string]: string | number | boolean },
|
firefoxUserPrefs?: { [key: string]: string | number | boolean },
|
||||||
|
|
|
||||||
|
|
@ -213,13 +213,11 @@ export class WKBrowserContext extends BrowserContext {
|
||||||
assert(!this._wkPages().length);
|
assert(!this._wkPages().length);
|
||||||
const browserContextId = this._browserContextId;
|
const browserContextId = this._browserContextId;
|
||||||
const promises: Promise<any>[] = [ super._initialize() ];
|
const promises: Promise<any>[] = [ super._initialize() ];
|
||||||
if (this._browser.options.downloadsPath) {
|
promises.push(this._browser._browserSession.send('Playwright.setDownloadBehavior', {
|
||||||
promises.push(this._browser._browserSession.send('Playwright.setDownloadBehavior', {
|
behavior: this._options.acceptDownloads ? 'allow' : 'deny',
|
||||||
behavior: this._options.acceptDownloads ? 'allow' : 'deny',
|
downloadPath: this._browser.options.downloadsPath,
|
||||||
downloadPath: this._browser.options.downloadsPath,
|
browserContextId
|
||||||
browserContextId
|
}));
|
||||||
}));
|
|
||||||
}
|
|
||||||
if (this._options.ignoreHTTPSErrors)
|
if (this._options.ignoreHTTPSErrors)
|
||||||
promises.push(this._browser._browserSession.send('Playwright.setIgnoreCertificateErrors', { browserContextId, ignore: true }));
|
promises.push(this._browser._browserSession.send('Playwright.setIgnoreCertificateErrors', { browserContextId, ignore: true }));
|
||||||
if (this._options.locale)
|
if (this._options.locale)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import { baseTest, CommonWorkerFixtures } from './baseTest';
|
||||||
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
||||||
|
|
||||||
type PlaywrightWorkerOptions = {
|
type PlaywrightWorkerOptions = {
|
||||||
traceDir: LaunchOptions['traceDir'];
|
tracesDir: LaunchOptions['tracesDir'];
|
||||||
executablePath: LaunchOptions['executablePath'];
|
executablePath: LaunchOptions['executablePath'];
|
||||||
proxy: LaunchOptions['proxy'];
|
proxy: LaunchOptions['proxy'];
|
||||||
args: LaunchOptions['args'];
|
args: LaunchOptions['args'];
|
||||||
|
|
@ -53,7 +53,7 @@ type PlaywrightTestFixtures = {
|
||||||
export type PlaywrightOptions = PlaywrightWorkerOptions & PlaywrightTestOptions;
|
export type PlaywrightOptions = PlaywrightWorkerOptions & PlaywrightTestOptions;
|
||||||
|
|
||||||
export const playwrightFixtures: folio.Fixtures<PlaywrightTestOptions & PlaywrightTestFixtures, PlaywrightWorkerOptions & PlaywrightWorkerFixtures, {}, CommonWorkerFixtures> = {
|
export const playwrightFixtures: folio.Fixtures<PlaywrightTestOptions & PlaywrightTestFixtures, PlaywrightWorkerOptions & PlaywrightWorkerFixtures, {}, CommonWorkerFixtures> = {
|
||||||
traceDir: [ undefined, { scope: 'worker' } ],
|
tracesDir: [ undefined, { scope: 'worker' } ],
|
||||||
executablePath: [ undefined, { scope: 'worker' } ],
|
executablePath: [ undefined, { scope: 'worker' } ],
|
||||||
proxy: [ undefined, { scope: 'worker' } ],
|
proxy: [ undefined, { scope: 'worker' } ],
|
||||||
args: [ undefined, { scope: 'worker' } ],
|
args: [ undefined, { scope: 'worker' } ],
|
||||||
|
|
@ -63,12 +63,12 @@ export const playwrightFixtures: folio.Fixtures<PlaywrightTestOptions & Playwrig
|
||||||
await run(playwright[browserName]);
|
await run(playwright[browserName]);
|
||||||
}, { scope: 'worker' } ],
|
}, { scope: 'worker' } ],
|
||||||
|
|
||||||
browserOptions: [async ({ headless, channel, executablePath, traceDir, proxy, args }, run) => {
|
browserOptions: [async ({ headless, channel, executablePath, tracesDir, proxy, args }, run) => {
|
||||||
await run({
|
await run({
|
||||||
headless,
|
headless,
|
||||||
channel,
|
channel,
|
||||||
executablePath,
|
executablePath,
|
||||||
traceDir,
|
tracesDir,
|
||||||
proxy,
|
proxy,
|
||||||
args,
|
args,
|
||||||
handleSIGINT: false,
|
handleSIGINT: false,
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ for (const browserName of browserNames) {
|
||||||
channel,
|
channel,
|
||||||
video,
|
video,
|
||||||
executablePath,
|
executablePath,
|
||||||
traceDir: process.env.PWTRACE ? path.join(outputDir, 'trace') : undefined,
|
tracesDir: process.env.PWTRACE ? path.join(outputDir, 'trace') : undefined,
|
||||||
coverageName: browserName,
|
coverageName: browserName,
|
||||||
},
|
},
|
||||||
define: { test: pageTest, fixtures: pageFixtures },
|
define: { test: pageTest, fixtures: pageFixtures },
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export class RemoteServer {
|
||||||
args: browserOptions.args,
|
args: browserOptions.args,
|
||||||
headless: browserOptions.headless,
|
headless: browserOptions.headless,
|
||||||
channel: browserOptions.channel,
|
channel: browserOptions.channel,
|
||||||
traceDir: browserOptions.traceDir,
|
tracesDir: browserOptions.tracesDir,
|
||||||
handleSIGINT: true,
|
handleSIGINT: true,
|
||||||
handleSIGTERM: true,
|
handleSIGTERM: true,
|
||||||
handleSIGHUP: true,
|
handleSIGHUP: true,
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import path from 'path';
|
|
||||||
import { expect, contextTest as test, browserTest } from './config/browserTest';
|
import { expect, contextTest as test, browserTest } from './config/browserTest';
|
||||||
import yauzl from 'yauzl';
|
import yauzl from 'yauzl';
|
||||||
import removeFolder from 'rimraf';
|
|
||||||
import jpeg from 'jpeg-js';
|
import jpeg from 'jpeg-js';
|
||||||
|
|
||||||
const traceDir = path.join(__dirname, '..', 'test-results', 'trace-' + process.env.FOLIO_WORKER_INDEX);
|
|
||||||
test.use({ traceDir });
|
|
||||||
|
|
||||||
test.beforeEach(async ({ browserName, headless }) => {
|
|
||||||
test.fixme(browserName === 'chromium' && !headless, 'Chromium screencast on headed has a min width issue');
|
|
||||||
await new Promise(f => removeFolder(traceDir, f));
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should collect trace', async ({ context, page, server, browserName }, testInfo) => {
|
test('should collect trace', async ({ context, page, server, browserName }, testInfo) => {
|
||||||
await context.tracing.start({ name: 'test', screenshots: true, snapshots: true });
|
await context.tracing.start({ name: 'test', screenshots: true, snapshots: true });
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
|
|
||||||
19
types/types.d.ts
vendored
19
types/types.d.ts
vendored
|
|
@ -7235,7 +7235,7 @@ export interface BrowserType<Unused = {}> {
|
||||||
/**
|
/**
|
||||||
* If specified, traces are saved into this directory.
|
* If specified, traces are saved into this directory.
|
||||||
*/
|
*/
|
||||||
traceDir?: string;
|
tracesDir?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specific user agent to use in this context.
|
* Specific user agent to use in this context.
|
||||||
|
|
@ -7424,7 +7424,7 @@ export interface BrowserType<Unused = {}> {
|
||||||
/**
|
/**
|
||||||
* If specified, traces are saved into this directory.
|
* If specified, traces are saved into this directory.
|
||||||
*/
|
*/
|
||||||
traceDir?: string;
|
tracesDir?: string;
|
||||||
}): Promise<BrowserServer>;
|
}): Promise<BrowserServer>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -10604,9 +10604,9 @@ export interface Touchscreen {
|
||||||
* Start with specifying the folder traces will be stored in:
|
* Start with specifying the folder traces will be stored in:
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* const browser = await chromium.launch({ traceDir: 'traces' });
|
* const browser = await chromium.launch();
|
||||||
* const context = await browser.newContext();
|
* const context = await browser.newContext();
|
||||||
* await context.tracing.start({ name: 'trace', screenshots: true, snapshots: true });
|
* await context.tracing.start({ screenshots: true, snapshots: true });
|
||||||
* const page = await context.newPage();
|
* const page = await context.newPage();
|
||||||
* await page.goto('https://playwright.dev');
|
* await page.goto('https://playwright.dev');
|
||||||
* await context.tracing.stop({ path: 'trace.zip' });
|
* await context.tracing.stop({ path: 'trace.zip' });
|
||||||
|
|
@ -10618,19 +10618,18 @@ export interface Tracing {
|
||||||
* Start tracing.
|
* Start tracing.
|
||||||
*
|
*
|
||||||
* ```js
|
* ```js
|
||||||
* await context.tracing.start({ name: 'trace', screenshots: true, snapshots: true });
|
* await context.tracing.start({ screenshots: true, snapshots: true });
|
||||||
* const page = await context.newPage();
|
* const page = await context.newPage();
|
||||||
* await page.goto('https://playwright.dev');
|
* await page.goto('https://playwright.dev');
|
||||||
* await context.tracing.stop();
|
* await context.tracing.stop({ path: 'trace.zip' });
|
||||||
* await context.tracing.export('trace.zip');
|
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
start(options?: {
|
start(options?: {
|
||||||
/**
|
/**
|
||||||
* If specified, the trace is going to be saved into the file with the given name inside the `traceDir` folder specified in
|
* If specified, the trace is going to be saved into the file with the given name inside the `tracesDir` folder specified
|
||||||
* [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browsertypelaunchoptions).
|
* in [browserType.launch([options])](https://playwright.dev/docs/api/class-browsertype#browsertypelaunchoptions).
|
||||||
*/
|
*/
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
||||||
|
|
@ -11343,7 +11342,7 @@ export interface LaunchOptions {
|
||||||
/**
|
/**
|
||||||
* If specified, traces are saved into this directory.
|
* If specified, traces are saved into this directory.
|
||||||
*/
|
*/
|
||||||
traceDir?: string;
|
tracesDir?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConnectOverCDPOptions {
|
export interface ConnectOverCDPOptions {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue