Reuse electron window; difficult task
This commit is contained in:
@ -28,6 +28,107 @@ import { isErrorWhitelisted } from './lib/console-error-whitelist'
|
||||
import { isArray } from 'lib/utils'
|
||||
import { reportRejection } from 'lib/trap'
|
||||
|
||||
// The below is copied from playwright-core because it exports none of them :(
|
||||
import { Env, BrowserContextOptions } from 'playwright-core'
|
||||
import type * as channels from '@protocol/channels';
|
||||
|
||||
// Copied from playwright-core
|
||||
function envObjectToArray(env: Env): { name: string, value: string }[] {
|
||||
const result: { name: string, value: string }[] = [];
|
||||
for (const name in env) {
|
||||
if (!Object.is(env[name], undefined))
|
||||
result.push({ name, value: String(env[name]) });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Copied from playwright-core
|
||||
export async function toClientCertificatesProtocol(certs?: BrowserContextOptions['clientCertificates']): Promise<channels.PlaywrightNewRequestParams['clientCertificates']> {
|
||||
if (!certs)
|
||||
return undefined;
|
||||
|
||||
const bufferizeContent = async (value?: Buffer, path?: string): Promise<Buffer | undefined> => {
|
||||
if (value)
|
||||
return value;
|
||||
if (path)
|
||||
return await fs.promises.readFile(path);
|
||||
};
|
||||
|
||||
return await Promise.all(certs.map(async cert => ({
|
||||
origin: cert.origin,
|
||||
cert: await bufferizeContent(cert.cert, cert.certPath),
|
||||
key: await bufferizeContent(cert.key, cert.keyPath),
|
||||
pfx: await bufferizeContent(cert.pfx, cert.pfxPath),
|
||||
passphrase: cert.passphrase,
|
||||
})));
|
||||
}
|
||||
|
||||
// Copied from playwright-core
|
||||
function toAcceptDownloadsProtocol(acceptDownloads?: boolean) {
|
||||
if (acceptDownloads === undefined)
|
||||
return undefined;
|
||||
if (acceptDownloads)
|
||||
return 'accept';
|
||||
return 'deny';
|
||||
}
|
||||
|
||||
// Copied from playwright-core
|
||||
function prepareRecordHarOptions(options: BrowserContextOptions['recordHar']): channels.RecordHarOptions | undefined {
|
||||
if (!options)
|
||||
return;
|
||||
return {
|
||||
path: options.path,
|
||||
content: options.content || (options.omitContent ? 'omit' : undefined),
|
||||
urlGlob: isString(options.urlFilter) ? options.urlFilter : undefined,
|
||||
urlRegexSource: isRegExp(options.urlFilter) ? options.urlFilter.source : undefined,
|
||||
urlRegexFlags: isRegExp(options.urlFilter) ? options.urlFilter.flags : undefined,
|
||||
mode: options.mode
|
||||
};
|
||||
}
|
||||
|
||||
// Copied from playwright-core
|
||||
async function prepareStorageState(options: BrowserContextOptions): Promise<channels.BrowserNewContextParams['storageState']> {
|
||||
if (typeof options.storageState !== 'string')
|
||||
return options.storageState;
|
||||
try {
|
||||
return JSON.parse(await fs.promises.readFile(options.storageState, 'utf8'));
|
||||
} catch (e) {
|
||||
rewriteErrorMessage(e, `Error reading storage state from ${options.storageState}:\n` + e.message);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from playwright-core
|
||||
async function prepareBrowserContextParams(options: BrowserContextOptions): Promise<channels.BrowserNewContextParams> {
|
||||
if (options.videoSize && !options.videosPath)
|
||||
throw new Error(`"videoSize" option requires "videosPath" to be specified`);
|
||||
if (options.extraHTTPHeaders)
|
||||
network.validateHeaders(options.extraHTTPHeaders);
|
||||
const contextParams: channels.BrowserNewContextParams = {
|
||||
...options,
|
||||
viewport: options.viewport === null ? undefined : options.viewport,
|
||||
noDefaultViewport: options.viewport === null,
|
||||
extraHTTPHeaders: options.extraHTTPHeaders ? headersObjectToArray(options.extraHTTPHeaders) : undefined,
|
||||
storageState: await prepareStorageState(options),
|
||||
serviceWorkers: options.serviceWorkers,
|
||||
recordHar: prepareRecordHarOptions(options.recordHar),
|
||||
colorScheme: options.colorScheme === null ? 'no-override' : options.colorScheme,
|
||||
reducedMotion: options.reducedMotion === null ? 'no-override' : options.reducedMotion,
|
||||
forcedColors: options.forcedColors === null ? 'no-override' : options.forcedColors,
|
||||
acceptDownloads: toAcceptDownloadsProtocol(options.acceptDownloads),
|
||||
clientCertificates: await toClientCertificatesProtocol(options.clientCertificates),
|
||||
};
|
||||
if (!contextParams.recordVideo && options.videosPath) {
|
||||
contextParams.recordVideo = {
|
||||
dir: options.videosPath,
|
||||
size: options.videoSize
|
||||
};
|
||||
}
|
||||
if (contextParams.recordVideo && contextParams.recordVideo.dir)
|
||||
contextParams.recordVideo.dir = path.resolve(process.cwd(), contextParams.recordVideo.dir);
|
||||
return contextParams;
|
||||
}
|
||||
|
||||
const toNormalizedCode = (text: string) => {
|
||||
return text.replace(/\s+/g, '')
|
||||
}
|
||||
@ -723,7 +824,7 @@ const moveDownloadedFileTo = async (page: Page, toLocation: string) => {
|
||||
const files = await fsp.readdir(downloadDir)
|
||||
return files.length
|
||||
})
|
||||
.toBe(1)
|
||||
.toBeGreaterThan(0)
|
||||
|
||||
// Go through the downloads dir and move files to new location
|
||||
const files = await fsp.readdir(downloadDir)
|
||||
@ -867,10 +968,12 @@ export async function setup(
|
||||
settings,
|
||||
IS_PLAYWRIGHT_KEY,
|
||||
PLAYWRIGHT_TEST_DIR,
|
||||
PERSIST_MODELING_CONTEXT,
|
||||
}) => {
|
||||
localStorage.clear()
|
||||
localStorage.setItem('TOKEN_PERSIST_KEY', token)
|
||||
localStorage.setItem('persistCode', ``)
|
||||
localStorage.setItem(PERSIST_MODELING_CONTEXT, JSON.stringify({openPanes: ['code']}))
|
||||
localStorage.setItem(settingsKey, settings)
|
||||
localStorage.setItem(IS_PLAYWRIGHT_KEY, 'true')
|
||||
localStorage.setItem('PLAYWRIGHT_TEST_DIR', PLAYWRIGHT_TEST_DIR)
|
||||
@ -891,6 +994,7 @@ export async function setup(
|
||||
}),
|
||||
IS_PLAYWRIGHT_KEY,
|
||||
PLAYWRIGHT_TEST_DIR: TEST_SETTINGS.app.projectDirectory,
|
||||
PERSIST_MODELING_CONTEXT,
|
||||
}
|
||||
)
|
||||
|
||||
@ -909,12 +1013,15 @@ export async function setup(
|
||||
await page.emulateMedia({ reducedMotion: 'reduce' })
|
||||
|
||||
// Trigger a navigation, since loading file:// doesn't.
|
||||
await page.reload()
|
||||
// await page.reload()
|
||||
}
|
||||
|
||||
let electronApp = undefined
|
||||
let context = undefined
|
||||
let page = undefined
|
||||
|
||||
export async function setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn,
|
||||
cleanProjectDir = true,
|
||||
appSettings,
|
||||
}: {
|
||||
@ -937,7 +1044,7 @@ export async function setupElectron({
|
||||
await fsp.mkdir(projectDirName)
|
||||
}
|
||||
|
||||
const electronApp = await electron.launch({
|
||||
const options = {
|
||||
args: ['.', '--no-sandbox'],
|
||||
env: {
|
||||
...process.env,
|
||||
@ -947,15 +1054,19 @@ export async function setupElectron({
|
||||
...(process.env.ELECTRON_OVERRIDE_DIST_PATH
|
||||
? { executablePath: process.env.ELECTRON_OVERRIDE_DIST_PATH + 'electron' }
|
||||
: {}),
|
||||
})
|
||||
}
|
||||
|
||||
const context = electronApp.context()
|
||||
const page = await electronApp.firstWindow()
|
||||
// Do this once and then reuse window on subsequent calls.
|
||||
if (!electronApp) {
|
||||
electronApp = await electron.launch(options)
|
||||
}
|
||||
|
||||
page.TEST_SETTINGS_FILE_KEY = projectDirName
|
||||
|
||||
context.on('console', console.log)
|
||||
page.on('console', console.log)
|
||||
if (!context || !page) {
|
||||
context = electronApp.context()
|
||||
page = await electronApp.firstWindow()
|
||||
context.on('console', console.log)
|
||||
page.on('console', console.log)
|
||||
}
|
||||
|
||||
if (cleanProjectDir) {
|
||||
const tempSettingsFilePath = path.join(projectDirName, SETTINGS_FILE_NAME)
|
||||
@ -985,11 +1096,7 @@ export async function setupElectron({
|
||||
await fsp.writeFile(tempSettingsFilePath, settingsOverrides)
|
||||
}
|
||||
|
||||
await folderSetupFn?.(projectDirName)
|
||||
|
||||
await setup(context, page)
|
||||
|
||||
return { electronApp, page, context, dir: projectDirName }
|
||||
return { electronApp, page, context, dir: projectDirName, options }
|
||||
}
|
||||
|
||||
function failOnConsoleErrors(page: Page, testInfo?: TestInfo) {
|
||||
|
Reference in New Issue
Block a user