fix: don't destroy BrowserView webContents when owning BrowserWindow hasn't been closed (#42372)

fix: don't destroy BrowserView webContents when owning BrowserWindow hasn't been closed (#42353)

* fix: moves bv webContents close to closed event

* chore: adds unit tests

* chore: test that bv webContents are destroyed when parent bw closed

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Anny Yang <anny@electronjs.org>
This commit is contained in:
trop[bot] 2024-06-10 07:40:53 -07:00 committed by GitHub
parent 993d3331fa
commit 0d12131f50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 54 additions and 5 deletions

View file

@ -54,7 +54,7 @@ BrowserWindow.prototype._init = function (this: BWT) {
this._browserViews = [];
this.on('close', () => {
this.on('closed', () => {
this._browserViews.forEach(b => b.webContents?.close({ waitForBeforeUnload: true }));
});

View file

@ -25,10 +25,12 @@ describe('BrowserView module', () => {
});
afterEach(async () => {
const p = once(w.webContents, 'destroyed');
await closeWindow(w);
w = null as any;
await p;
if (!w.isDestroyed()) {
const p = once(w.webContents, 'destroyed');
await closeWindow(w);
w = null as any;
await p;
}
if (view && view.webContents) {
const p = once(view.webContents, 'destroyed');
@ -534,6 +536,53 @@ describe('BrowserView module', () => {
});
describe('shutdown behavior', () => {
it('emits the destroyed event when the host BrowserWindow is closed', async () => {
view = new BrowserView();
w.addBrowserView(view);
await view.webContents.loadURL(`data:text/html,
<html>
<body>
<div id="bv_id">HELLO BROWSERVIEW</div>
</body>
</html>
`);
const query = 'document.getElementById("bv_id").textContent';
const contentBefore = await view.webContents.executeJavaScript(query);
expect(contentBefore).to.equal('HELLO BROWSERVIEW');
w.close();
const destroyed = once(view.webContents, 'destroyed');
const closed = once(w, 'closed');
await Promise.all([destroyed, closed]);
});
it('does not destroy its webContents if an owner BrowserWindow close event is prevented', async () => {
view = new BrowserView();
w.addBrowserView(view);
await view.webContents.loadURL(`data:text/html,
<html>
<body>
<div id="bv_id">HELLO BROWSERVIEW</div>
</body>
</html>
`);
const query = 'document.getElementById("bv_id").textContent';
const contentBefore = await view.webContents.executeJavaScript(query);
expect(contentBefore).to.equal('HELLO BROWSERVIEW');
w.once('close', (e) => {
e.preventDefault();
});
w.close();
const contentAfter = await view.webContents.executeJavaScript(query);
expect(contentAfter).to.equal('HELLO BROWSERVIEW');
});
it('does not crash on exit', async () => {
const rc = await startRemoteControlApp();
await rc.remotely(() => {