fix(screencast): use viewport as default size (#3844)

This commit is contained in:
Yury Semikhatsky 2020-09-11 15:14:31 -07:00 committed by GitHub
parent c4adeb66ce
commit 40323aa94d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 75 additions and 24 deletions

View File

@ -220,7 +220,8 @@ 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.
- `_recordVideos` <[Object]> **experimental** Enables automatic video recording for new pages. The video will have frames with the provided dimensions. Actual picture of the page will be scaled down if necessary to fit specified size.
- `_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.
- returns: <[Promise]<[BrowserContext]>>
@ -265,7 +266,8 @@ 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.
- `_recordVideos` <[Object]> **experimental** Enables automatic video recording for the new page. The video will have frames with the provided dimensions. Actual picture of the page will be scaled down if necessary to fit specified size.
- `_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.
- returns: <[Promise]<[Page]>>
@ -792,7 +794,8 @@ const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
_videosPath: __dirname // Save videos to custom directory
});
const context = await browser.newContext({
_recordVideos: { width: 640, height: 360 }
_recordVideos: true,
_videoSize: { width: 640, height: 360 }
});
const page = await context.newPage();
const video = await page.waitForEvent('_videostarted');
@ -4268,7 +4271,8 @@ const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
- `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`'.
- `_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` <[Object]> **experimental** Enables automatic video recording for the new page. The video will have frames with the provided dimensions. Actual picture of the page will be scaled down if necessary to fit specified size.
- `_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.
- returns: <[Promise]<[BrowserContext]>> Promise that resolves to the persistent browser context instance.

View File

@ -37,7 +37,8 @@ const fs = require('fs');
_videosPath: __dirname,
});
const context = await browser.newContext({
_recordVideos: {width: 320, height: 240},
_recordVideos: true,
_videoSize: {width: 320, height: 240},
});
const page = await context.newPage();
const video = await page.waitForEvent('_videostarted');

View File

@ -371,7 +371,8 @@ export type BrowserNewContextParams = {
hasTouch?: boolean,
colorScheme?: 'dark' | 'light' | 'no-preference',
acceptDownloads?: boolean,
_recordVideos?: {
_recordVideos?: boolean,
_videoSize?: {
width: number,
height: number,
},
@ -408,7 +409,8 @@ export type BrowserNewContextOptions = {
hasTouch?: boolean,
colorScheme?: 'dark' | 'light' | 'no-preference',
acceptDownloads?: boolean,
_recordVideos?: {
_recordVideos?: boolean,
_videoSize?: {
width: number,
height: number,
},

View File

@ -367,7 +367,8 @@ Browser:
- light
- no-preference
acceptDownloads: boolean?
_recordVideos:
_recordVideos: boolean?
_videoSize:
type: object?
properties:
width: number

View File

@ -217,7 +217,8 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
hasTouch: tOptional(tBoolean),
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
acceptDownloads: tOptional(tBoolean),
_recordVideos: tOptional(tObject({
_recordVideos: tOptional(tBoolean),
_videoSize: tOptional(tObject({
width: tNumber,
height: tNumber,
})),

View File

@ -459,11 +459,13 @@ class FrameSession {
for (const source of this._crPage._page._evaluateOnNewDocumentSources)
promises.push(this._evaluateOnNewDocument(source));
if (this._crPage._browserContext._options._recordVideos) {
const contextOptions = this._crPage._browserContext._options._recordVideos;
const size = this._crPage._browserContext._options._videoSize || this._crPage._browserContext._options.viewport || { width: 1280, height: 720 };
const screencastId = createGuid();
const outputFile = path.join(this._crPage._browserContext._browser._options._videosPath!, screencastId + '.webm');
const options = Object.assign({}, contextOptions, {outputFile});
promises.push(this._startScreencast(screencastId, options));
promises.push(this._startScreencast(screencastId, {
...size,
outputFile,
}));
}
promises.push(this._client.send('Runtime.runIfWaitingForDebugger'));
promises.push(this._firstNonInitialNavigationCommittedPromise);

View File

@ -223,8 +223,9 @@ export class FFBrowserContext extends BrowserContext {
if (this._options.colorScheme)
promises.push(this._browser._connection.send('Browser.setColorScheme', { browserContextId, colorScheme: this._options.colorScheme }));
if (this._options._recordVideos) {
const size = this._options._videoSize || this._options.viewport || { width: 1280, height: 720 };
await this._browser._connection.send('Browser.setScreencastOptions', {
...this._options._recordVideos,
...size,
dir: this._browser._options._videosPath!,
browserContextId: this._browserContextId
});

View File

@ -238,10 +238,8 @@ export type BrowserContextOptions = {
hasTouch?: boolean,
colorScheme?: ColorScheme,
acceptDownloads?: boolean,
_recordVideos?: {
width: number,
height: number
}
_recordVideos?: boolean,
_videoSize?: Size,
};
export type EnvArray = { name: string, value: string }[];

View File

@ -114,10 +114,12 @@ export class WKPage implements PageDelegate {
this._grantPermissions(key, value);
}
if (this._browserContext._options._recordVideos) {
const contextOptions = this._browserContext._options._recordVideos;
const size = this._browserContext._options._videoSize || this._browserContext._options.viewport || { width: 1280, height: 720 };
const outputFile = path.join(this._browserContext._browser._options._videosPath!, createGuid() + '.webm');
const options = Object.assign({}, contextOptions, {outputFile});
promises.push(this.startScreencast(options));
promises.push(this.startScreencast({
...size,
outputFile,
}));
}
await Promise.all(promises);
}

View File

@ -235,7 +235,7 @@ describe('screencast', suite => {
it('should automatically start/finish when new page is created/closed', async ({browserType, defaultBrowserOptions, tmpDir}) => {
const browser = await browserType.launch({ ...defaultBrowserOptions, _videosPath: tmpDir });
const context = await browser.newContext({_recordVideos: {width: 320, height: 240}});
const context = await browser.newContext({ _recordVideos: true, _videoSize: { width: 320, height: 240 }});
const [screencast, newPage] = await Promise.all([
new Promise<any>(r => context.on('page', page => page.on('_videostarted', r))),
context.newPage(),
@ -252,7 +252,7 @@ describe('screencast', suite => {
it('should finish when contex closes', async ({browserType, defaultBrowserOptions, tmpDir}) => {
const browser = await browserType.launch({ ...defaultBrowserOptions, _videosPath: tmpDir });
const context = await browser.newContext({_recordVideos: {width: 320, height: 240}});
const context = await browser.newContext({ _recordVideos: true, _videoSize: { width: 320, height: 240 } });
const [video] = await Promise.all([
new Promise<any>(r => context.on('page', page => page.on('_videostarted', r))),
@ -269,7 +269,7 @@ describe('screencast', suite => {
});
it('should fire striclty after context.newPage', async ({browser}) => {
const context = await browser.newContext({_recordVideos: {width: 320, height: 240}});
const context = await browser.newContext({ _recordVideos: true, _videoSize: { width: 320, height: 240 } });
const page = await context.newPage();
// Should not hang.
await page.waitForEvent('_videostarted');
@ -278,7 +278,7 @@ describe('screencast', suite => {
it('should fire start event for popups', async ({browserType, defaultBrowserOptions, tmpDir, server}) => {
const browser = await browserType.launch({ ...defaultBrowserOptions, _videosPath: tmpDir });
const context = await browser.newContext({_recordVideos: {width: 320, height: 240}});
const context = await browser.newContext({ _recordVideos: true, _videoSize: { width: 320, height: 240 } });
const [page] = await Promise.all([
context.newPage(),
@ -339,4 +339,43 @@ describe('screencast', suite => {
expectAll(pixels, almostRed);
}
});
it('should use viewport as default size', async ({browser, page, tmpDir, videoPlayer, toImpl}) => {
const size = {width: 800, height: 600};
const context = await browser.newContext({_recordVideos: true, viewport: size});
const [video] = await Promise.all([
new Promise<any>(r => context.on('page', page => page.on('_videostarted', r))),
context.newPage(),
]);
await new Promise(r => setTimeout(r, 1000));
const [videoFile] = await Promise.all([
video.path(),
context.close(),
]);
expect(fs.existsSync(videoFile)).toBe(true);
await videoPlayer.load(videoFile);
expect(await videoPlayer.videoWidth()).toBe(size.width);
expect(await videoPlayer.videoHeight()).toBe(size.height);
});
it('should be 1280x720 by default', async ({browser, page, tmpDir, videoPlayer, toImpl}) => {
const context = await browser.newContext({_recordVideos: true});
const [video] = await Promise.all([
new Promise<any>(r => context.on('page', page => page.on('_videostarted', r))),
context.newPage(),
]);
await new Promise(r => setTimeout(r, 1000));
const [videoFile] = await Promise.all([
video.path(),
context.close(),
]);
expect(fs.existsSync(videoFile)).toBe(true);
await videoPlayer.load(videoFile);
expect(await videoPlayer.videoWidth()).toBe(1280);
expect(await videoPlayer.videoHeight()).toBe(720);
});
});