Skip to content
This repository has been archived by the owner on Nov 29, 2023. It is now read-only.

Commit

Permalink
Web test/benchmark setup refinements
Browse files Browse the repository at this point in the history
Faster Firefox startup, improved logging
  • Loading branch information
eyelidlessness committed Feb 21, 2023
1 parent 538bcfe commit d9ae798
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 50 deletions.
34 changes: 34 additions & 0 deletions config/firefox.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"browser.cache.memory.capacity": 65536,
"browser.chrome.toolbar_style": 1,
"browser.display.show_image_placeholders": false,
"browser.display.use_document_colors": false,
"browser.display.use_document_fonts": 0,
"browser.display.use_system_colors": true,
"browser.formfill.enable": false,
"browser.helperApps.deleteTempFileOnExit": true,
"browser.pocket.enabled": false,
"browser.shell.checkDefaultBrowser": false,
"browser.startup.homepage": "about:blank",
"browser.startup.page": 0,
"browser.tabs.forceHide": true,
"browser.urlbar.autocomplete.enabled": false,
"browser.urlbar.autoFill": false,
"browser.urlbar.showPopup": false,
"browser.urlbar.showSearch": false,
"content.notify.interval": 500000,
"content.notify.ontimer": true,
"content.switch.threshold": 250000,
"extensions.checkCompatibility": false,
"extensions.checkUpdateSecurity": false,
"extensions.update.autoUpdateEnabled": false,
"extensions.update.enabled": false,
"general.startup.browser": false,
"loop.enabled": false,
"network.http.pipelining.maxrequests": 8,
"network.http.pipelining": true,
"network.http.proxy.pipelining": true,
"permissions.default.image": 2,
"plugin.default_plugin_disabled": false,
"reader.parse-on-load.enabled": false
}
11 changes: 8 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="./icon.png" />
<!-- See https://stackoverflow.com/a/13416784 -->
<link rel="icon" href="data:;base64,=" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Enketo Transformer (web)</title>
</head>
<body>
<script type="module">
import { transform } from './src/transformer.ts';

globalThis.enketo = {
transformer: { transform },
};
</script>
</head>
<body>
<p>
Nothing to see here! This page is used for running browser tests and
benchmarks.
</p>
</body>
</html>
9 changes: 9 additions & 0 deletions test/browser-env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Transform } from '../src/transformer';

declare global {
const enketo: {
transformer: {
transform: Transform;
};
};
}
114 changes: 67 additions & 47 deletions test/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,95 +3,115 @@ import type { Attr } from 'linkedom/types/interface/attr';
import type { Element as BaseElement } from 'linkedom/types/interface/element';
import type { Node } from 'linkedom/types/interface/node';
import { resolve } from 'path';
import type { Page } from 'playwright';
import { fileURLToPath } from 'url';
import firefoxUserPrefs from '../config/firefox.json';
import type { Survey, Transform, TransformedSurvey } from '../src/transformer';
import { fixtures } from './fixtures';

export { fixtures };

// eslint-disable-next-line import/no-mutable-exports
let reload: () => Promise<void>;
let reload: () => Promise<Page | void>;

// eslint-disable-next-line import/no-mutable-exports
let transform: Transform;

declare const enketo: {
transformer: {
transform: Transform;
};
};

if (ENV === 'node') {
reload = () => Promise.resolve();
transform = (await import('../src/transformer')).transform;
} else {
const { createServer } = await import('vite');
const root = fileURLToPath(new URL('..', import.meta.url));
const configFile = resolve(root, './vite.config.ts');
const server = await createServer({
configFile,
define: {
PACKAGE_VERSION: JSON.stringify(PACKAGE_VERSION),
VERSION: JSON.stringify(VERSION),
ENV: JSON.stringify(ENV),
BROWSER: JSON.stringify(BROWSER),
},
root,
});

await server.listen();

server.printUrls();

const playwright = await import('playwright');
const browserType = playwright[BROWSER];
const browser = await browserType.launch();

let page = await browser.newPage();
const [server, browser] = await Promise.all([
createServer({
configFile,
// clearScreen: false,
define: {
PACKAGE_VERSION: JSON.stringify(PACKAGE_VERSION),
VERSION: JSON.stringify(VERSION),
ENV: JSON.stringify(ENV),
BROWSER: JSON.stringify(BROWSER),
},
root,
}),
browserType.launch({
firefoxUserPrefs,
}),
]);

let isLoading = false;
await server.listen();

page.on('console', async (message) => {
if (!isLoading) {
console.log(
...(await Promise.all(
message.args().map((arg) => arg.jsonValue())
))
);
}
});
const url = server.resolvedUrls!.local[0]!;

let isFirstLoad = true;
let page: Page | null = null;
let isLoading = false;

reload = async () => {
const load = async () => {
isLoading = true;
const url = 'http://localhost:8085';

if (isFirstLoad) {
await page.goto(url);
isFirstLoad = false;
} else {
await page.close();
const [context] = await Promise.all([
browser.newContext(),
page?.close(),
]);

const context = await browser.newContext();
page = await context.newPage();

page = await context.newPage();
await page.goto(url);
}
page.on('console', async (message) => {
// This basically just suppresses useless built-in Vite logging
if (!isLoading) {
let type = message.type();

if (type === 'warning') {
type = 'warn';
}

const args = await Promise.all(
message.args().map((arg) => arg.jsonValue())
);

if (type === 'trace') {
type = 'log';
args.push(message.location());
}

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - even if the return type for `message.type` were more
// accurate, this would still fail because some console methods are
// not variadic. We just have to trust that Playwright is passing
// the correct arguments for whichever console method was called.
console[type](...args);
}
});

await page.goto(url);
await page.waitForFunction(() => typeof enketo !== 'undefined');

isLoading = false;

return page;
};

await reload();
page = await load();

reload = load;

transform = async <T extends Survey>(
survey: T
): Promise<TransformedSurvey<T>> => {
// The *intent* here is that the global declaration will only affect web
// environments. Unfortunately, like TypeScript's DOM lib, there is no
// such thing as conditional global augmentation.
await import('./browser-env');

delete survey.preprocess;

const { error, result } = await page.evaluate(
const { error, result } = await page!.evaluate(
async ([input]) => {
try {
const result = await enketo.transformer.transform(input);
Expand Down

0 comments on commit d9ae798

Please sign in to comment.