Skip to content

Commit c51bd43

Browse files
aslushnikovyury-s
andauthored
cherry-pick(release-1.11): fix video saving (#6671)
- Cherry-Pick PR #6648 SHA b946437 - Cherry-Pick PR #6664 SHA 2ef47b9 References microsoft/playwright-java#432 Co-authored-by: Yury Semikhatsky <[email protected]>
1 parent 6a9939d commit c51bd43

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed

src/server/browser.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import { RecentLogsCollector } from '../utils/debugLogger';
2424
import * as registry from '../utils/registry';
2525
import { SdkObject } from './instrumentation';
2626
import { Artifact } from './artifact';
27-
import { kBrowserClosedError } from '../utils/errors';
2827

2928
export interface BrowserProcess {
3029
onclose?: ((exitCode: number | null, signal: string | null) => void);
@@ -120,9 +119,6 @@ export abstract class Browser extends SdkObject {
120119
context._browserClosed();
121120
if (this._defaultContext)
122121
this._defaultContext._browserClosed();
123-
for (const video of this._idToVideo.values())
124-
video.artifact.reportFinished(kBrowserClosedError);
125-
this._idToVideo.clear();
126122
this.emit(Browser.Events.Disconnected);
127123
}
128124

src/server/chromium/crPage.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,9 +900,11 @@ class FrameSession {
900900
this._screencastId = null;
901901
const recorder = this._videoRecorder!;
902902
this._videoRecorder = null;
903-
const video = this._crPage._browserContext._browser._takeVideo(screencastId);
904903
await this._stopScreencast(recorder);
905904
await recorder.stop().catch(() => {});
905+
// Keep the video artifact in the map utntil encoding is fully finished, if the context
906+
// starts closing before the video is fully written to disk it will wait for it.
907+
const video = this._crPage._browserContext._browser._takeVideo(screencastId);
906908
video?.reportFinished();
907909
}
908910

src/server/firefox/ffBrowser.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18+
import { kBrowserClosedError } from '../../utils/errors';
1819
import { assert } from '../../utils/utils';
1920
import { Browser, BrowserOptions } from '../browser';
2021
import { assertBrowserContextIsNotOwned, BrowserContext, validateBrowserContextOptions, verifyGeolocation } from '../browserContext';
@@ -56,7 +57,7 @@ export class FFBrowser extends Browser {
5657
this._connection = connection;
5758
this._ffPages = new Map();
5859
this._contexts = new Map();
59-
this._connection.on(ConnectionEvents.Disconnected, () => this._didClose());
60+
this._connection.on(ConnectionEvents.Disconnected, () => this._onDisconnect());
6061
this._connection.on('Browser.attachedToTarget', this._onAttachedToTarget.bind(this));
6162
this._connection.on('Browser.detachedFromTarget', this._onDetachedFromTarget.bind(this));
6263
this._connection.on('Browser.downloadCreated', this._onDownloadCreated.bind(this));
@@ -136,6 +137,13 @@ export class FFBrowser extends Browser {
136137
_onScreencastFinished(payload: Protocol.Browser.screencastFinishedPayload) {
137138
this._takeVideo(payload.screencastId)?.reportFinished();
138139
}
140+
141+
_onDisconnect() {
142+
for (const video of this._idToVideo.values())
143+
video.artifact.reportFinished(kBrowserClosedError);
144+
this._idToVideo.clear();
145+
this._didClose();
146+
}
139147
}
140148

141149
export class FFBrowserContext extends BrowserContext {

src/server/webkit/wkBrowser.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import * as types from '../types';
2626
import { Protocol } from './protocol';
2727
import { kPageProxyMessageReceived, PageProxyMessageReceivedPayload, WKConnection, WKSession } from './wkConnection';
2828
import { WKPage } from './wkPage';
29+
import { kBrowserClosedError } from '../../utils/errors';
2930

3031
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.2 Safari/605.1.15';
3132
const BROWSER_VERSION = '14.2';
@@ -72,6 +73,9 @@ export class WKBrowser extends Browser {
7273
_onDisconnect() {
7374
for (const wkPage of this._wkPages.values())
7475
wkPage.dispose(true);
76+
for (const video of this._idToVideo.values())
77+
video.artifact.reportFinished(kBrowserClosedError);
78+
this._idToVideo.clear();
7579
this._didClose();
7680
}
7781

tests/screencast.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,4 +615,32 @@ it.describe('screencast', () => {
615615
const saveResult = await page.video().saveAs(file).catch(e => e);
616616
expect(saveResult.message).toContain('rowser has been closed');
617617
});
618+
619+
it('should wait for video to finish if page was closed', async ({browserType, browserOptions, contextOptions}, testInfo) => {
620+
const size = { width: 320, height: 240 };
621+
const browser = await browserType.launch(browserOptions);
622+
623+
const videoDir = testInfo.outputPath('');
624+
const context = await browser.newContext({
625+
...contextOptions,
626+
recordVideo: {
627+
dir: videoDir,
628+
size,
629+
},
630+
viewport: size,
631+
});
632+
633+
const page = await context.newPage();
634+
await new Promise(r => setTimeout(r, 1000));
635+
await page.close();
636+
await context.close();
637+
await browser.close();
638+
639+
const videoFiles = findVideos(videoDir);
640+
expect(videoFiles.length).toBe(1);
641+
const videoPlayer = new VideoPlayer(videoFiles[0]);
642+
expect(videoPlayer.videoWidth).toBe(320);
643+
expect(videoPlayer.videoHeight).toBe(240);
644+
});
645+
618646
});

0 commit comments

Comments
 (0)