chore: reowrked tests to use a runBrowserTest to allow previewing the results in a browser

This commit is contained in:
2024-02-17 21:12:54 +01:00
parent 1c55b894c9
commit 3b540d0c48
7 changed files with 254 additions and 132 deletions

View File

@@ -11,44 +11,28 @@ import {isInDebugMode} from "./debug-mode.ts";
export type PageTestCallback = (page: Page)=>Promise<void>;
export interface TestFilterOptions{
html?: boolean
console?: ('log'|'error'|'warn')[] | true
errors?: boolean, // again don't know possible values
responses?: boolean, // interesting to see what other values were requested
requestsFailed?: boolean, // will probably also be replicated into console errors, but helpful to have if imports werent found
}
export interface TestOptions {
page: string
path: string
cb: PageTestCallback
filterOutput: TestFilterOptions
replaceHost: boolean
replaceHostWith?: string
}
const defaultOptions: Partial<TestOptions> = {
page: 'index.html',
path: 'index.html',
cb: async (page: Page)=>{
await page.waitForNetworkIdle({});
},
replaceHost: true,
replaceHostWith: `http://localhost`,
filterOutput:{
html: true,
console: ['log','error','warn'],// TODO: or warning? need to check what possible values are
errors: true, // again don't know possible values
responses: true, // interesting to see what other values were requested
requestsFailed: true, // will probably also be replicated into console errors, but helpful to have if imports werent found
}
}
export interface TestOutput{
html?: string,
console?: string[],
errors?: string[],
responses?: string[],
requestsFailed?: string[],
html: string,
console: string[],
errors: string[],
responses: string[],
requestsFailed: string[],
}
/**
* Opens a page in a puppeteer browser and return the resulting HTML and logmessages produced.
* Optionally a callback can be provided to simulate user interactions on the page before returning the HTML
@@ -61,17 +45,12 @@ export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: stri
const options : TestOptions = (<TestOptions>{
...defaultOptions,
...opts,
filterOutput: {
...defaultOptions.filterOutput,
...(opts?.filterOutput),
},
});
const {
page: path,
path,
cb,
replaceHost,
replaceHostWith,
filterOutput
} = options;
const browser = await puppeteer.launch({
@@ -80,64 +59,64 @@ export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: stri
const page = await browser.newPage();
let output : TestOutput = {
html: '',
console: [],
errors: [],
responses: [],
requestsFailed: []
};
try{
let errored = false;
try {
// Track requests, errors and console
page.on('console', message => {
let [type, text] = [message.type(), message.text()];
if(replaceHost){
if (replaceHost) {
text = text.replaceAll(hostUrl, replaceHostWith!);
}
if((<any>filterOutput.console)?.includes?.(<any>type) ?? (filterOutput.console === true)){// TODO: add callback option
output.console?.push(`[${type}] ${text}`);
}
}).on('pageerror', ({ message }) => {
output.console?.push(`[${type}] ${text}`);
}).on('pageerror', ({message}) => {
let text = message;
if(replaceHost){
if (replaceHost) {
text = text.replaceAll(hostUrl, replaceHostWith!);
}
if(filterOutput.errors === true) {// TODO add callback option
output.errors?.push(text)
}
output.errors?.push(text);
}).on('response', response => {
let [status, url] = [response.status(), response.url()]
if(replaceHost){
if (replaceHost) {
url = url.replaceAll(hostUrl, replaceHostWith!);
}
if(filterOutput.responses === true) {// TODO add callback option
output.responses?.push(`${status} ${url}`)
}
output.responses?.push(`${status} ${url}`);
}).on('requestfailed', request => {
let [failure, url] = [request.failure()?.errorText, request.url()];
if(replaceHost){
if (replaceHost) {
failure = failure?.replaceAll(hostUrl, replaceHostWith!);
url = url.replaceAll(hostUrl, replaceHostWith!);
}
if(filterOutput.requestsFailed === true) {// TODO add callback option
output.requestsFailed?.push(`${failure} ${url}`)
}
output.requestsFailed?.push(`${failure} ${url}`);
});
const url = new URL(`${hostUrl}/${path??''}`);
const url = new URL(path??'', hostUrl);
await page.goto(url.href);
if(!cb) {
if (!cb) {
await page.waitForNetworkIdle({});
}else{
} else {
await cb(page);
}
const htmlHandle = await page.$('html');
const html = await page.evaluate(html => html?.outerHTML??html?.innerHTML, htmlHandle);
const html = await page.evaluate(html => html?.outerHTML ?? html?.innerHTML, htmlHandle);
// Add the final html
output.html = html;
output.html = html || '';
return output;
}catch(err){
errored = true;
throw err;
}finally{
if(isInDebugMode()){
if(isInDebugMode() && !errored){
console.log(`DEBUG MODE ENABLED, Close the puppeteer browsertab to continue!\n${import.meta.url}:144`);
await new Promise((resolve)=>{
page.on('close', ()=>{
@@ -148,9 +127,7 @@ export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: stri
}else{
await page.close();
}
await browser.close();
}
return output;
}