Repository: electron/electron
Pull request: fix: flaky utility and BrowserView tests

#### Description of Change

fixes a few reoccurring flaky tests I noticed in #44411

- Utility process checks for unique process name in crash details. Concurrent crashes can overlap causing problems. https://ci.appveyor.com/project/electron-bot/electron-woa-testing/builds/50882274/job/f4pqgi79du1fq2om/tests
- BrowserView tests ensure no WebContents exist before and after each test. Concurrently running non-BrowserView tests might be throwing this off.

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [x] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [ ] relevant documentation, tutorials, templates and examples are changed or added
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: none


Changed files:
filename: spec/api-browser-view-spec.ts
patch: @@ -1,4 +1,4 @@
-import { BrowserView, BrowserWindow, screen, webContents } from 'electron/main';
+import { BrowserView, BrowserWindow, screen, session, webContents } from 'electron/main';
 
 import { expect } from 'chai';
 
@@ -11,24 +11,29 @@ import { closeWindow } from './lib/window-helpers';
 
 describe('BrowserView module', () => {
   const fixtures = path.resolve(__dirname, 'fixtures');
+  const ses = session.fromPartition(crypto.randomUUID());
 
   let w: BrowserWindow;
   let view: BrowserView;
 
+  const getSessionWebContents = () =>
+    webContents.getAllWebContents().filter(wc => wc.session === ses);
+
   beforeEach(() => {
-    expect(webContents.getAllWebContents().length).to.equal(0, 'expected no webContents to exist');
+    expect(getSessionWebContents().length).to.equal(0, 'expected no webContents to exist');
     w = new BrowserWindow({
       show: false,
       width: 400,
       height: 400,
       webPreferences: {
-        backgroundThrottling: false
+        backgroundThrottling: false,
+        session: ses
       }
     });
   });
 
   afterEach(async () => {
-    if (!w.isDestroyed()) {
+    if (w && !w.isDestroyed()) {
       const p = once(w.webContents, 'destroyed');
       await closeWindow(w);
       w = null as any;
@@ -42,15 +47,15 @@ describe('BrowserView module', () => {
       await p;
     }
 
-    expect(webContents.getAllWebContents().length).to.equal(0, 'expected no webContents to exist');
+    expect(getSessionWebContents().length).to.equal(0, 'expected no webContents to exist');
   });
 
   it('sets the correct class name on the prototype', () => {
     expect(BrowserView.prototype.constructor.name).to.equal('BrowserView');
   });
 
   it('can be created with an existing webContents', async () => {
-    const wc = (webContents as typeof ElectronInternal.WebContents).create({ sandbox: true });
+    const wc = (webContents as typeof ElectronInternal.WebContents).create({ session: ses, sandbox: true });
     await wc.loadURL('about:blank');
 
     view = new BrowserView({ webContents: wc } as any);

filename: spec/api-utility-process-spec.ts
patch: @@ -144,21 +144,36 @@ describe('utilityProcess module', () => {
   });
 
   describe('app \'child-process-gone\' event', () => {
+    const waitForCrash = (name: string) => {
+      return new Promise<Electron.Details>((resolve) => {
+        app.on('child-process-gone', function onCrash (_event, details) {
+          if (details.name === name) {
+            app.off('child-process-gone', onCrash);
+            resolve(details);
+          }
+        });
+      });
+    };
+
     ifit(!isWindows32Bit)('with default serviceName', async () => {
+      const name = 'Node Utility Process';
+      const crashPromise = waitForCrash(name);
       utilityProcess.fork(path.join(fixturesPath, 'crash.js'));
-      const [, details] = await once(app, 'child-process-gone') as [any, Electron.Details];
+      const details = await crashPromise;
       expect(details.type).to.equal('Utility');
       expect(details.serviceName).to.equal('node.mojom.NodeService');
-      expect(details.name).to.equal('Node Utility Process');
+      expect(details.name).to.equal(name);
       expect(details.reason).to.be.oneOf(['crashed', 'abnormal-exit']);
     });
 
     ifit(!isWindows32Bit)('with custom serviceName', async () => {
-      utilityProcess.fork(path.join(fixturesPath, 'crash.js'), [], { serviceName: 'Hello World!' });
-      const [, details] = await once(app, 'child-process-gone') as [any, Electron.Details];
+      const name = crypto.randomUUID();
+      const crashPromise = waitForCrash(name);
+      utilityProcess.fork(path.join(fixturesPath, 'crash.js'), [], { serviceName: name });
+      const details = await crashPromise;
       expect(details.type).to.equal('Utility');
       expect(details.serviceName).to.equal('node.mojom.NodeService');
-      expect(details.name).to.equal('Hello World!');
+      expect(details.name).to.equal(name);
       expect(details.reason).to.be.oneOf(['crashed', 'abnormal-exit']);
     });
   });