Fix playwright tests on Linux (#1440)

This commit is contained in:
Adam Weeden 2022-07-30 13:15:30 -04:00 committed by GitHub
parent 0de2463f2b
commit 82ff609a91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 18 deletions

View File

@ -117,18 +117,23 @@ const fileDownloadOptions = { ...appArgs.fileDownloadOptions };
electronDownload(fileDownloadOptions);
if (appArgs.processEnvs) {
let processEnvs: Record<string, string> =
appArgs.processEnvs as unknown as Record<string, string>;
// This is compatibility if just a string was passed.
if (typeof appArgs.processEnvs === 'string') {
process.env.processEnvs = appArgs.processEnvs;
} else {
Object.keys(appArgs.processEnvs)
.filter((key) => key !== undefined)
.forEach((key) => {
// @ts-expect-error TS will complain this could be undefined, but we filtered those out
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
process.env[key] = appArgs.processEnvs[key];
});
try {
processEnvs = JSON.parse(appArgs.processEnvs) as Record<string, string>;
} catch {
// This wasn't JSON. Fall back to the old code
processEnvs = {};
process.env.processEnvs = appArgs.processEnvs;
}
}
Object.keys(processEnvs)
.filter((key) => key !== undefined)
.forEach((key) => {
process.env[key] = processEnvs[key];
});
}
if (typeof appArgs.flashPluginDir === 'string') {

View File

@ -27,6 +27,17 @@ export function hasWine(): boolean {
return hasbin.sync('wine');
}
// I tried to place this (and the other is* functions) in
// a new shared helpers, but alas eslint gets real confused
// about the type signatures and thinks they're all any.
// TODO: Figure out a way to refactor duplicate code from
// src/helpers/helpers.ts and app/src/helpers/helpers.ts
// into the shared module
export function isLinux(): boolean {
return os.platform() === 'linux';
}
export function isOSX(): boolean {
return os.platform() === 'darwin';
}

View File

@ -11,7 +11,7 @@ import {
Page,
} from 'playwright';
import { getTempDir } from './helpers/helpers';
import { getTempDir, isLinux } from './helpers/helpers';
import { NativefierOptions } from '../shared/src/options/model';
const INJECT_DIR = path.join(__dirname, '..', 'app', 'inject');
@ -70,11 +70,26 @@ describe('Application launch', () => {
.catch(() => log.log('window.console', consoleMessage));
};
app = await _electron.launch({
args: [appMainJSPath],
// Workaround for the following errors in some linux distros:
// pw:browser [pid=24716][err] [24718:0100/000000.660708:ERROR:zygote_linux.cc(650)] write: Broken pipe (32) +16ms
// pw:browser [pid=24719][err] [24719:0725/114519.722060:FATAL:setuid_sandbox_host.cc(157)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /home/parallels/Dev/nativefier/node_modules/electron/dist/chrome-sandbox is owned by root and has mode 4755. +61ms
args: isLinux()
? ['--no-sandbox', '--disable-setuid-sandbox', appMainJSPath]
: [appMainJSPath],
env: {
LOG_FILE_DIR: logFileDir,
PLAYWRIGHT_TEST: '1',
PLAYWRIGHT_CONFIG: JSON.stringify(playwrightConfig),
PLAYWRIGHT_CONFIG: JSON.stringify({
...playwrightConfig,
// disableGpu and process.env.DISPLAY forwarding solve the following errors on Linux:
// pw:browser [pid=286188][err] [286188:0724/102939.938248:ERROR:ozone_platform_x11.cc(248)] Missing X server or $DISPLAY +77ms
// pw:browser [pid=286188][err] [286188:0724/102939.938299:ERROR:env.cc(225)] The platform failed to initialize. Exiting. +2ms
disableGpu: isLinux() ? true : undefined,
processEnvs:
isLinux() && process.env.DISPLAY
? JSON.stringify({ DISPLAY: process.env.DISPLAY })
: undefined,
} as NativefierOptions),
USE_LOG_FILE: '1',
VERBOSE: '1',
},
@ -344,24 +359,29 @@ describe('Application launch', () => {
const loginWindow = appWindows.filter((x) => x !== mainWindow)[0];
await loginWindow.waitForLoadState('domcontentloaded');
await loginWindow.waitForLoadState('load');
const usernameField = await loginWindow.$('#username-input');
expect(usernameField).not.toBeNull();
await usernameField?.fill('foo');
const passwordField = await loginWindow.$('#password-input');
expect(passwordField).not.toBeNull();
await passwordField?.fill('bar');
const submitButton = await loginWindow.$('#submit-form-button');
expect(submitButton).not.toBeNull();
await usernameField?.fill('foo');
await passwordField?.fill('bar');
// "Why is this here?" you may be asking yourself.
// Because for some reason, on some linux boxes,
// the click function will not work until this is done.
// Why? I do not have access to the dark incantation
// that would allow me to know such information.
log.log({ submitButton });
await submitButton?.click();
await mainWindow.waitForLoadState('networkidle');
await mainWindow.waitForEvent('load');
const documentText = await mainWindow.evaluate<string>(
'document.documentElement.innerText',