Skip to content

Commit

Permalink
api(trace): introduce artifacts options (#3914)
Browse files Browse the repository at this point in the history
api(trace): introduce artifacts options

This introduces launch({ artifactsPath }) and newContext({ relativeArtifactsPath, recordTrace }) options.
- artifactsPath option controls the directory where all artifacts go. If not passed, artifacts are not collected.
- relativeArtifactsPath can be used to put context-specific artifacts into a subfolder. If not passed, shared artifactsPath is used.
- recordTrace controls trace recording.

We also expose trace types under playwright/types/trace.d.ts.

In the follow up:
- videos will be put into artifactsPath;
- downloads will be put into artifactsPath, or keep using existing downloadsPath when artifactsPath is not specified.
  • Loading branch information
dgozman authored Sep 18, 2020
1 parent bff9fb2 commit 0ade6af
Show file tree
Hide file tree
Showing 18 changed files with 204 additions and 121 deletions.
9 changes: 9 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,12 @@ Indicates that the browser is connected.
- `password` <[string]>
- `colorScheme` <"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. See [page.emulateMedia(options)](#pageemulatemediaoptions) for more details. Defaults to '`light`'.
- `logger` <[Logger]> Logger sink for Playwright logging.
- `relativeArtifactsPath` <[string]> Specifies a folder for artifacts like downloads, videos and traces, relative to `artifactsPath` from [`browserType.launch`](#browsertypelaunchoptions). Defaults to `.`.
- `_recordVideos` <[boolean]> **experimental** Enables automatic video recording for new pages.
- `_videoSize` <[Object]> **experimental** Specifies dimensions of the automatically recorded video. Can only be used if `_recordVideos` is true. If not specified the size will be equal to `viewport`. If `viewport` is not configured explicitly the video size defaults to 1280x720. Actual picture of the page will be scaled down if necessary to fit specified size.
- `width` <[number]> Video frame width.
- `height` <[number]> Video frame height.
- `recordTrace` <[boolean]> Enables trace recording to the `relativeArtifactsPath` folder.
- returns: <[Promise]<[BrowserContext]>>

Creates a new browser context. It won't share cookies/cache with other browser contexts.
Expand Down Expand Up @@ -266,10 +268,12 @@ Creates a new browser context. It won't share cookies/cache with other browser c
- `password` <[string]>
- `colorScheme` <"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. See [page.emulateMedia(options)](#pageemulatemediaoptions) for more details. Defaults to '`light`'.
- `logger` <[Logger]> Logger sink for Playwright logging.
- `relativeArtifactsPath` <[string]> Specifies a folder for artifacts like downloads, videos and traces, relative to `artifactsPath` from [`browserType.launch`](#browsertypelaunchoptions). Defaults to `.`.
- `_recordVideos` <[boolean]> **experimental** Enables automatic video recording for the new page.
- `_videoSize` <[Object]> **experimental** Specifies dimensions of the automatically recorded video. Can only be used if `_recordVideos` is true. If not specified the size will be equal to `viewport`. If `viewport` is not configured explicitly the video size defaults to 1280x720. Actual picture of the page will be scaled down if necessary to fit specified size.
- `width` <[number]> Video frame width.
- `height` <[number]> Video frame height.
- `recordTrace` <[boolean]> Enables trace recording to the `relativeArtifactsPath` folder.
- returns: <[Promise]<[Page]>>

Creates a new page in a new browser context. Closing this page will close the context as well.
Expand Down Expand Up @@ -4200,6 +4204,7 @@ This methods attaches Playwright to an existing browser instance.
- `username` <[string]> Optional username to use if HTTP proxy requires authentication.
- `password` <[string]> Optional password to use if HTTP proxy requires authentication.
- `downloadsPath` <[string]> If specified, accepted downloads are downloaded into this folder. Otherwise, temporary folder is created and is deleted when browser is closed.
- `artifactsPath` <[string]> Specifies a folder for various artifacts like downloads, videos and traces. If not specified, artifacts are not collected.
- `_videosPath` <[string]> **experimental** If specified, recorded videos are saved into this folder. Otherwise, temporary folder is created and is deleted when browser is closed.
- `chromiumSandbox` <[boolean]> Enable Chromium sandboxing. Defaults to `true`.
- `firefoxUserPrefs` <[Object]<[string], [string]|[number]|[boolean]>> Firefox user preferences. Learn more about the Firefox user preferences at [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox).
Expand Down Expand Up @@ -4243,6 +4248,7 @@ const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
- `password` <[string]> Optional password to use if HTTP proxy requires authentication.
- `acceptDownloads` <[boolean]> Whether to automatically download all the attachments. Defaults to `false` where all the downloads are canceled.
- `downloadsPath` <[string]> If specified, accepted downloads are downloaded into this folder. Otherwise, temporary folder is created and is deleted when browser is closed.
- `artifactsPath` <[string]> Specifies a folder for various artifacts like downloads, videos and traces. If not specified, artifacts are not collected.
- `chromiumSandbox` <[boolean]> Enable Chromium sandboxing. Defaults to `true`.
- `handleSIGINT` <[boolean]> Close the browser process on Ctrl-C. Defaults to `true`.
- `handleSIGTERM` <[boolean]> Close the browser process on SIGTERM. Defaults to `true`.
Expand Down Expand Up @@ -4275,11 +4281,13 @@ const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
- `username` <[string]>
- `password` <[string]>
- `colorScheme` <"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. See [page.emulateMedia(options)](#pageemulatemediaoptions) for more details. Defaults to '`light`'.
- `relativeArtifactsPath` <[string]> Specifies a folder for artifacts like downloads, videos and traces, relative to `artifactsPath`. Defaults to `.`.
- `_videosPath` <[string]> **experimental** If specified, recorded videos are saved into this folder. Otherwise, temporary folder is created and is deleted when browser is closed.
- `_recordVideos` <[boolean]> **experimental** Enables automatic video recording for new pages.
- `_videoSize` <[Object]> **experimental** Specifies dimensions of the automatically recorded video. Can only be used if `_recordVideos` is true. If not specified the size will be equal to `viewport`. If `viewport` is not configured explicitly the video size defaults to 1280x720. Actual picture of the page will be scaled down if necessary to fit specified size.
- `width` <[number]> Video frame width.
- `height` <[number]> Video frame height.
- `recordTrace` <[boolean]> Enables trace recording to the `relativeArtifactsPath` folder.
- returns: <[Promise]<[BrowserContext]>> Promise that resolves to the persistent browser context instance.

Launches browser that uses persistent storage located at `userDataDir` and returns the only context. Closing this context will automatically close the browser.
Expand All @@ -4297,6 +4305,7 @@ Launches browser that uses persistent storage located at `userDataDir` and retur
- `username` <[string]> Optional username to use if HTTP proxy requires authentication.
- `password` <[string]> Optional password to use if HTTP proxy requires authentication.
- `downloadsPath` <[string]> If specified, accepted downloads are downloaded into this folder. Otherwise, temporary folder is created and is deleted when browser is closed.
- `artifactsPath` <[string]> Specifies a folder for various artifacts like downloads, videos and traces. If not specified, artifacts are not collected.
- `_videosPath` <[string]> **experimental** If specified, recorded videos are saved into this folder. Otherwise, temporary folder is created and is deleted when browser is closed.
- `chromiumSandbox` <[boolean]> Enable Chromium sandboxing. Defaults to `true`.
- `firefoxUserPrefs` <[Object]<[string], [string]|[number]|[boolean]>> Firefox user preferences. Learn more about the Firefox user preferences at [`about:config`](https://support.mozilla.org/en-US/kb/about-config-editor-firefox).
Expand Down
1 change: 1 addition & 0 deletions src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export type LaunchServerOptions = {
password?: string
},
downloadsPath?: string,
artifactsPath?: string,
_videosPath?: string,
chromiumSandbox?: boolean,
port?: number,
Expand Down
2 changes: 2 additions & 0 deletions src/inprocess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import { PlaywrightDispatcher } from './dispatchers/playwrightDispatcher';
import { Connection } from './client/connection';
import { BrowserServerLauncherImpl } from './browserServerImpl';
import { installDebugController } from './debug/debugController';
import { installTracer } from './trace/tracer';

export function setupInProcess(playwright: PlaywrightImpl): PlaywrightAPI {
installDebugController();
installTracer();

const clientConnection = new Connection();
const dispatcherConnection = new DispatcherConnection();
Expand Down
12 changes: 12 additions & 0 deletions src/protocol/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export type BrowserTypeLaunchParams = {
password?: string,
},
downloadsPath?: string,
artifactsPath?: string,
_videosPath?: string,
firefoxUserPrefs?: any,
chromiumSandbox?: boolean,
Expand Down Expand Up @@ -195,6 +196,7 @@ export type BrowserTypeLaunchOptions = {
password?: string,
},
downloadsPath?: string,
artifactsPath?: string,
_videosPath?: string,
firefoxUserPrefs?: any,
chromiumSandbox?: boolean,
Expand Down Expand Up @@ -226,6 +228,7 @@ export type BrowserTypeLaunchPersistentContextParams = {
password?: string,
},
downloadsPath?: string,
artifactsPath?: string,
_videosPath?: string,
chromiumSandbox?: boolean,
slowMo?: number,
Expand Down Expand Up @@ -260,6 +263,8 @@ export type BrowserTypeLaunchPersistentContextParams = {
hasTouch?: boolean,
colorScheme?: 'light' | 'dark' | 'no-preference',
acceptDownloads?: boolean,
relativeArtifactsPath?: string,
recordTrace?: boolean,
};
export type BrowserTypeLaunchPersistentContextOptions = {
executablePath?: string,
Expand All @@ -283,6 +288,7 @@ export type BrowserTypeLaunchPersistentContextOptions = {
password?: string,
},
downloadsPath?: string,
artifactsPath?: string,
_videosPath?: string,
chromiumSandbox?: boolean,
slowMo?: number,
Expand Down Expand Up @@ -317,6 +323,8 @@ export type BrowserTypeLaunchPersistentContextOptions = {
hasTouch?: boolean,
colorScheme?: 'light' | 'dark' | 'no-preference',
acceptDownloads?: boolean,
relativeArtifactsPath?: string,
recordTrace?: boolean,
};
export type BrowserTypeLaunchPersistentContextResult = {
context: BrowserContextChannel,
Expand Down Expand Up @@ -371,6 +379,8 @@ export type BrowserNewContextParams = {
hasTouch?: boolean,
colorScheme?: 'dark' | 'light' | 'no-preference',
acceptDownloads?: boolean,
relativeArtifactsPath?: string,
recordTrace?: boolean,
_recordVideos?: boolean,
_videoSize?: {
width: number,
Expand Down Expand Up @@ -409,6 +419,8 @@ export type BrowserNewContextOptions = {
hasTouch?: boolean,
colorScheme?: 'dark' | 'light' | 'no-preference',
acceptDownloads?: boolean,
relativeArtifactsPath?: string,
recordTrace?: boolean,
_recordVideos?: boolean,
_videoSize?: {
width: number,
Expand Down
6 changes: 6 additions & 0 deletions src/protocol/protocol.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ BrowserType:
username: string?
password: string?
downloadsPath: string?
artifactsPath: string?
_videosPath: string?
firefoxUserPrefs: json?
chromiumSandbox: boolean?
Expand Down Expand Up @@ -259,6 +260,7 @@ BrowserType:
username: string?
password: string?
downloadsPath: string?
artifactsPath: string?
_videosPath: string?
chromiumSandbox: boolean?
slowMo: number?
Expand Down Expand Up @@ -306,6 +308,8 @@ BrowserType:
- dark
- no-preference
acceptDownloads: boolean?
relativeArtifactsPath: string?
recordTrace: boolean?
returns:
context: BrowserContext

Expand Down Expand Up @@ -367,6 +371,8 @@ Browser:
- light
- no-preference
acceptDownloads: boolean?
relativeArtifactsPath: string?
recordTrace: boolean?
_recordVideos: boolean?
_videoSize:
type: object?
Expand Down
6 changes: 6 additions & 0 deletions src/protocol/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
password: tOptional(tString),
})),
downloadsPath: tOptional(tString),
artifactsPath: tOptional(tString),
_videosPath: tOptional(tString),
firefoxUserPrefs: tOptional(tAny),
chromiumSandbox: tOptional(tBoolean),
Expand Down Expand Up @@ -149,6 +150,7 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
password: tOptional(tString),
})),
downloadsPath: tOptional(tString),
artifactsPath: tOptional(tString),
_videosPath: tOptional(tString),
chromiumSandbox: tOptional(tBoolean),
slowMo: tOptional(tNumber),
Expand Down Expand Up @@ -183,6 +185,8 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
hasTouch: tOptional(tBoolean),
colorScheme: tOptional(tEnum(['light', 'dark', 'no-preference'])),
acceptDownloads: tOptional(tBoolean),
relativeArtifactsPath: tOptional(tString),
recordTrace: tOptional(tBoolean),
});
scheme.BrowserCloseParams = tOptional(tObject({}));
scheme.BrowserNewContextParams = tObject({
Expand Down Expand Up @@ -217,6 +221,8 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
hasTouch: tOptional(tBoolean),
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
acceptDownloads: tOptional(tBoolean),
relativeArtifactsPath: tOptional(tString),
recordTrace: tOptional(tBoolean),
_recordVideos: tOptional(tBoolean),
_videoSize: tOptional(tObject({
width: tNumber,
Expand Down
2 changes: 2 additions & 0 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import { PlaywrightDispatcher } from './dispatchers/playwrightDispatcher';
import { Electron } from './server/electron/electron';
import { gracefullyCloseAll } from './server/processLauncher';
import { installDebugController } from './debug/debugController';
import { installTracer } from './trace/tracer';

installDebugController();
installTracer();

const dispatcherConnection = new DispatcherConnection();
const transport = new Transport(process.stdout, process.stdin);
Expand Down
1 change: 1 addition & 0 deletions src/server/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface BrowserProcess {

export type BrowserOptions = types.UIOptions & {
name: string,
artifactsPath?: string,
downloadsPath?: string,
_videosPath?: string,
headful?: boolean,
Expand Down
7 changes: 7 additions & 0 deletions src/server/browserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Page, PageBinding } from './page';
import { Progress, ProgressController, ProgressResult } from './progress';
import { Selectors, serverSelectors } from './selectors';
import * as types from './types';
import * as path from 'path';

export class Video {
private readonly _path: string;
Expand Down Expand Up @@ -92,13 +93,19 @@ export abstract class BrowserContext extends EventEmitter {
readonly _browserContextId: string | undefined;
private _selectors?: Selectors;
readonly _actionListeners = new Set<ActionListener>();
readonly _artifactsPath?: string;

constructor(browser: Browser, options: types.BrowserContextOptions, browserContextId: string | undefined) {
super();
this._browser = browser;
this._options = options;
this._browserContextId = browserContextId;
this._isPersistentContext = !browserContextId;
if (browser._options.artifactsPath) {
this._artifactsPath = browser._options.artifactsPath;
if (options.relativeArtifactsPath)
this._artifactsPath = path.join(this._artifactsPath, options.relativeArtifactsPath);
}
this._closePromise = new Promise(fulfill => this._closePromiseFulfill = fulfill);
}

Expand Down
2 changes: 2 additions & 0 deletions src/server/browserType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export abstract class BrowserType {
slowMo: options.slowMo,
persistent,
headful: !options.headless,
artifactsPath: options.artifactsPath,
downloadsPath,
_videosPath,
browserProcess,
Expand Down Expand Up @@ -134,6 +135,7 @@ export abstract class BrowserType {
}
return dir;
};
// TODO: use artifactsPath for downloads and videos.
const downloadsPath = await ensurePath(DOWNLOADS_FOLDER, options.downloadsPath);
const _videosPath = await ensurePath(VIDEOS_FOLDER, options._videosPath);

Expand Down
3 changes: 3 additions & 0 deletions src/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ export type BrowserContextOptions = {
acceptDownloads?: boolean,
_recordVideos?: boolean,
_videoSize?: Size,
recordTrace?: boolean,
relativeArtifactsPath?: string,
};

export type EnvArray = { name: string, value: string }[];
Expand All @@ -257,6 +259,7 @@ type LaunchOptionsBase = {
headless?: boolean,
devtools?: boolean,
proxy?: ProxySettings,
artifactsPath?: string,
downloadsPath?: string,
_videosPath?: string,
chromiumSandbox?: boolean,
Expand Down
13 changes: 1 addition & 12 deletions src/trace/snapshotter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import * as types from '../server/types';
import { SnapshotData, takeSnapshotInFrame } from './snapshotterInjected';
import { assert, calculateSha1, createGuid } from '../utils/utils';
import { ElementHandle } from '../server/dom';
import { FrameSnapshot, PageSnapshot } from './traceTypes';

export type SnapshotterResource = {
pageId: string,
Expand All @@ -41,18 +42,6 @@ export type SnapshotterBlob = {
sha1: string,
};

export type FrameSnapshot = {
frameId: string,
url: string,
html: string,
resourceOverrides: { url: string, sha1: string }[],
};
export type PageSnapshot = {
viewportSize?: { width: number, height: number },
// First frame is the main frame.
frames: FrameSnapshot[],
};

export interface SnapshotterDelegate {
onBlob(blob: SnapshotterBlob): void;
onResource(resource: SnapshotterResource): void;
Expand Down
22 changes: 22 additions & 0 deletions src/trace/traceTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,25 @@ export type ActionTraceEvent = {
stack?: string,
error?: string,
};

export type TraceEvent =
ContextCreatedTraceEvent |
ContextDestroyedTraceEvent |
PageCreatedTraceEvent |
PageDestroyedTraceEvent |
NetworkResourceTraceEvent |
ActionTraceEvent;


export type FrameSnapshot = {
frameId: string,
url: string,
html: string,
resourceOverrides: { url: string, sha1: string }[],
};

export type PageSnapshot = {
viewportSize?: { width: number, height: number },
// First frame is the main frame.
frames: FrameSnapshot[],
};
Loading

0 comments on commit 0ade6af

Please sign in to comment.