chore: reowrked tests to use a runBrowserTest to allow previewing the results in a browser
This commit is contained in:
parent
1c55b894c9
commit
3b540d0c48
@ -5,22 +5,11 @@ import { rollup } from "rollup";
|
|||||||
import urlPlugin from "@rollup/plugin-url";
|
import urlPlugin from "@rollup/plugin-url";
|
||||||
|
|
||||||
import html from "../../src/index.ts";
|
import html from "../../src/index.ts";
|
||||||
import serveTest from "../util/serve-test.ts";
|
import {runBrowserTest} from "../util/browser-test.ts";
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {OutputOptions}
|
|
||||||
*/
|
|
||||||
const output= {
|
|
||||||
dir: 'output', // Output all files
|
|
||||||
format: 'es', // iifi and cjs should be added to tests
|
|
||||||
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
|
|
||||||
chunkFileNames: '[name].js',
|
|
||||||
entryFileNames: '[name].[extname]',
|
|
||||||
assetFileNames: '[name].[extname]',
|
|
||||||
};
|
|
||||||
|
|
||||||
import {fileURLToPath} from "node:url";
|
import {fileURLToPath} from "node:url";
|
||||||
import handlebars from "handlebars";
|
import handlebars from "handlebars";
|
||||||
|
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
process.chdir(join(__dirname, 'fixtures'));
|
process.chdir(join(__dirname, 'fixtures'));
|
||||||
|
|
||||||
@ -32,7 +21,7 @@ const defaultAssetInclude = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
test.serial('web-bundle', async (t) => {
|
test.serial('web-bundle', async (t) => {
|
||||||
const bundle = await rollup({
|
const out = await runBrowserTest({
|
||||||
input: 'index.hbs',
|
input: 'index.hbs',
|
||||||
treeshake: 'smallest',
|
treeshake: 'smallest',
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -46,13 +35,19 @@ test.serial('web-bundle', async (t) => {
|
|||||||
urlPlugin({
|
urlPlugin({
|
||||||
include: defaultAssetInclude,
|
include: defaultAssetInclude,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
serveTest({
|
|
||||||
path: 'index.html',
|
|
||||||
t,
|
|
||||||
})
|
|
||||||
],
|
],
|
||||||
|
}, {
|
||||||
|
path: 'index.html',
|
||||||
|
log: t.log,
|
||||||
|
},{
|
||||||
|
dir: 'output', // Output all files
|
||||||
|
format: 'es', // iifi and cjs should be added to tests
|
||||||
|
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
|
||||||
|
chunkFileNames: '[name].js',
|
||||||
|
entryFileNames: '[name].[extname]',
|
||||||
|
assetFileNames: '[name].[extname]',
|
||||||
});
|
});
|
||||||
await bundle.generate(output);
|
t.snapshot(out);
|
||||||
|
// await bundle.generate(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -12,25 +12,11 @@ import typescriptPlugin from "@rollup/plugin-typescript";
|
|||||||
import replacePlugin from "@rollup/plugin-replace";
|
import replacePlugin from "@rollup/plugin-replace";
|
||||||
|
|
||||||
import html from "../../src/index.ts";
|
import html from "../../src/index.ts";
|
||||||
import serveTest from "../util/serve-test.ts";
|
import {runBrowserTest} from "../util/browser-test.ts";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {OutputOptions}
|
|
||||||
*/
|
|
||||||
const output= {
|
|
||||||
dir: 'output', // Output all files
|
|
||||||
format: 'es', // iifi and cjs should be added to tests
|
|
||||||
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
|
|
||||||
chunkFileNames: '[name].js',
|
|
||||||
entryFileNames: '[name].[extname]',
|
|
||||||
assetFileNames: '[name].[extname]',
|
|
||||||
};
|
|
||||||
|
|
||||||
import {fileURLToPath} from "node:url";
|
import {fileURLToPath} from "node:url";
|
||||||
import handlebars from "handlebars";
|
import handlebars from "handlebars";
|
||||||
import {debugPrintOutput, getCode} from "../util/index.ts";
|
// import {debugPrintOutput, getCode, runBrowserTest} from "../util/index.ts";
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
process.chdir(join(__dirname, 'fixtures'));
|
process.chdir(join(__dirname, 'fixtures'));
|
||||||
|
|
||||||
@ -42,7 +28,7 @@ const defaultAssetInclude = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
test.serial('web-bundle', async (t) => {
|
test.serial('web-bundle', async (t) => {
|
||||||
const bundle = await rollup({
|
const out = await runBrowserTest({
|
||||||
input: 'index.hbs',
|
input: 'index.hbs',
|
||||||
treeshake: 'smallest',
|
treeshake: 'smallest',
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -79,14 +65,19 @@ test.serial('web-bundle', async (t) => {
|
|||||||
urlPlugin({
|
urlPlugin({
|
||||||
include: defaultAssetInclude,
|
include: defaultAssetInclude,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
serveTest({
|
|
||||||
path: 'index.html',
|
|
||||||
t,
|
|
||||||
})
|
|
||||||
],
|
],
|
||||||
|
}, {
|
||||||
|
path: 'index.html',
|
||||||
|
log: t.log,
|
||||||
|
},{
|
||||||
|
dir: 'output', // Output all files
|
||||||
|
format: 'es', // iifi and cjs should be added to tests
|
||||||
|
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
|
||||||
|
chunkFileNames: '[name].js',
|
||||||
|
entryFileNames: '[name].[extname]',
|
||||||
|
assetFileNames: '[name].[extname]',
|
||||||
});
|
});
|
||||||
const generated = await bundle.generate(output);
|
t.snapshot(out);
|
||||||
|
|
||||||
// const code = await getCode(bundle, output);
|
// const code = await getCode(bundle, output);
|
||||||
// debugPrintOutput('jsx-web-app',code);
|
// debugPrintOutput('jsx-web-app',code);
|
||||||
|
|||||||
@ -1,24 +1,17 @@
|
|||||||
import {resolve, join, dirname} from "node:path";
|
import {resolve, join, dirname} from "node:path";
|
||||||
import * as path from "node:path";
|
|
||||||
import test from "ava";
|
import test from "ava";
|
||||||
import { rollup } from "rollup";
|
import {runBrowserTest} from "../util/index.ts";
|
||||||
import {debugPrintOutput, getCode} from "../util/index.ts";
|
|
||||||
|
|
||||||
import html from "../../src/index.ts";
|
import html from "../../src/index.ts";
|
||||||
|
|
||||||
const output = {
|
|
||||||
dir: 'output', // Output all files
|
|
||||||
format: 'es', // iifi and cjs should be added to tests
|
|
||||||
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
|
|
||||||
};
|
|
||||||
|
|
||||||
import {fileURLToPath} from "node:url";
|
import {fileURLToPath} from "node:url";
|
||||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
process.chdir(join(__dirname, 'fixtures'));
|
process.chdir(join(__dirname, 'fixtures'));
|
||||||
|
|
||||||
|
|
||||||
test.serial('rewrite-url', async (t) => {
|
test.serial('rewrite-url', async (t) => {
|
||||||
const bundle = await rollup({
|
|
||||||
|
const out = await runBrowserTest({
|
||||||
input: {
|
input: {
|
||||||
['index']: 'index.html',
|
['index']: 'index.html',
|
||||||
['admin/index']: resolve(__dirname,'fixtures','admin/index.html'),
|
['admin/index']: resolve(__dirname,'fixtures','admin/index.html'),
|
||||||
@ -30,11 +23,38 @@ test.serial('rewrite-url', async (t) => {
|
|||||||
return `/${rootPath}`;
|
return `/${rootPath}`;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
]
|
],
|
||||||
|
},{
|
||||||
|
log: t.log,
|
||||||
|
filterOutput:{
|
||||||
|
// TODO: Currently only need the "await getCode(bundle, output);" as output
|
||||||
|
},
|
||||||
|
path: '/admin'
|
||||||
|
}, {
|
||||||
|
dir: 'output', // Output all files
|
||||||
|
format: 'es', // iifi and cjs should be added to tests
|
||||||
|
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
|
||||||
});
|
});
|
||||||
const code = await getCode(bundle, output);
|
|
||||||
debugPrintOutput('rewrite-url',code);
|
t.snapshot(out.code); // Snapshot the result code
|
||||||
t.snapshot(code);
|
|
||||||
|
// const bundle = await rollup({
|
||||||
|
// input: {
|
||||||
|
// ['index']: 'index.html',
|
||||||
|
// ['admin/index']: resolve(__dirname,'fixtures','admin/index.html'),
|
||||||
|
// ['admin/app']: resolve(__dirname,'fixtures','admin/app.js'),
|
||||||
|
// },
|
||||||
|
// plugins: [
|
||||||
|
// html({
|
||||||
|
// rewriteUrl(relative, {rootPath, from}){
|
||||||
|
// return `/${rootPath}`;
|
||||||
|
// }
|
||||||
|
// }),
|
||||||
|
// ]
|
||||||
|
// });
|
||||||
|
// const code = await getCode(bundle, output);
|
||||||
|
// debugPrintOutput('rewrite-url',code);
|
||||||
|
// t.snapshot(code);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO various parameters
|
// TODO various parameters
|
||||||
|
|||||||
129
test/util/browser-test.ts
Normal file
129
test/util/browser-test.ts
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import {Plugin, InputPluginOption, RollupOptions, OutputOptions, RollupOutput} from "rollup";
|
||||||
|
import {TestOptions as BrowserTestOptions, TestOutput as PuppeteerTestOutput} from "./puppeteer-run-test.js";
|
||||||
|
import { rollup } from "rollup";
|
||||||
|
import serveTest, {LogCallback} from "./serve-test.js";
|
||||||
|
import type {ExecutionContext} from "ava";
|
||||||
|
import {getCode, TestOutput} from "./code-output.ts";
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * The AVA context used to test (ie t.snapshot(..) )
|
||||||
|
// */
|
||||||
|
// t: ExecutionContext
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// try{
|
||||||
|
// // Track requests, errors and console
|
||||||
|
// page.on('console', message => {
|
||||||
|
// let [type, text] = [message.type(), message.text()];
|
||||||
|
// 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 }) => {
|
||||||
|
// let text = message;
|
||||||
|
// if(replaceHost){
|
||||||
|
// text = text.replaceAll(hostUrl, replaceHostWith!);
|
||||||
|
// }
|
||||||
|
// if(filterOutput.errors === true) {// TODO add callback option
|
||||||
|
// output.errors?.push(text)
|
||||||
|
// }
|
||||||
|
// }).on('response', response => {
|
||||||
|
// let [status, url] = [response.status(), response.url()]
|
||||||
|
// if(replaceHost){
|
||||||
|
// url = url.replaceAll(hostUrl, replaceHostWith!);
|
||||||
|
// }
|
||||||
|
// if(filterOutput.responses === true) {// TODO add callback option
|
||||||
|
// output.responses?.push(`${status} ${url}`)
|
||||||
|
// }
|
||||||
|
// }).on('requestfailed', request => {
|
||||||
|
// let [failure, url] = [request.failure()?.errorText, request.url()];
|
||||||
|
// 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}`)
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// testOptions.t?.snapshot?.(testOutput);
|
||||||
|
|
||||||
|
export interface OutputFilterOptions {
|
||||||
|
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 BrowserTestInput extends BrowserTestOptions{
|
||||||
|
log?: LogCallback;
|
||||||
|
/**
|
||||||
|
* Optionally specify what to filter from the output
|
||||||
|
*/
|
||||||
|
filterOutput?: OutputFilterOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface BrowserTestOutput extends PuppeteerTestOutput{
|
||||||
|
code: TestOutput[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runBrowserTest(
|
||||||
|
build: RollupOptions,
|
||||||
|
test?: BrowserTestInput | false,
|
||||||
|
output?: OutputOptions
|
||||||
|
) : Promise<Partial<BrowserTestOutput>>{
|
||||||
|
const resolvedPlugins = await Promise.resolve(build.plugins||null);
|
||||||
|
let pluginsArray : InputPluginOption[] = [];
|
||||||
|
if(resolvedPlugins && resolvedPlugins instanceof Array){
|
||||||
|
pluginsArray = resolvedPlugins
|
||||||
|
}else if(resolvedPlugins){
|
||||||
|
pluginsArray = [resolvedPlugins];
|
||||||
|
}
|
||||||
|
|
||||||
|
let testOutput: Partial<BrowserTestOutput> = {};
|
||||||
|
const bundle = await rollup({
|
||||||
|
...build,
|
||||||
|
plugins: [
|
||||||
|
...pluginsArray,
|
||||||
|
// TODO check if browser output is requested (either for snapshot or for testing)
|
||||||
|
...(test? [serveTest({
|
||||||
|
// TODO: intercept output from the serveTest? (and include as one bit in output options below, for snapshotting)
|
||||||
|
...test,
|
||||||
|
log: test.log ?? console.log,
|
||||||
|
onResult: (output)=>{
|
||||||
|
testOutput = {...testOutput, ...output};
|
||||||
|
}
|
||||||
|
})]: [])
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO make configurable?
|
||||||
|
const generated = await bundle.generate({
|
||||||
|
dir: 'output', // Output all files
|
||||||
|
format: 'es', // iifi and cjs should be added to tests
|
||||||
|
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
|
||||||
|
chunkFileNames: '[name].js',
|
||||||
|
entryFileNames: '[name].mjs',
|
||||||
|
assetFileNames: '[name].[extname]',
|
||||||
|
});
|
||||||
|
|
||||||
|
if(output){
|
||||||
|
testOutput.code = await getCode(bundle, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
return testOutput
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
|
// TODO: this should be the main module used, other should be imported manually if exceptions are needed?
|
||||||
|
export * from "./browser-test.ts";
|
||||||
|
|
||||||
export * from "./code-output.ts";
|
export * from "./code-output.ts";
|
||||||
export * from "./print-code-output.ts";
|
export * from "./print-code-output.ts";
|
||||||
export * from "./serve-test.ts";
|
export * from "./serve-test.ts";
|
||||||
|
|
||||||
|
|
||||||
// export * from './misc.js';
|
// export * from './misc.js';
|
||||||
|
|||||||
@ -11,44 +11,28 @@ import {isInDebugMode} from "./debug-mode.ts";
|
|||||||
|
|
||||||
export type PageTestCallback = (page: Page)=>Promise<void>;
|
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 {
|
export interface TestOptions {
|
||||||
page: string
|
path: string
|
||||||
cb: PageTestCallback
|
cb: PageTestCallback
|
||||||
filterOutput: TestFilterOptions
|
|
||||||
replaceHost: boolean
|
replaceHost: boolean
|
||||||
replaceHostWith?: string
|
replaceHostWith?: string
|
||||||
}
|
}
|
||||||
const defaultOptions: Partial<TestOptions> = {
|
const defaultOptions: Partial<TestOptions> = {
|
||||||
page: 'index.html',
|
path: 'index.html',
|
||||||
cb: async (page: Page)=>{
|
cb: async (page: Page)=>{
|
||||||
await page.waitForNetworkIdle({});
|
await page.waitForNetworkIdle({});
|
||||||
},
|
},
|
||||||
replaceHost: true,
|
replaceHost: true,
|
||||||
replaceHostWith: `http://localhost`,
|
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{
|
export interface TestOutput{
|
||||||
html?: string,
|
html: string,
|
||||||
console?: string[],
|
console: string[],
|
||||||
errors?: string[],
|
errors: string[],
|
||||||
responses?: string[],
|
responses: string[],
|
||||||
requestsFailed?: string[],
|
requestsFailed: string[],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a page in a puppeteer browser and return the resulting HTML and logmessages produced.
|
* 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
|
* 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>{
|
const options : TestOptions = (<TestOptions>{
|
||||||
...defaultOptions,
|
...defaultOptions,
|
||||||
...opts,
|
...opts,
|
||||||
filterOutput: {
|
|
||||||
...defaultOptions.filterOutput,
|
|
||||||
...(opts?.filterOutput),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const {
|
const {
|
||||||
page: path,
|
path,
|
||||||
cb,
|
cb,
|
||||||
replaceHost,
|
replaceHost,
|
||||||
replaceHostWith,
|
replaceHostWith,
|
||||||
filterOutput
|
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const browser = await puppeteer.launch({
|
const browser = await puppeteer.launch({
|
||||||
@ -80,12 +59,15 @@ export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: stri
|
|||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
|
||||||
let output : TestOutput = {
|
let output : TestOutput = {
|
||||||
|
html: '',
|
||||||
console: [],
|
console: [],
|
||||||
errors: [],
|
errors: [],
|
||||||
responses: [],
|
responses: [],
|
||||||
requestsFailed: []
|
requestsFailed: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let errored = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Track requests, errors and console
|
// Track requests, errors and console
|
||||||
page.on('console', message => {
|
page.on('console', message => {
|
||||||
@ -93,37 +75,29 @@ export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: stri
|
|||||||
if (replaceHost) {
|
if (replaceHost) {
|
||||||
text = text.replaceAll(hostUrl, replaceHostWith!);
|
text = text.replaceAll(hostUrl, replaceHostWith!);
|
||||||
}
|
}
|
||||||
if((<any>filterOutput.console)?.includes?.(<any>type) ?? (filterOutput.console === true)){// TODO: add callback option
|
|
||||||
output.console?.push(`[${type}] ${text}`);
|
output.console?.push(`[${type}] ${text}`);
|
||||||
}
|
|
||||||
}).on('pageerror', ({message}) => {
|
}).on('pageerror', ({message}) => {
|
||||||
let text = message;
|
let text = message;
|
||||||
if (replaceHost) {
|
if (replaceHost) {
|
||||||
text = text.replaceAll(hostUrl, replaceHostWith!);
|
text = text.replaceAll(hostUrl, replaceHostWith!);
|
||||||
}
|
}
|
||||||
if(filterOutput.errors === true) {// TODO add callback option
|
output.errors?.push(text);
|
||||||
output.errors?.push(text)
|
|
||||||
}
|
|
||||||
}).on('response', response => {
|
}).on('response', response => {
|
||||||
let [status, url] = [response.status(), response.url()]
|
let [status, url] = [response.status(), response.url()]
|
||||||
if (replaceHost) {
|
if (replaceHost) {
|
||||||
url = url.replaceAll(hostUrl, replaceHostWith!);
|
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 => {
|
}).on('requestfailed', request => {
|
||||||
let [failure, url] = [request.failure()?.errorText, request.url()];
|
let [failure, url] = [request.failure()?.errorText, request.url()];
|
||||||
if (replaceHost) {
|
if (replaceHost) {
|
||||||
failure = failure?.replaceAll(hostUrl, replaceHostWith!);
|
failure = failure?.replaceAll(hostUrl, replaceHostWith!);
|
||||||
url = url.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);
|
await page.goto(url.href);
|
||||||
|
|
||||||
if (!cb) {
|
if (!cb) {
|
||||||
@ -135,9 +109,14 @@ export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: stri
|
|||||||
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
|
// Add the final html
|
||||||
output.html = html;
|
output.html = html || '';
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}catch(err){
|
||||||
|
errored = true;
|
||||||
|
throw err;
|
||||||
}finally{
|
}finally{
|
||||||
if(isInDebugMode()){
|
if(isInDebugMode() && !errored){
|
||||||
console.log(`DEBUG MODE ENABLED, Close the puppeteer browsertab to continue!\n${import.meta.url}:144`);
|
console.log(`DEBUG MODE ENABLED, Close the puppeteer browsertab to continue!\n${import.meta.url}:144`);
|
||||||
await new Promise((resolve)=>{
|
await new Promise((resolve)=>{
|
||||||
page.on('close', ()=>{
|
page.on('close', ()=>{
|
||||||
@ -148,9 +127,7 @@ export async function puppeteerRunTest(opts: Partial<TestOptions>, hostUrl: stri
|
|||||||
}else{
|
}else{
|
||||||
await page.close();
|
await page.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
await browser.close();
|
await browser.close();
|
||||||
}
|
}
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
import {puppeteerRunTest, TestFilterOptions, PageTestCallback} from "./puppeteer-run-test.ts";
|
import {puppeteerRunTest, PageTestCallback, TestOutput} from "./puppeteer-run-test.ts";
|
||||||
import {isInDebugMode} from "./debug-mode.ts";
|
import {isInDebugMode} from "./debug-mode.ts";
|
||||||
|
|
||||||
import {resolve, posix} from "node:path";
|
import {resolve, posix} from "node:path";
|
||||||
@ -28,7 +28,7 @@ import type {
|
|||||||
} from 'http'
|
} from 'http'
|
||||||
import type { ServerOptions } from 'https'
|
import type { ServerOptions } from 'https'
|
||||||
|
|
||||||
import type {ExecutionContext} from "ava";
|
import test, {ExecutionContext} from "ava";
|
||||||
import {createReadStream} from "fs";
|
import {createReadStream} from "fs";
|
||||||
|
|
||||||
|
|
||||||
@ -37,32 +37,27 @@ type TypeMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type ErrorCodeException = Error & {code: string};
|
type ErrorCodeException = Error & {code: string};
|
||||||
|
export type TestResultCallback = (output: TestOutput)=>void;
|
||||||
|
export type LogCallback = (...args: string[])=>void;
|
||||||
|
|
||||||
export interface RollupServeTestOptions {
|
|
||||||
|
export interface ServeTestOptions {
|
||||||
/**
|
/**
|
||||||
* Change the path to be opened when the test is started
|
* Change the path to be opened when the test is started
|
||||||
* Remember to start with a slash, e.g. `'/different/page'`
|
* Remember to start with a slash, e.g. `'/different/page'`
|
||||||
*/
|
*/
|
||||||
path?: string
|
path?: string
|
||||||
|
|
||||||
/**
|
|
||||||
* Optionally specify what to filter from the output
|
|
||||||
*/
|
|
||||||
filterOutput?: TestFilterOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fallback to serving from a specified srcDir
|
* Fallback to serving from a specified srcDir, this allows setting breakpoints on sourcecode and test the sourcemaps
|
||||||
*/
|
*/
|
||||||
srcDir?: string|boolean;
|
srcDir?: string|boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A callback to manually take control of the page and simulate user interactions
|
* A callback to manually take control of the page and simulate user interactions
|
||||||
*/
|
*/
|
||||||
cb?: PageTestCallback
|
cb?: PageTestCallback;
|
||||||
/**
|
|
||||||
* The AVA context used to test (ie t.snapshot(..) )
|
|
||||||
*/
|
|
||||||
t: ExecutionContext
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to `true` to return index.html (200) instead of error page (404)
|
* Set to `true` to return index.html (200) instead of error page (404)
|
||||||
@ -105,6 +100,20 @@ export interface RollupServeTestOptions {
|
|||||||
* Execute function after server has begun listening
|
* Execute function after server has begun listening
|
||||||
*/
|
*/
|
||||||
onListening?: (server: Server) => void
|
onListening?: (server: Server) => void
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RollupServeTestOptions extends ServeTestOptions{
|
||||||
|
/**
|
||||||
|
* A callback to run when a test has been run
|
||||||
|
*/
|
||||||
|
onResult?: TestResultCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to log messages
|
||||||
|
*/
|
||||||
|
log?: LogCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -137,7 +146,7 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
info: 34,
|
info: 34,
|
||||||
warn: 33,
|
warn: 33,
|
||||||
}[mode];
|
}[mode];
|
||||||
testOptions.t.log(`\u001b[${modeColor}m${msg}\u001b[0m`);
|
testOptions.log?.(`\u001b[${modeColor}m${msg}\u001b[0m`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestListener = async (request: IncomingMessage, response: ServerResponse) => {
|
const requestListener = async (request: IncomingMessage, response: ServerResponse) => {
|
||||||
@ -266,11 +275,10 @@ export default function serveTest (options: RollupServeTestOptions ): Plugin {
|
|||||||
first = false
|
first = false
|
||||||
|
|
||||||
const testOutput = await puppeteerRunTest({
|
const testOutput = await puppeteerRunTest({
|
||||||
page: testOptions.path!,
|
...testOptions
|
||||||
cb: testOptions.cb,
|
}, url);
|
||||||
filterOutput: testOptions.filterOutput,
|
|
||||||
}, url)
|
testOptions.onResult?.(testOutput);
|
||||||
testOptions.t?.snapshot?.(testOutput);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user