fix(screencast): use viewport as default size (#3844)
This commit is contained in:
Родитель
c4adeb66ce
Коммит
40323aa94d
12
docs/api.md
12
docs/api.md
|
@ -220,7 +220,8 @@ Indicates that the browser is connected.
|
||||||
- `password` <[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`'.
|
- `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.
|
- `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.
|
- `width` <[number]> Video frame width.
|
||||||
- `height` <[number]> Video frame height.
|
- `height` <[number]> Video frame height.
|
||||||
- returns: <[Promise]<[BrowserContext]>>
|
- returns: <[Promise]<[BrowserContext]>>
|
||||||
|
@ -265,7 +266,8 @@ Creates a new browser context. It won't share cookies/cache with other browser c
|
||||||
- `password` <[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`'.
|
- `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.
|
- `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.
|
- `width` <[number]> Video frame width.
|
||||||
- `height` <[number]> Video frame height.
|
- `height` <[number]> Video frame height.
|
||||||
- returns: <[Promise]<[Page]>>
|
- returns: <[Promise]<[Page]>>
|
||||||
|
@ -792,7 +794,8 @@ const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
|
||||||
_videosPath: __dirname // Save videos to custom directory
|
_videosPath: __dirname // Save videos to custom directory
|
||||||
});
|
});
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
_recordVideos: { width: 640, height: 360 }
|
_recordVideos: true,
|
||||||
|
_videoSize: { width: 640, height: 360 }
|
||||||
});
|
});
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
const video = await page.waitForEvent('_videostarted');
|
const video = await page.waitForEvent('_videostarted');
|
||||||
|
@ -4268,7 +4271,8 @@ const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
|
||||||
- `password` <[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`'.
|
- `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.
|
- `_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.
|
- `width` <[number]> Video frame width.
|
||||||
- `height` <[number]> Video frame height.
|
- `height` <[number]> Video frame height.
|
||||||
- returns: <[Promise]<[BrowserContext]>> Promise that resolves to the persistent browser context instance.
|
- returns: <[Promise]<[BrowserContext]>> Promise that resolves to the persistent browser context instance.
|
||||||
|
|
|
@ -37,7 +37,8 @@ const fs = require('fs');
|
||||||
_videosPath: __dirname,
|
_videosPath: __dirname,
|
||||||
});
|
});
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
_recordVideos: {width: 320, height: 240},
|
_recordVideos: true,
|
||||||
|
_videoSize: {width: 320, height: 240},
|
||||||
});
|
});
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
const video = await page.waitForEvent('_videostarted');
|
const video = await page.waitForEvent('_videostarted');
|
||||||
|
|
|
@ -371,7 +371,8 @@ export type BrowserNewContextParams = {
|
||||||
hasTouch?: boolean,
|
hasTouch?: boolean,
|
||||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_recordVideos?: {
|
_recordVideos?: boolean,
|
||||||
|
_videoSize?: {
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
},
|
},
|
||||||
|
@ -408,7 +409,8 @@ export type BrowserNewContextOptions = {
|
||||||
hasTouch?: boolean,
|
hasTouch?: boolean,
|
||||||
colorScheme?: 'dark' | 'light' | 'no-preference',
|
colorScheme?: 'dark' | 'light' | 'no-preference',
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_recordVideos?: {
|
_recordVideos?: boolean,
|
||||||
|
_videoSize?: {
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
},
|
},
|
||||||
|
|
|
@ -367,7 +367,8 @@ Browser:
|
||||||
- light
|
- light
|
||||||
- no-preference
|
- no-preference
|
||||||
acceptDownloads: boolean?
|
acceptDownloads: boolean?
|
||||||
_recordVideos:
|
_recordVideos: boolean?
|
||||||
|
_videoSize:
|
||||||
type: object?
|
type: object?
|
||||||
properties:
|
properties:
|
||||||
width: number
|
width: number
|
||||||
|
|
|
@ -217,7 +217,8 @@ export function createScheme(tChannel: (name: string) => Validator): Scheme {
|
||||||
hasTouch: tOptional(tBoolean),
|
hasTouch: tOptional(tBoolean),
|
||||||
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
|
colorScheme: tOptional(tEnum(['dark', 'light', 'no-preference'])),
|
||||||
acceptDownloads: tOptional(tBoolean),
|
acceptDownloads: tOptional(tBoolean),
|
||||||
_recordVideos: tOptional(tObject({
|
_recordVideos: tOptional(tBoolean),
|
||||||
|
_videoSize: tOptional(tObject({
|
||||||
width: tNumber,
|
width: tNumber,
|
||||||
height: tNumber,
|
height: tNumber,
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -459,11 +459,13 @@ class FrameSession {
|
||||||
for (const source of this._crPage._page._evaluateOnNewDocumentSources)
|
for (const source of this._crPage._page._evaluateOnNewDocumentSources)
|
||||||
promises.push(this._evaluateOnNewDocument(source));
|
promises.push(this._evaluateOnNewDocument(source));
|
||||||
if (this._crPage._browserContext._options._recordVideos) {
|
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 screencastId = createGuid();
|
||||||
const outputFile = path.join(this._crPage._browserContext._browser._options._videosPath!, screencastId + '.webm');
|
const outputFile = path.join(this._crPage._browserContext._browser._options._videosPath!, screencastId + '.webm');
|
||||||
const options = Object.assign({}, contextOptions, {outputFile});
|
promises.push(this._startScreencast(screencastId, {
|
||||||
promises.push(this._startScreencast(screencastId, options));
|
...size,
|
||||||
|
outputFile,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
promises.push(this._client.send('Runtime.runIfWaitingForDebugger'));
|
promises.push(this._client.send('Runtime.runIfWaitingForDebugger'));
|
||||||
promises.push(this._firstNonInitialNavigationCommittedPromise);
|
promises.push(this._firstNonInitialNavigationCommittedPromise);
|
||||||
|
|
|
@ -223,8 +223,9 @@ export class FFBrowserContext extends BrowserContext {
|
||||||
if (this._options.colorScheme)
|
if (this._options.colorScheme)
|
||||||
promises.push(this._browser._connection.send('Browser.setColorScheme', { browserContextId, colorScheme: this._options.colorScheme }));
|
promises.push(this._browser._connection.send('Browser.setColorScheme', { browserContextId, colorScheme: this._options.colorScheme }));
|
||||||
if (this._options._recordVideos) {
|
if (this._options._recordVideos) {
|
||||||
|
const size = this._options._videoSize || this._options.viewport || { width: 1280, height: 720 };
|
||||||
await this._browser._connection.send('Browser.setScreencastOptions', {
|
await this._browser._connection.send('Browser.setScreencastOptions', {
|
||||||
...this._options._recordVideos,
|
...size,
|
||||||
dir: this._browser._options._videosPath!,
|
dir: this._browser._options._videosPath!,
|
||||||
browserContextId: this._browserContextId
|
browserContextId: this._browserContextId
|
||||||
});
|
});
|
||||||
|
|
|
@ -238,10 +238,8 @@ export type BrowserContextOptions = {
|
||||||
hasTouch?: boolean,
|
hasTouch?: boolean,
|
||||||
colorScheme?: ColorScheme,
|
colorScheme?: ColorScheme,
|
||||||
acceptDownloads?: boolean,
|
acceptDownloads?: boolean,
|
||||||
_recordVideos?: {
|
_recordVideos?: boolean,
|
||||||
width: number,
|
_videoSize?: Size,
|
||||||
height: number
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EnvArray = { name: string, value: string }[];
|
export type EnvArray = { name: string, value: string }[];
|
||||||
|
|
|
@ -114,10 +114,12 @@ export class WKPage implements PageDelegate {
|
||||||
this._grantPermissions(key, value);
|
this._grantPermissions(key, value);
|
||||||
}
|
}
|
||||||
if (this._browserContext._options._recordVideos) {
|
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 outputFile = path.join(this._browserContext._browser._options._videosPath!, createGuid() + '.webm');
|
||||||
const options = Object.assign({}, contextOptions, {outputFile});
|
promises.push(this.startScreencast({
|
||||||
promises.push(this.startScreencast(options));
|
...size,
|
||||||
|
outputFile,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,7 @@ describe('screencast', suite => {
|
||||||
|
|
||||||
it('should automatically start/finish when new page is created/closed', async ({browserType, defaultBrowserOptions, tmpDir}) => {
|
it('should automatically start/finish when new page is created/closed', async ({browserType, defaultBrowserOptions, tmpDir}) => {
|
||||||
const browser = await browserType.launch({ ...defaultBrowserOptions, _videosPath: 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([
|
const [screencast, newPage] = await Promise.all([
|
||||||
new Promise<any>(r => context.on('page', page => page.on('_videostarted', r))),
|
new Promise<any>(r => context.on('page', page => page.on('_videostarted', r))),
|
||||||
context.newPage(),
|
context.newPage(),
|
||||||
|
@ -252,7 +252,7 @@ describe('screencast', suite => {
|
||||||
|
|
||||||
it('should finish when contex closes', async ({browserType, defaultBrowserOptions, tmpDir}) => {
|
it('should finish when contex closes', async ({browserType, defaultBrowserOptions, tmpDir}) => {
|
||||||
const browser = await browserType.launch({ ...defaultBrowserOptions, _videosPath: 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([
|
const [video] = await Promise.all([
|
||||||
new Promise<any>(r => context.on('page', page => page.on('_videostarted', r))),
|
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}) => {
|
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();
|
const page = await context.newPage();
|
||||||
// Should not hang.
|
// Should not hang.
|
||||||
await page.waitForEvent('_videostarted');
|
await page.waitForEvent('_videostarted');
|
||||||
|
@ -278,7 +278,7 @@ describe('screencast', suite => {
|
||||||
|
|
||||||
it('should fire start event for popups', async ({browserType, defaultBrowserOptions, tmpDir, server}) => {
|
it('should fire start event for popups', async ({browserType, defaultBrowserOptions, tmpDir, server}) => {
|
||||||
const browser = await browserType.launch({ ...defaultBrowserOptions, _videosPath: 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 [page] = await Promise.all([
|
const [page] = await Promise.all([
|
||||||
context.newPage(),
|
context.newPage(),
|
||||||
|
@ -339,4 +339,43 @@ describe('screencast', suite => {
|
||||||
expectAll(pixels, almostRed);
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
Загрузка…
Ссылка в новой задаче