Skip to content

Commit e989a10

Browse files
committed
chore: restore the missing video event
1 parent 9daedac commit e989a10

File tree

9 files changed

+114
-1
lines changed

9 files changed

+114
-1
lines changed

docs/api.md

+40
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- [class: ConsoleMessage](#class-consolemessage)
1515
- [class: Dialog](#class-dialog)
1616
- [class: Download](#class-download)
17+
- [class: Video](#class-video)
1718
- [class: FileChooser](#class-filechooser)
1819
- [class: Keyboard](#class-keyboard)
1920
- [class: Mouse](#class-mouse)
@@ -307,6 +308,7 @@ await context.close();
307308
<!-- GEN:toc -->
308309
- [event: 'close'](#event-close)
309310
- [event: 'page'](#event-page)
311+
- [event: 'video'](#event-video)
310312
- [browserContext.addCookies(cookies)](#browsercontextaddcookiescookies)
311313
- [browserContext.addInitScript(script[, arg])](#browsercontextaddinitscriptscript-arg)
312314
- [browserContext.browser()](#browsercontextbrowser)
@@ -354,6 +356,13 @@ console.log(await page.evaluate('location.href'));
354356

355357
> **NOTE** Use [`page.waitForLoadState([state[, options]])`](#pagewaitforloadstatestate-options) to wait until the page gets to a particular state (you should not need it in most cases).
356358
359+
#### event: 'video'
360+
- <[Video]>
361+
362+
Emitted when the video recording is started. User can access video file information via the passed [Video] instance.
363+
364+
> **NOTE** Browser context **must** be created with the `videosPath` set to record videos.
365+
357366
#### browserContext.addCookies(cookies)
358367
- `cookies` <[Array]<[Object]>>
359368
- `name` <[string]> **required**
@@ -3429,6 +3438,36 @@ Returns suggested filename for this download. It is typically computed by the br
34293438
Returns downloaded url.
34303439

34313440

3441+
### class: Video
3442+
3443+
[Video] objects are dispatched by the browser context via the ['video'](#event-video) event.
3444+
3445+
All the video files generated for the browser context are reported with this event. Video event is emitted once the video starts. Video itself becomes available once browser context closes:
3446+
3447+
```js
3448+
context.on('video', video => {
3449+
console.log(video.page().url(), video.path());
3450+
})
3451+
```
3452+
3453+
> **NOTE** Browser context **must** be created with the `videosPath` set to record videos.
3454+
3455+
<!-- GEN:toc -->
3456+
- [video.page()](#videopage)
3457+
- [video.path()](#videopath)
3458+
<!-- GEN:stop -->
3459+
3460+
#### video.page()
3461+
- returns: <[Page]>
3462+
3463+
Returns the page this video is recorder for.
3464+
3465+
#### video.path()
3466+
- returns: <[string]>
3467+
3468+
Returns the file system path this video is recorder to.
3469+
3470+
34323471
### class: FileChooser
34333472

34343473
[FileChooser] objects are dispatched by the page in the ['filechooser'](#event-filechooser) event.
@@ -4436,6 +4475,7 @@ const backgroundPage = await context.waitForEvent('backgroundpage');
44364475
<!-- GEN:toc-extends-BrowserContext -->
44374476
- [event: 'close'](#event-close)
44384477
- [event: 'page'](#event-page)
4478+
- [event: 'video'](#event-video)
44394479
- [browserContext.addCookies(cookies)](#browsercontextaddcookiescookies)
44404480
- [browserContext.addInitScript(script[, arg])](#browsercontextaddinitscriptscript-arg)
44414481
- [browserContext.browser()](#browsercontextbrowser)

src/client/api.ts

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export { JSHandle } from './jsHandle';
3232
export { Request, Response, Route } from './network';
3333
export { Page } from './page';
3434
export { Selectors } from './selectors';
35+
export { Video } from './video';
3536
export { Worker } from './worker';
3637

3738
export { ChromiumBrowser } from './chromiumBrowser';

src/client/events.ts

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export const Events = {
2323
BrowserContext: {
2424
Close: 'close',
2525
Page: 'page',
26+
Video: 'video',
2627
},
2728

2829
BrowserServer: {

src/client/page.ts

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import { Size, URLMatch, Headers, LifecycleEvent, WaitForEventOptions, SelectOpt
4444
import { evaluationScript, urlMatches } from './clientHelper';
4545
import { isString, isRegExp, isObject, mkdirIfNeeded, headersObjectToArray } from '../utils/utils';
4646
import { isSafeCloseError } from '../utils/errors';
47+
import { Video } from './video';
4748

4849
const fsWriteFileAsync = util.promisify(fs.writeFile.bind(fs));
4950
const mkdirAsync = util.promisify(fs.mkdir);
@@ -125,6 +126,7 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
125126
this._channel.on('requestFinished', ({ request }) => this.emit(Events.Page.RequestFinished, Request.from(request)));
126127
this._channel.on('response', ({ response }) => this.emit(Events.Page.Response, Response.from(response)));
127128
this._channel.on('route', ({ route, request }) => this._onRoute(Route.from(route), Request.from(request)));
129+
this._channel.on('video', ({ path }) => this._onVideo(path));
128130
this._channel.on('worker', ({ worker }) => this._onWorker(Worker.from(worker)));
129131

130132
if (this._browserContext._browserName === 'chromium') {
@@ -173,6 +175,10 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
173175
this._browserContext._onBinding(bindingCall);
174176
}
175177

178+
_onVideo(path: string): void {
179+
this._browserContext.emit(Events.BrowserContext.Video, new Video(this, path));
180+
}
181+
176182
_onWorker(worker: Worker): void {
177183
this._workers.add(worker);
178184
worker._page = this;

src/client/video.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright (c) Microsoft Corporation.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { Page } from './page';
18+
19+
export class Video {
20+
private _page: Page;
21+
private _path: string;
22+
23+
constructor(page: Page, path: string) {
24+
this._page = page;
25+
this._path = path;
26+
}
27+
28+
page(): Page {
29+
return this._page;
30+
}
31+
32+
path(): string {
33+
return this._path;
34+
}
35+
}

src/dispatchers/pageDispatcher.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { BrowserContext, runAction } from '../server/browserContext';
17+
import { BrowserContext, runAction, Video } from '../server/browserContext';
1818
import { Frame } from '../server/frames';
1919
import { Request } from '../server/network';
2020
import { Page, Worker } from '../server/page';
@@ -66,6 +66,7 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageInitializer> i
6666
}));
6767
page.on(Page.Events.RequestFinished, request => this._dispatchEvent('requestFinished', { request: RequestDispatcher.from(scope, request) }));
6868
page.on(Page.Events.Response, response => this._dispatchEvent('response', { response: new ResponseDispatcher(this._scope, response) }));
69+
page.on(Page.Events.VideoStarted, (video: Video) => this._dispatchEvent('video', { path: video._path }));
6970
page.on(Page.Events.Worker, worker => this._dispatchEvent('worker', { worker: new WorkerDispatcher(this._scope, worker) }));
7071
}
7172

src/protocol/channels.ts

+4
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ export interface PageChannel extends Channel {
683683
on(event: 'requestFinished', callback: (params: PageRequestFinishedEvent) => void): this;
684684
on(event: 'response', callback: (params: PageResponseEvent) => void): this;
685685
on(event: 'route', callback: (params: PageRouteEvent) => void): this;
686+
on(event: 'video', callback: (params: PageVideoEvent) => void): this;
686687
on(event: 'worker', callback: (params: PageWorkerEvent) => void): this;
687688
setDefaultNavigationTimeoutNoReply(params: PageSetDefaultNavigationTimeoutNoReplyParams, metadata?: Metadata): Promise<PageSetDefaultNavigationTimeoutNoReplyResult>;
688689
setDefaultTimeoutNoReply(params: PageSetDefaultTimeoutNoReplyParams, metadata?: Metadata): Promise<PageSetDefaultTimeoutNoReplyResult>;
@@ -765,6 +766,9 @@ export type PageRouteEvent = {
765766
route: RouteChannel,
766767
request: RequestChannel,
767768
};
769+
export type PageVideoEvent = {
770+
path: string,
771+
};
768772
export type PageWorkerEvent = {
769773
worker: WorkerChannel,
770774
};

src/protocol/protocol.yml

+4
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,10 @@ Page:
927927
route: Route
928928
request: Request
929929

930+
video:
931+
parameters:
932+
path: string
933+
930934
worker:
931935
parameters:
932936
worker: Worker

test/screencast.spec.ts

+21
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,27 @@ describe('screencast', suite => {
180180
}
181181
});
182182

183+
it('should emit video event', async ({browser, testInfo}) => {
184+
const videosPath = testInfo.outputPath('');
185+
const size = { width: 320, height: 240 };
186+
const context = await browser.newContext({
187+
videosPath,
188+
viewport: size,
189+
videoSize: size
190+
});
191+
const videos = [];
192+
context.on('video', video => {
193+
videos.push(video);
194+
});
195+
const page = await context.newPage();
196+
await page.evaluate(() => document.body.style.backgroundColor = 'red');
197+
await new Promise(r => setTimeout(r, 1000));
198+
await context.close();
199+
expect(videos.length).toBe(1);
200+
expect(videos[0].path()).toContain(videosPath);
201+
expect(videos[0].page()).toBe(page);
202+
});
203+
183204
it('should capture navigation', async ({browser, server, testInfo}) => {
184205
const videosPath = testInfo.outputPath('');
185206
const context = await browser.newContext({

0 commit comments

Comments
 (0)