Skip to content

Commit 0237b7b

Browse files
committed
cherry-pick(#19601): fix(electron): fix the directory app path
1 parent e78bd24 commit 0237b7b

File tree

7 files changed

+70
-68
lines changed

7 files changed

+70
-68
lines changed

packages/playwright-core/src/client/electron.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
6262
readonly _context: BrowserContext;
6363
private _windows = new Set<Page>();
6464
private _timeoutSettings = new TimeoutSettings();
65+
private _isClosed = false;
6566

6667
static from(electronApplication: channels.ElectronApplicationChannel): ElectronApplication {
6768
return (electronApplication as any)._object;
@@ -73,7 +74,10 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
7374
for (const page of this._context._pages)
7475
this._onPage(page);
7576
this._context.on(Events.BrowserContext.Page, page => this._onPage(page));
76-
this._channel.on('close', () => this.emit(Events.ElectronApplication.Close));
77+
this._channel.on('close', () => {
78+
this._isClosed = true;
79+
this.emit(Events.ElectronApplication.Close);
80+
});
7781
}
7882

7983
process(): childProcess.ChildProcess {
@@ -102,6 +106,8 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
102106
}
103107

104108
async close() {
109+
if (this._isClosed)
110+
return;
105111
await this._channel.close();
106112
}
107113

packages/playwright-core/src/server/electron/loader.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
const { app } = require('electron');
18+
const fs = require('fs');
1819
const path = require('path');
1920
const { chromiumSwitches } = require('../chromium/chromiumSwitches');
2021

@@ -42,7 +43,13 @@ app.emit = (event: string | symbol, ...args: any[]): boolean => {
4243
}
4344
return originalEmit(event, ...args);
4445
};
45-
app.getAppPath = () => path.dirname(appPath);
46+
47+
app.getAppPath = () => {
48+
if (fs.statSync(appPath).isFile())
49+
return path.dirname(appPath);
50+
return appPath;
51+
};
52+
4653
let isReady = false;
4754
let whenReadyCallback: (event: any) => any;
4855
const whenReadyPromise = new Promise<void>(f => whenReadyCallback = f);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const { protocol } = require('electron');
2+
protocol.registerSchemesAsPrivileged([]);

tests/electron/electron-app.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
const { app, protocol } = require('electron');
22
const path = require('path');
33

4-
// Test using pre-ready apis.
5-
protocol.registerSchemesAsPrivileged([]);
6-
74
app.on('window-all-closed', e => e.preventDefault());
85

96
app.whenReady().then(() => {

tests/electron/electron-app.spec.ts

Lines changed: 39 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ import path from 'path';
1919
import fs from 'fs';
2020
import { electronTest as test, expect } from './electronTest';
2121

22-
test('should fire close event', async ({ playwright }) => {
23-
const electronApp = await playwright._electron.launch({
24-
args: [path.join(__dirname, 'electron-app.js')],
25-
});
22+
test('should fire close event', async ({ launchElectronApp }) => {
23+
const electronApp = await launchElectronApp('electron-app.js');
2624
const events = [];
2725
electronApp.on('close', () => events.push('application'));
2826
electronApp.context().on('close', () => events.push('context'));
@@ -33,22 +31,16 @@ test('should fire close event', async ({ playwright }) => {
3331
expect(events.join('|')).toBe('context|application');
3432
});
3533

36-
test('should dispatch ready event', async ({ playwright }) => {
37-
const electronApp = await playwright._electron.launch({
38-
args: [path.join(__dirname, 'electron-app-ready-event.js')],
39-
});
40-
try {
41-
const events = await electronApp.evaluate(() => globalThis.__playwrightLog);
42-
expect(events).toEqual([
43-
'isReady == false',
44-
'will-finish-launching fired',
45-
'ready fired',
46-
'whenReady resolved',
47-
'isReady == true',
48-
]);
49-
} finally {
50-
await electronApp.close();
51-
}
34+
test('should dispatch ready event', async ({ launchElectronApp }) => {
35+
const electronApp = await launchElectronApp('electron-app-ready-event.js');
36+
const events = await electronApp.evaluate(() => globalThis.__playwrightLog);
37+
expect(events).toEqual([
38+
'isReady == false',
39+
'will-finish-launching fired',
40+
'ready fired',
41+
'whenReady resolved',
42+
'isReady == true',
43+
]);
5244
});
5345

5446
test('should script application', async ({ electronApp }) => {
@@ -114,28 +106,19 @@ test('should have a clipboard instance', async ({ electronApp }) => {
114106
expect(clipboardContentRead).toEqual(clipboardContentToWrite);
115107
});
116108

117-
test('should test app that opens window fast', async ({ playwright }) => {
118-
const electronApp = await playwright._electron.launch({
119-
args: [path.join(__dirname, 'electron-window-app.js')],
120-
});
121-
await electronApp.close();
109+
test('should test app that opens window fast', async ({ launchElectronApp }) => {
110+
await launchElectronApp('electron-window-app.js');
122111
});
123112

124-
test('should return browser window', async ({ playwright }) => {
125-
const electronApp = await playwright._electron.launch({
126-
args: [path.join(__dirname, 'electron-window-app.js')],
127-
});
113+
test('should return browser window', async ({ launchElectronApp }) => {
114+
const electronApp = await launchElectronApp('electron-window-app.js');
128115
const page = await electronApp.firstWindow();
129116
const bwHandle = await electronApp.browserWindow(page);
130117
expect(await bwHandle.evaluate((bw: BrowserWindow) => bw.title)).toBe('Electron');
131-
await electronApp.close();
132118
});
133119

134-
test('should bypass csp', async ({ playwright, server }) => {
135-
const app = await playwright._electron.launch({
136-
args: [require('path').join(__dirname, 'electron-app.js')],
137-
bypassCSP: true,
138-
});
120+
test('should bypass csp', async ({ launchElectronApp, server }) => {
121+
const app = await launchElectronApp('electron-app.js', { bypassCSP: true });
139122
await app.evaluate(electron => {
140123
const window = new electron.BrowserWindow({
141124
width: 800,
@@ -147,13 +130,10 @@ test('should bypass csp', async ({ playwright, server }) => {
147130
await page.goto(server.PREFIX + '/csp.html');
148131
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
149132
expect(await page.evaluate('window["__injected"]')).toBe(42);
150-
await app.close();
151133
});
152134

153-
test('should create page for browser view', async ({ playwright }) => {
154-
const app = await playwright._electron.launch({
155-
args: [path.join(__dirname, 'electron-window-app.js')],
156-
});
135+
test('should create page for browser view', async ({ launchElectronApp }) => {
136+
const app = await launchElectronApp('electron-window-app.js');
157137
await app.firstWindow();
158138
await app.evaluate(async electron => {
159139
const window = electron.BrowserWindow.getAllWindows()[0];
@@ -163,13 +143,10 @@ test('should create page for browser view', async ({ playwright }) => {
163143
view.setBounds({ x: 0, y: 0, width: 256, height: 256 });
164144
});
165145
await expect.poll(() => app.windows().length).toBe(2);
166-
await app.close();
167146
});
168147

169-
test('should return same browser window for browser view pages', async ({ playwright }) => {
170-
const app = await playwright._electron.launch({
171-
args: [path.join(__dirname, 'electron-window-app.js')],
172-
});
148+
test('should return same browser window for browser view pages', async ({ launchElectronApp }) => {
149+
const app = await launchElectronApp('electron-window-app.js');
173150
await app.firstWindow();
174151
await app.evaluate(async electron => {
175152
const window = electron.BrowserWindow.getAllWindows()[0];
@@ -187,12 +164,10 @@ test('should return same browser window for browser view pages', async ({ playwr
187164
})
188165
);
189166
expect(firstWindowId).toEqual(secondWindowId);
190-
await app.close();
191167
});
192168

193-
test('should record video', async ({ playwright }, testInfo) => {
194-
const app = await playwright._electron.launch({
195-
args: [path.join(__dirname, 'electron-window-app.js')],
169+
test('should record video', async ({ launchElectronApp }, testInfo) => {
170+
const app = await launchElectronApp('electron-window-app.js', {
196171
recordVideo: { dir: testInfo.outputPath('video') }
197172
});
198173
const page = await app.firstWindow();
@@ -203,25 +178,31 @@ test('should record video', async ({ playwright }, testInfo) => {
203178
expect(fs.statSync(videoPath).size).toBeGreaterThan(0);
204179
});
205180

206-
test('should be able to get the first window when with a delayed navigation', async ({ playwright }) => {
181+
test('should be able to get the first window when with a delayed navigation', async ({ launchElectronApp }) => {
207182
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/17765' });
208183

209-
const app = await playwright._electron.launch({
210-
args: [path.join(__dirname, 'electron-window-app-delayed-loadURL.js')],
211-
});
184+
const app = await launchElectronApp('electron-window-app-delayed-loadURL.js');
212185
const page = await app.firstWindow();
213186
await expect(page).toHaveURL('data:text/html,<h1>Foobar</h1>');
214187
await expect(page.locator('h1')).toHaveText('Foobar');
215-
await app.close();
216188
});
217189

218-
test('should detach debugger on app-initiated exit', async ({ playwright }) => {
219-
const electronApp = await playwright._electron.launch({
220-
args: [path.join(__dirname, 'electron-app.js')],
221-
});
190+
test('should detach debugger on app-initiated exit', async ({ launchElectronApp }) => {
191+
const electronApp = await launchElectronApp('electron-app.js');
222192
const closePromise = new Promise(f => electronApp.process().on('close', f));
223193
await electronApp.evaluate(({ app }) => {
224194
app.quit();
225195
});
226196
await closePromise;
227197
});
198+
199+
test('should run pre-ready apis', async ({ launchElectronApp }) => {
200+
await launchElectronApp('electron-pre-ready-app.js');
201+
});
202+
203+
test('should resolve app path for folder apps', async ({ launchElectronApp }) => {
204+
const electronApp = await launchElectronApp('.');
205+
const appPath = await electronApp.evaluate(async ({ app }) => app.getAppPath());
206+
expect(appPath).toBe(path.resolve(__dirname));
207+
await electronApp.close();
208+
});

tests/electron/electronTest.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { assert } from 'playwright-core/lib/utils';
2626

2727
type ElectronTestFixtures = PageTestFixtures & {
2828
electronApp: ElectronApplication;
29+
launchElectronApp: (appFile: string, options?: any) => Promise<ElectronApplication>;
2930
newWindow: () => Promise<Page>;
3031
};
3132

@@ -40,14 +41,21 @@ export const electronTest = baseTest.extend<TraceViewerFixtures>(traceViewerFixt
4041
isElectron: [true, { scope: 'worker' }],
4142
isWebView2: [false, { scope: 'worker' }],
4243

43-
electronApp: async ({ playwright }, run) => {
44+
launchElectronApp: async ({ playwright }, use) => {
4445
// This env prevents 'Electron Security Policy' console message.
4546
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
46-
const electronApp = await playwright._electron.launch({
47-
args: [path.join(__dirname, 'electron-app.js')],
47+
const apps: ElectronApplication[] = [];
48+
await use(async (appFile: string, options?: any[]) => {
49+
const app = await playwright._electron.launch({ ...options, args: [path.join(__dirname, appFile)] });
50+
apps.push(app);
51+
return app;
4852
});
49-
await run(electronApp);
50-
await electronApp.close();
53+
for (const app of apps)
54+
await app.close();
55+
},
56+
57+
electronApp: async ({ launchElectronApp }, use) => {
58+
await use(await launchElectronApp('electron-app.js'));
5159
},
5260

5361
newWindow: async ({ electronApp }, run) => {

tests/electron/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require('electron');

0 commit comments

Comments
 (0)