fix(electron): fix the directory app path (#19601)

This commit is contained in:
Pavel Feldman 2022-12-20 12:50:53 -08:00 committed by GitHub
parent 51782cfa5d
commit 95cc5c2a2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 70 additions and 68 deletions

View File

@ -62,6 +62,7 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
readonly _context: BrowserContext;
private _windows = new Set<Page>();
private _timeoutSettings = new TimeoutSettings();
private _isClosed = false;
static from(electronApplication: channels.ElectronApplicationChannel): ElectronApplication {
return (electronApplication as any)._object;
@ -73,7 +74,10 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
for (const page of this._context._pages)
this._onPage(page);
this._context.on(Events.BrowserContext.Page, page => this._onPage(page));
this._channel.on('close', () => this.emit(Events.ElectronApplication.Close));
this._channel.on('close', () => {
this._isClosed = true;
this.emit(Events.ElectronApplication.Close);
});
}
process(): childProcess.ChildProcess {
@ -102,6 +106,8 @@ export class ElectronApplication extends ChannelOwner<channels.ElectronApplicati
}
async close() {
if (this._isClosed)
return;
await this._channel.close();
}

View File

@ -15,6 +15,7 @@
*/
const { app } = require('electron');
const fs = require('fs');
const path = require('path');
const { chromiumSwitches } = require('../chromium/chromiumSwitches');
@ -42,7 +43,13 @@ app.emit = (event: string | symbol, ...args: any[]): boolean => {
}
return originalEmit(event, ...args);
};
app.getAppPath = () => path.dirname(appPath);
app.getAppPath = () => {
if (fs.statSync(appPath).isFile())
return path.dirname(appPath);
return appPath;
};
let isReady = false;
let whenReadyCallback: (event: any) => any;
const whenReadyPromise = new Promise<void>(f => whenReadyCallback = f);

View File

@ -0,0 +1,2 @@
const { protocol } = require('electron');
protocol.registerSchemesAsPrivileged([]);

View File

@ -1,9 +1,6 @@
const { app, protocol } = require('electron');
const path = require('path');
// Test using pre-ready apis.
protocol.registerSchemesAsPrivileged([]);
app.on('window-all-closed', e => e.preventDefault());
app.whenReady().then(() => {

View File

@ -19,10 +19,8 @@ import path from 'path';
import fs from 'fs';
import { electronTest as test, expect } from './electronTest';
test('should fire close event', async ({ playwright }) => {
const electronApp = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-app.js')],
});
test('should fire close event', async ({ launchElectronApp }) => {
const electronApp = await launchElectronApp('electron-app.js');
const events = [];
electronApp.on('close', () => events.push('application'));
electronApp.context().on('close', () => events.push('context'));
@ -33,22 +31,16 @@ test('should fire close event', async ({ playwright }) => {
expect(events.join('|')).toBe('context|application');
});
test('should dispatch ready event', async ({ playwright }) => {
const electronApp = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-app-ready-event.js')],
});
try {
const events = await electronApp.evaluate(() => globalThis.__playwrightLog);
expect(events).toEqual([
'isReady == false',
'will-finish-launching fired',
'ready fired',
'whenReady resolved',
'isReady == true',
]);
} finally {
await electronApp.close();
}
test('should dispatch ready event', async ({ launchElectronApp }) => {
const electronApp = await launchElectronApp('electron-app-ready-event.js');
const events = await electronApp.evaluate(() => globalThis.__playwrightLog);
expect(events).toEqual([
'isReady == false',
'will-finish-launching fired',
'ready fired',
'whenReady resolved',
'isReady == true',
]);
});
test('should script application', async ({ electronApp }) => {
@ -114,28 +106,19 @@ test('should have a clipboard instance', async ({ electronApp }) => {
expect(clipboardContentRead).toEqual(clipboardContentToWrite);
});
test('should test app that opens window fast', async ({ playwright }) => {
const electronApp = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-window-app.js')],
});
await electronApp.close();
test('should test app that opens window fast', async ({ launchElectronApp }) => {
await launchElectronApp('electron-window-app.js');
});
test('should return browser window', async ({ playwright }) => {
const electronApp = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-window-app.js')],
});
test('should return browser window', async ({ launchElectronApp }) => {
const electronApp = await launchElectronApp('electron-window-app.js');
const page = await electronApp.firstWindow();
const bwHandle = await electronApp.browserWindow(page);
expect(await bwHandle.evaluate((bw: BrowserWindow) => bw.title)).toBe('Electron');
await electronApp.close();
});
test('should bypass csp', async ({ playwright, server }) => {
const app = await playwright._electron.launch({
args: [require('path').join(__dirname, 'electron-app.js')],
bypassCSP: true,
});
test('should bypass csp', async ({ launchElectronApp, server }) => {
const app = await launchElectronApp('electron-app.js', { bypassCSP: true });
await app.evaluate(electron => {
const window = new electron.BrowserWindow({
width: 800,
@ -147,13 +130,10 @@ test('should bypass csp', async ({ playwright, server }) => {
await page.goto(server.PREFIX + '/csp.html');
await page.addScriptTag({ content: 'window["__injected"] = 42;' });
expect(await page.evaluate('window["__injected"]')).toBe(42);
await app.close();
});
test('should create page for browser view', async ({ playwright }) => {
const app = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-window-app.js')],
});
test('should create page for browser view', async ({ launchElectronApp }) => {
const app = await launchElectronApp('electron-window-app.js');
await app.firstWindow();
await app.evaluate(async electron => {
const window = electron.BrowserWindow.getAllWindows()[0];
@ -163,13 +143,10 @@ test('should create page for browser view', async ({ playwright }) => {
view.setBounds({ x: 0, y: 0, width: 256, height: 256 });
});
await expect.poll(() => app.windows().length).toBe(2);
await app.close();
});
test('should return same browser window for browser view pages', async ({ playwright }) => {
const app = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-window-app.js')],
});
test('should return same browser window for browser view pages', async ({ launchElectronApp }) => {
const app = await launchElectronApp('electron-window-app.js');
await app.firstWindow();
await app.evaluate(async electron => {
const window = electron.BrowserWindow.getAllWindows()[0];
@ -187,12 +164,10 @@ test('should return same browser window for browser view pages', async ({ playwr
})
);
expect(firstWindowId).toEqual(secondWindowId);
await app.close();
});
test('should record video', async ({ playwright }, testInfo) => {
const app = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-window-app.js')],
test('should record video', async ({ launchElectronApp }, testInfo) => {
const app = await launchElectronApp('electron-window-app.js', {
recordVideo: { dir: testInfo.outputPath('video') }
});
const page = await app.firstWindow();
@ -203,25 +178,31 @@ test('should record video', async ({ playwright }, testInfo) => {
expect(fs.statSync(videoPath).size).toBeGreaterThan(0);
});
test('should be able to get the first window when with a delayed navigation', async ({ playwright }) => {
test('should be able to get the first window when with a delayed navigation', async ({ launchElectronApp }) => {
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/17765' });
const app = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-window-app-delayed-loadURL.js')],
});
const app = await launchElectronApp('electron-window-app-delayed-loadURL.js');
const page = await app.firstWindow();
await expect(page).toHaveURL('data:text/html,<h1>Foobar</h1>');
await expect(page.locator('h1')).toHaveText('Foobar');
await app.close();
});
test('should detach debugger on app-initiated exit', async ({ playwright }) => {
const electronApp = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-app.js')],
});
test('should detach debugger on app-initiated exit', async ({ launchElectronApp }) => {
const electronApp = await launchElectronApp('electron-app.js');
const closePromise = new Promise(f => electronApp.process().on('close', f));
await electronApp.evaluate(({ app }) => {
app.quit();
});
await closePromise;
});
test('should run pre-ready apis', async ({ launchElectronApp }) => {
await launchElectronApp('electron-pre-ready-app.js');
});
test('should resolve app path for folder apps', async ({ launchElectronApp }) => {
const electronApp = await launchElectronApp('.');
const appPath = await electronApp.evaluate(async ({ app }) => app.getAppPath());
expect(appPath).toBe(path.resolve(__dirname));
await electronApp.close();
});

View File

@ -26,6 +26,7 @@ import { assert } from 'playwright-core/lib/utils';
type ElectronTestFixtures = PageTestFixtures & {
electronApp: ElectronApplication;
launchElectronApp: (appFile: string, options?: any) => Promise<ElectronApplication>;
newWindow: () => Promise<Page>;
};
@ -40,14 +41,21 @@ export const electronTest = baseTest.extend<TraceViewerFixtures>(traceViewerFixt
isElectron: [true, { scope: 'worker' }],
isWebView2: [false, { scope: 'worker' }],
electronApp: async ({ playwright }, run) => {
launchElectronApp: async ({ playwright }, use) => {
// This env prevents 'Electron Security Policy' console message.
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
const electronApp = await playwright._electron.launch({
args: [path.join(__dirname, 'electron-app.js')],
const apps: ElectronApplication[] = [];
await use(async (appFile: string, options?: any[]) => {
const app = await playwright._electron.launch({ ...options, args: [path.join(__dirname, appFile)] });
apps.push(app);
return app;
});
await run(electronApp);
await electronApp.close();
for (const app of apps)
await app.close();
},
electronApp: async ({ launchElectronApp }, use) => {
await use(await launchElectronApp('electron-app.js'));
},
newWindow: async ({ electronApp }, run) => {

1
tests/electron/index.js Normal file
View File

@ -0,0 +1 @@
require('electron');