Skip to content

Commit 414ae00

Browse files
authored
fix(electron): handle in-event await errors (#2207)
1 parent ebceaf4 commit 414ae00

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

packages/playwright-electron/README.md

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ app.whenReady().then(createWindow);
5858

5959
`test/spec.js` - test file
6060
```js
61-
6261
const { electron } = require('playwright-electron');
6362
const assert = require('assert');
6463
const electronPath = require('electron');
@@ -80,25 +79,80 @@ describe('Sanity checks', function () {
8079
await this.app.close();
8180
});
8281

83-
it('sanity checks', async () => {
84-
// Wait for the first window to appear.
85-
const window = await this.app.firstWindow();
82+
it('script application', async () => {
83+
const appPath = await this.app.evaluate(async ({ app }) => {
84+
// This runs in the main Electron process, first parameter is
85+
// the result of the require('electron') in the main app script.
86+
return app.getAppPath();
87+
});
88+
assert.equal(appPath, path.join(__dirname, '..'));
89+
});
8690

87-
// Assert window title.
88-
assert.equal(await window.title(), 'Hello World!');
91+
it('window title', async () => {
92+
// Return value of this.app.firstWindow a Playwright Page.
93+
// See https://playwright.dev/#path=docs%2Fapi.md&q=class-page.
94+
95+
// Get a Playwright page for the first Electron window.
96+
// It awaits for the page to be available. Alternatively use
97+
// this.app.windows() or this.app.waitForEvent('window').
98+
const page = await this.app.firstWindow();
99+
assert.equal(await page.title(), 'Hello World!');
100+
});
101+
102+
it('capture screenshot', async () => {
103+
const page = await this.app.firstWindow();
89104

90105
// Capture window screenshot.
91-
await window.screenshot({ path: 'intro.png' });
106+
await page.screenshot({ path: 'intro.png' });
107+
});
108+
109+
it('sniff console', async () => {
110+
const page = await this.app.firstWindow();
92111

93112
// Collect console logs.
94113
let consoleText;
95-
window.on('console', message => consoleText = message.text());
114+
page.on('console', message => consoleText = message.text());
96115

97116
// Click button.
98-
await window.click('text=Click me');
117+
await page.click('text=Click me');
99118

100119
// Check that click produced console message.
101120
assert.equal(consoleText, 'click');
102121
});
122+
123+
it('intercept network', async () => {
124+
await this.app.firstWindow();
125+
126+
// Return value of this.app.context() is a Playwright BrowserContext.
127+
// See https://playwright.dev/#path=docs%2Fapi.md&q=class-browsercontext.
128+
129+
await await this.app.context().route('**/empty.html', (route, request) => {
130+
route.fulfill({
131+
status: 200,
132+
contentType: 'text/html',
133+
body: '<title>Hello World</title>',
134+
})
135+
});
136+
137+
// Helper method to create BrowserWindow.
138+
const page = await this.app.newBrowserWindow({ width: 800, height: 600 });
139+
await page.goto('https://localhost:1000/empty.html');
140+
141+
assert.equal(await page.title(), 'Hello World');
142+
});
143+
144+
it('should maximize window', async () => {
145+
await this.app.firstWindow();
146+
147+
const page = await this.app.newBrowserWindow({ width: 800, height: 600 });
148+
// page.browserWindow is a Playwright JSHandle pointing at Electron's
149+
// BrowserWindow.
150+
// https://playwright.dev/#path=docs%2Fapi.md&q=class-jshandle
151+
await page.browserWindow.evaluate(browserWindow => browserWindow.maximize());
152+
assert(await page.browserWindow.evaluate(browserWindow => browserWindow.isMaximized()));
153+
await page.browserWindow.evaluate(browserWindow => browserWindow.unmaximize());
154+
assert(!(await page.browserWindow.evaluate(browserWindow => browserWindow.isMaximized())));
155+
});
156+
103157
});
104158
```

src/server/electron.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,17 @@ export class ElectronApplication extends ExtendedEventEmitter {
7575
// Needs to be sync.
7676
const windowId = ++this._lastWindowId;
7777
// Can be async.
78-
const handle = await this._nodeElectronHandle!.evaluateHandle(({ BrowserWindow }, windowId) => BrowserWindow.fromId(windowId), windowId);
78+
const handle = await this._nodeElectronHandle!.evaluateHandle(({ BrowserWindow }, windowId) => BrowserWindow.fromId(windowId), windowId).catch(e => {});
79+
if (!handle)
80+
return;
7981
(page as any).browserWindow = handle;
8082
(page as any)._browserWindowId = windowId;
8183
page.on(Events.Page.Close, () => {
8284
(page as any).browserWindow.dispose();
8385
this._windows.delete(page);
8486
});
8587
this._windows.add(page);
86-
await page.waitForLoadState('domcontentloaded');
88+
await page.waitForLoadState('domcontentloaded').catch(e => {}); // can happen after detach
8789
this.emit(ElectronEvents.ElectronApplication.Window, page);
8890
}
8991

0 commit comments

Comments
 (0)