onnxruntime/js/web/test/e2e/exports/test.js
Scott McKay 04ff0ceeed Merge
2025-01-18 11:24:02 +10:00

127 lines
4.2 KiB
JavaScript

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
const EventEmitter = require('node:events');
const path = require('path');
const { runShellCmd } = require('./utils');
const launchBrowserAndRunTests = async (logPrefix, port) => {
const testResults = [];
const puppeteer = require('puppeteer-core');
let browser;
try {
browser = await puppeteer.launch({
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
browser: 'chrome',
headless: true,
args: ['--enable-features=SharedArrayBuffer', '--no-sandbox', '--disable-setuid-sandbox'],
});
for await (const flags of [
[false, false],
[false, true],
[true, false],
[true, true],
]) {
const [multiThread, proxy] = flags;
console.log(`[${logPrefix}] Running test with multi-thread: ${multiThread}, proxy: ${proxy}...`);
const page = await browser.newPage();
await page.goto(`http://localhost:${port}`);
// wait for the page to load
await page.waitForSelector('#ortstate', { visible: true });
// if multi-thread is enabled, check the checkbox
if (multiThread) {
await page.locator('#cb-mt').click();
}
// if proxy is enabled, check the checkbox
if (proxy) {
await page.locator('#cb-px').click();
}
// click the load model button
await page.locator('#btn-load').click();
// wait for the model to load or fail
await page.waitForFunction("['2','3'].includes(document.getElementById('ortstate').innerText)");
// verify the model is loaded
const modelLoadState = await page.$eval('#ortstate', (el) => el.innerText);
if (modelLoadState !== '2') {
const ortLog = await page.$eval('#ortlog', (el) => el.innerText);
testResults.push({ multiThread, proxy, success: false, message: `Failed to load model: ${ortLog}` });
continue;
}
// click the run test button
await page.locator('#btn-run').click();
// wait for the inference run to complete or fail
await page.waitForFunction("['5','6'].includes(document.getElementById('ortstate').innerText)");
// verify the inference run result
const runState = await page.$eval('#ortstate', (el) => el.innerText);
if (runState !== '5') {
const ortLog = await page.$eval('#ortlog', (el) => el.innerText);
testResults.push({ multiThread, proxy, success: false, message: `Failed to run model: ${ortLog}` });
continue;
}
testResults.push({ multiThread, proxy, success: true });
}
return testResults;
} finally {
console.log(`[${logPrefix}] Closing the browser...`);
// close the browser
if (browser) {
await browser.close();
}
}
};
async function runTest(testCaseName, logPrefix, ready, cmd, port) {
const wd = path.join(__dirname, 'testcases', testCaseName);
logPrefix = [testCaseName, ...logPrefix].join(':');
console.log(`[${logPrefix}] Testing...`);
const npmRunDevEvent = new EventEmitter();
const npmRunDev = runShellCmd(cmd, {
wd,
event: npmRunDevEvent,
ready,
ignoreExitCode: true,
});
let testResults;
npmRunDevEvent.on('serverReady', async () => {
try {
testResults = await launchBrowserAndRunTests(logPrefix, port);
} finally {
console.log(`[${logPrefix}] Killing the server...`);
// kill the server as the last step
npmRunDevEvent.emit('kill');
}
});
await npmRunDev;
console.log(`[${logPrefix}] test result:`, testResults);
if (testResults.some((r) => !r.success)) {
throw new Error(`[${logPrefix}] test failed.`);
}
}
async function runDevTest(testCaseName, ready, port, logPrefix = '', cmd = 'npm run dev') {
return runTest(testCaseName, logPrefix ? ['dev', logPrefix] : ['dev'], ready, cmd, port);
}
async function runProdTest(testCaseName, ready, port) {
const wd = path.join(__dirname, 'testcases', testCaseName);
console.log(`[${testCaseName}:prod] Building...`);
await runShellCmd('npm run build', { wd });
await runTest(testCaseName, ['prod'], ready, 'npm run start', port);
}
module.exports = {
runDevTest,
runProdTest,
};