@web/test-runner-core
Advanced tools
Comparing version 0.0.0-canary-20230420104136 to 0.0.0-canary-20231122093600
@@ -1,2 +0,2 @@ | ||
import { TestSession, TestResultError, TestSuiteResult, TestResult } from '../dist/index'; | ||
import { TestSession, TestResultError, TestSuiteResult, TestResult } from '../dist/index.js'; | ||
@@ -3,0 +3,0 @@ export interface RuntimeConfig { |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=BrowserLauncher.js.map |
@@ -1,8 +0,6 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BufferedLogger = void 0; | ||
class BufferedLogger { | ||
export class BufferedLogger { | ||
parent; | ||
buffer = []; | ||
constructor(parent) { | ||
this.parent = parent; | ||
this.buffer = []; | ||
} | ||
@@ -36,3 +34,2 @@ log(...messages) { | ||
} | ||
exports.BufferedLogger = BufferedLogger; | ||
//# sourceMappingURL=BufferedLogger.js.map |
@@ -1,12 +0,6 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getManualDebugMenu = void 0; | ||
const nanocolors_1 = require("nanocolors"); | ||
const ip_1 = __importDefault(require("ip")); | ||
function getManualDebugMenu(config) { | ||
import { cyan, gray } from 'nanocolors'; | ||
import ip from 'ip'; | ||
export function getManualDebugMenu(config) { | ||
const localAddress = `${config.protocol}//${config.hostname}:${config.port}/`; | ||
const networkAddress = `${config.protocol}//${ip_1.default.address()}:${config.port}/`; | ||
const networkAddress = `${config.protocol}//${ip.address()}:${config.port}/`; | ||
return [ | ||
@@ -18,10 +12,9 @@ 'Debug manually in a browser not controlled by the test runner.', | ||
' ', | ||
`Local address: ${nanocolors_1.cyan(localAddress)}`, | ||
`Network address: ${nanocolors_1.cyan(networkAddress)}`, | ||
`Local address: ${cyan(localAddress)}`, | ||
`Network address: ${cyan(networkAddress)}`, | ||
' ', | ||
`${nanocolors_1.gray('Press')} D ${nanocolors_1.gray('to open the browser.')}`, | ||
`${nanocolors_1.gray('Press')} ${config.manual ? 'Q' : 'ESC'} ${nanocolors_1.gray('to exit manual debug.')}`, | ||
`${gray('Press')} D ${gray('to open the browser.')}`, | ||
`${gray('Press')} ${config.manual ? 'Q' : 'ESC'} ${gray('to exit manual debug.')}`, | ||
].filter(_ => !!_); | ||
} | ||
exports.getManualDebugMenu = getManualDebugMenu; | ||
//# sourceMappingURL=getManualDebugMenu.js.map |
@@ -1,12 +0,9 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getSelectFilesMenu = void 0; | ||
const nanocolors_1 = require("nanocolors"); | ||
const path_1 = require("path"); | ||
function getSelectFilesMenu(succeededFiles, failedFiles) { | ||
import { cyan, red } from 'nanocolors'; | ||
import { relative } from 'path'; | ||
export function getSelectFilesMenu(succeededFiles, failedFiles) { | ||
const maxI = succeededFiles.length + failedFiles.length; | ||
const minWidth = maxI.toString().length + 1; | ||
function formatTestFile(file, i, offset, failed) { | ||
const relativePath = path_1.relative(process.cwd(), file); | ||
return `[${i + offset}]${' '.repeat(Math.max(0, minWidth - (i + offset).toString().length))}${failed ? nanocolors_1.red(relativePath) : nanocolors_1.cyan(relativePath)}`; | ||
const relativePath = relative(process.cwd(), file); | ||
return `[${i + offset}]${' '.repeat(Math.max(0, minWidth - (i + offset).toString().length))}${failed ? red(relativePath) : cyan(relativePath)}`; | ||
} | ||
@@ -23,3 +20,2 @@ const entries = [ | ||
} | ||
exports.getSelectFilesMenu = getSelectFilesMenu; | ||
//# sourceMappingURL=getSelectFilesMenu.js.map |
@@ -1,26 +0,22 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getWatchCommands = void 0; | ||
const nanocolors_1 = require("nanocolors"); | ||
function getWatchCommands(coverage, testFiles, focusedTest) { | ||
import { gray } from 'nanocolors'; | ||
export function getWatchCommands(coverage, testFiles, focusedTest) { | ||
if (focusedTest) { | ||
return [ | ||
`${nanocolors_1.gray('Press')} F ${nanocolors_1.gray('to focus another test file.')}`, | ||
`${nanocolors_1.gray('Press')} D ${nanocolors_1.gray('to debug in the browser.')}`, | ||
coverage ? `${nanocolors_1.gray('Press')} C ${nanocolors_1.gray('to view coverage details.')}` : '', | ||
`${nanocolors_1.gray('Press')} Q ${nanocolors_1.gray('to exit watch mode.')}`, | ||
`${nanocolors_1.gray('Press')} Enter ${nanocolors_1.gray('to re-run this test file.')}`, | ||
`${nanocolors_1.gray('Press')} ESC ${nanocolors_1.gray('to exit focus mode')}`, | ||
`${gray('Press')} F ${gray('to focus another test file.')}`, | ||
`${gray('Press')} D ${gray('to debug in the browser.')}`, | ||
coverage ? `${gray('Press')} C ${gray('to view coverage details.')}` : '', | ||
`${gray('Press')} Q ${gray('to exit watch mode.')}`, | ||
`${gray('Press')} Enter ${gray('to re-run this test file.')}`, | ||
`${gray('Press')} ESC ${gray('to exit focus mode')}`, | ||
].filter(_ => !!_); | ||
} | ||
return [ | ||
testFiles.length > 1 ? `${nanocolors_1.gray('Press')} F ${nanocolors_1.gray('to focus on a test file.')}` : '', | ||
`${nanocolors_1.gray('Press')} D ${nanocolors_1.gray('to debug in the browser.')}`, | ||
`${nanocolors_1.gray('Press')} M ${nanocolors_1.gray('to debug manually in a custom browser.')}`, | ||
coverage ? `${nanocolors_1.gray('Press')} C ${nanocolors_1.gray('to view coverage details.')}` : '', | ||
`${nanocolors_1.gray('Press')} Q ${nanocolors_1.gray('to quit watch mode.')}`, | ||
`${nanocolors_1.gray('Press')} Enter ${nanocolors_1.gray('to re-run all tests.')}`, | ||
testFiles.length > 1 ? `${gray('Press')} F ${gray('to focus on a test file.')}` : '', | ||
`${gray('Press')} D ${gray('to debug in the browser.')}`, | ||
`${gray('Press')} M ${gray('to debug manually in a custom browser.')}`, | ||
coverage ? `${gray('Press')} C ${gray('to view coverage details.')}` : '', | ||
`${gray('Press')} Q ${gray('to quit watch mode.')}`, | ||
`${gray('Press')} Enter ${gray('to re-run all tests.')}`, | ||
].filter(_ => !!_); | ||
} | ||
exports.getWatchCommands = getWatchCommands; | ||
//# sourceMappingURL=getWatchCommands.js.map |
@@ -1,20 +0,15 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BufferedConsole = void 0; | ||
const stream_1 = require("stream"); | ||
const console_1 = require("console"); | ||
import { Writable } from 'stream'; | ||
import { Console } from 'console'; | ||
/** | ||
* Buffers console messages so that they can be flushed all at once. | ||
*/ | ||
class BufferedConsole { | ||
constructor() { | ||
this.buffer = []; | ||
this.outStream = new stream_1.Writable({ | ||
write: (chunk, encoding, callback) => { | ||
callback(); | ||
this.buffer.push(chunk); | ||
}, | ||
}); | ||
this.console = new console_1.Console({ colorMode: true, stdout: this.outStream }); | ||
} | ||
export class BufferedConsole { | ||
buffer = []; | ||
outStream = new Writable({ | ||
write: (chunk, encoding, callback) => { | ||
callback(); | ||
this.buffer.push(chunk); | ||
}, | ||
}); | ||
console = new Console({ colorMode: true, stdout: this.outStream }); | ||
flush() { | ||
@@ -28,3 +23,2 @@ // flush all pending console output | ||
} | ||
exports.BufferedConsole = BufferedConsole; | ||
//# sourceMappingURL=BufferedConsole.js.map |
@@ -1,2 +0,2 @@ | ||
import { EventEmitter } from '../../utils/EventEmitter'; | ||
import { EventEmitter } from '../../utils/EventEmitter.js'; | ||
interface EventMap { | ||
@@ -3,0 +3,0 @@ input: string; |
@@ -1,25 +0,13 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DynamicTerminal = void 0; | ||
const log_update_1 = __importDefault(require("log-update")); | ||
const cli_cursor_1 = __importDefault(require("cli-cursor")); | ||
const BufferedConsole_1 = require("./BufferedConsole"); | ||
const EventEmitter_1 = require("../../utils/EventEmitter"); | ||
import logUpdate from 'log-update'; | ||
import cliCursor from 'cli-cursor'; | ||
import { BufferedConsole } from './BufferedConsole.js'; | ||
import { EventEmitter } from '../../utils/EventEmitter.js'; | ||
const CLEAR_COMMAND = process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H'; | ||
class DynamicTerminal extends EventEmitter_1.EventEmitter { | ||
constructor() { | ||
super(...arguments); | ||
this.originalFunctions = {}; | ||
this.previousDynamic = []; | ||
this.started = false; | ||
this.bufferedConsole = new BufferedConsole_1.BufferedConsole(); | ||
this.pendingConsoleFlush = false; | ||
this.isInteractive = process.stdout.isTTY; | ||
this.onStdInData = (input) => { | ||
this.emit('input', input); | ||
}; | ||
} | ||
export class DynamicTerminal extends EventEmitter { | ||
originalFunctions = {}; | ||
previousDynamic = []; | ||
started = false; | ||
bufferedConsole = new BufferedConsole(); | ||
pendingConsoleFlush = false; | ||
isInteractive = process.stdout.isTTY; | ||
start() { | ||
@@ -36,2 +24,5 @@ // start off with an empty line | ||
} | ||
onStdInData = (input) => { | ||
this.emit('input', input); | ||
}; | ||
observeDirectInput() { | ||
@@ -44,3 +35,3 @@ if (!this.isInteractive) { | ||
} | ||
cli_cursor_1.default.hide(); | ||
cliCursor.hide(); | ||
} | ||
@@ -54,8 +45,9 @@ observeConfirmedInput() { | ||
} | ||
cli_cursor_1.default.show(); | ||
cliCursor.show(); | ||
} | ||
stop() { | ||
this.flushConsoleOutput(); | ||
log_update_1.default.done(); | ||
logUpdate.done(); | ||
for (const [key, fn] of Object.entries(this.originalFunctions)) { | ||
// @ts-ignore | ||
console[key] = fn; | ||
@@ -87,3 +79,3 @@ } | ||
this.previousDynamic = entries; | ||
log_update_1.default(entries.join('\n')); | ||
logUpdate(entries.join('\n')); | ||
} | ||
@@ -120,3 +112,3 @@ /** | ||
// clear progress bar | ||
log_update_1.default.clear(); | ||
logUpdate.clear(); | ||
// log static console messages | ||
@@ -132,3 +124,2 @@ this.bufferedConsole.flush(); | ||
} | ||
exports.DynamicTerminal = DynamicTerminal; | ||
//# sourceMappingURL=DynamicTerminal.js.map |
@@ -1,4 +0,4 @@ | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestRunner } from '../runner/TestRunner'; | ||
export declare type MenuType = 'none' | 'overview' | 'focus' | 'debug' | 'manual-debug'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestRunner } from '../runner/TestRunner.js'; | ||
export type MenuType = 'none' | 'overview' | 'focus' | 'debug' | 'manual-debug'; | ||
export declare const MENUS: { | ||
@@ -5,0 +5,0 @@ NONE: MenuType; |
@@ -1,19 +0,13 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestRunnerCli = exports.MENUS = void 0; | ||
const code_frame_1 = require("@babel/code-frame"); | ||
const path_1 = __importDefault(require("path")); | ||
const nanocolors_1 = require("nanocolors"); | ||
const open_1 = __importDefault(require("open")); | ||
const writeCoverageReport_1 = require("./writeCoverageReport"); | ||
const getSelectFilesMenu_1 = require("./getSelectFilesMenu"); | ||
const getWatchCommands_1 = require("./getWatchCommands"); | ||
const DynamicTerminal_1 = require("./terminal/DynamicTerminal"); | ||
const BufferedLogger_1 = require("./BufferedLogger"); | ||
const getManualDebugMenu_1 = require("./getManualDebugMenu"); | ||
const TestSessionStatus_1 = require("../test-session/TestSessionStatus"); | ||
exports.MENUS = { | ||
import { codeFrameColumns } from '@babel/code-frame'; | ||
import path from 'path'; | ||
import { bold, cyan, red } from 'nanocolors'; | ||
import openBrowser from 'open'; | ||
import { writeCoverageReport } from './writeCoverageReport.js'; | ||
import { getSelectFilesMenu } from './getSelectFilesMenu.js'; | ||
import { getWatchCommands } from './getWatchCommands.js'; | ||
import { DynamicTerminal } from './terminal/DynamicTerminal.js'; | ||
import { BufferedLogger } from './BufferedLogger.js'; | ||
import { getManualDebugMenu } from './getManualDebugMenu.js'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
export const MENUS = { | ||
NONE: 'none', | ||
@@ -31,11 +25,17 @@ OVERVIEW: 'overview', | ||
}; | ||
class TestRunnerCli { | ||
export class TestRunnerCli { | ||
config; | ||
runner; | ||
terminal = new DynamicTerminal(); | ||
reportedFilesByTestRun = new Map(); | ||
sessions; | ||
activeMenu = MENUS.NONE; | ||
menuSucceededAndPendingFiles = []; | ||
menuFailedFiles = []; | ||
testCoverage; | ||
pendingReportPromises = []; | ||
logger; | ||
localAddress; | ||
lastStaticLog = -1; | ||
constructor(config, runner) { | ||
this.terminal = new DynamicTerminal_1.DynamicTerminal(); | ||
this.reportedFilesByTestRun = new Map(); | ||
this.activeMenu = exports.MENUS.NONE; | ||
this.menuSucceededAndPendingFiles = []; | ||
this.menuFailedFiles = []; | ||
this.pendingReportPromises = []; | ||
this.lastStaticLog = -1; | ||
this.config = config; | ||
@@ -51,3 +51,2 @@ this.runner = runner; | ||
start() { | ||
var _a; | ||
this.setupTerminalEvents(); | ||
@@ -57,3 +56,3 @@ this.setupRunnerEvents(); | ||
for (const reporter of this.config.reporters) { | ||
(_a = reporter.start) === null || _a === void 0 ? void 0 : _a.call(reporter, { | ||
reporter.start?.({ | ||
config: this.config, | ||
@@ -67,3 +66,3 @@ sessions: this.sessions, | ||
} | ||
this.switchMenu(this.config.manual ? exports.MENUS.MANUAL_DEBUG : exports.MENUS.OVERVIEW); | ||
this.switchMenu(this.config.manual ? MENUS.MANUAL_DEBUG : MENUS.OVERVIEW); | ||
if (this.config.watch || (this.config.manual && this.terminal.isInteractive)) { | ||
@@ -73,6 +72,6 @@ this.terminal.observeDirectInput(); | ||
if (this.config.staticLogging || !this.terminal.isInteractive) { | ||
this.logger.log(nanocolors_1.bold(`Running ${this.runner.testFiles.length} test files...\n`)); | ||
this.logger.log(bold(`Running ${this.runner.testFiles.length} test files...\n`)); | ||
} | ||
if (this.config.open) { | ||
open_1.default(this.localAddress); | ||
openBrowser(this.localAddress); | ||
} | ||
@@ -82,4 +81,3 @@ } | ||
this.terminal.on('input', key => { | ||
var _a; | ||
if ([exports.MENUS.DEBUG_SELECT_FILE, exports.MENUS.FOCUS_SELECT_FILE].includes(this.activeMenu)) { | ||
if ([MENUS.DEBUG_SELECT_FILE, MENUS.FOCUS_SELECT_FILE].includes(this.activeMenu)) { | ||
const i = Number(key); | ||
@@ -95,4 +93,4 @@ if (!Number.isNaN(i)) { | ||
case 'Q': | ||
if (this.activeMenu === exports.MENUS.OVERVIEW || | ||
(this.config.manual && this.activeMenu === exports.MENUS.MANUAL_DEBUG)) { | ||
if (this.activeMenu === MENUS.OVERVIEW || | ||
(this.config.manual && this.activeMenu === MENUS.MANUAL_DEBUG)) { | ||
this.runner.stop(); | ||
@@ -102,3 +100,3 @@ } | ||
case 'D': | ||
if (this.activeMenu === exports.MENUS.OVERVIEW) { | ||
if (this.activeMenu === MENUS.OVERVIEW) { | ||
if (this.runner.focusedTestFile) { | ||
@@ -111,24 +109,24 @@ this.runner.startDebugBrowser(this.runner.focusedTestFile); | ||
else { | ||
this.switchMenu(exports.MENUS.DEBUG_SELECT_FILE); | ||
this.switchMenu(MENUS.DEBUG_SELECT_FILE); | ||
} | ||
} | ||
else if (this.activeMenu === exports.MENUS.MANUAL_DEBUG) { | ||
open_1.default(this.localAddress); | ||
else if (this.activeMenu === MENUS.MANUAL_DEBUG) { | ||
openBrowser(this.localAddress); | ||
} | ||
return; | ||
case 'F': | ||
if (this.activeMenu === exports.MENUS.OVERVIEW && this.runner.testFiles.length > 1) { | ||
this.switchMenu(exports.MENUS.FOCUS_SELECT_FILE); | ||
if (this.activeMenu === MENUS.OVERVIEW && this.runner.testFiles.length > 1) { | ||
this.switchMenu(MENUS.FOCUS_SELECT_FILE); | ||
} | ||
return; | ||
case 'C': | ||
if (this.activeMenu === exports.MENUS.OVERVIEW && this.config.coverage) { | ||
open_1.default(`file://${path_1.default.resolve((_a = this.config.coverageConfig.reportDir) !== null && _a !== void 0 ? _a : '', 'lcov-report', 'index.html')}`); | ||
if (this.activeMenu === MENUS.OVERVIEW && this.config.coverage) { | ||
openBrowser(`file://${path.resolve(this.config.coverageConfig.reportDir ?? '', 'lcov-report', 'index.html')}`); | ||
} | ||
return; | ||
case 'M': | ||
this.switchMenu(exports.MENUS.MANUAL_DEBUG); | ||
this.switchMenu(MENUS.MANUAL_DEBUG); | ||
return; | ||
case KEYCODES.ESCAPE: | ||
if (this.activeMenu === exports.MENUS.OVERVIEW && this.runner.focusedTestFile) { | ||
if (this.activeMenu === MENUS.OVERVIEW && this.runner.focusedTestFile) { | ||
this.runner.focusedTestFile = undefined; | ||
@@ -138,4 +136,4 @@ this.reportTestResults(true); | ||
} | ||
else if (this.activeMenu === exports.MENUS.MANUAL_DEBUG) { | ||
this.switchMenu(exports.MENUS.OVERVIEW); | ||
else if (this.activeMenu === MENUS.MANUAL_DEBUG) { | ||
this.switchMenu(MENUS.OVERVIEW); | ||
} | ||
@@ -153,6 +151,6 @@ return; | ||
this.sessions.on('session-status-updated', session => { | ||
if (this.activeMenu !== exports.MENUS.OVERVIEW) { | ||
if (this.activeMenu !== MENUS.OVERVIEW) { | ||
return; | ||
} | ||
if (session.status === TestSessionStatus_1.SESSION_STATUS.FINISHED) { | ||
if (session.status === SESSION_STATUS.FINISHED) { | ||
this.reportTestResult(session.testFile); | ||
@@ -163,7 +161,6 @@ this.reportTestProgress(); | ||
this.runner.on('test-run-started', ({ testRun }) => { | ||
var _a; | ||
for (const reporter of this.config.reporters) { | ||
(_a = reporter.onTestRunStarted) === null || _a === void 0 ? void 0 : _a.call(reporter, { testRun }); | ||
reporter.onTestRunStarted?.({ testRun }); | ||
} | ||
if (this.activeMenu !== exports.MENUS.OVERVIEW) { | ||
if (this.activeMenu !== MENUS.OVERVIEW) { | ||
return; | ||
@@ -178,5 +175,4 @@ } | ||
this.runner.on('test-run-finished', ({ testRun, testCoverage }) => { | ||
var _a; | ||
for (const reporter of this.config.reporters) { | ||
(_a = reporter.onTestRunFinished) === null || _a === void 0 ? void 0 : _a.call(reporter, { | ||
reporter.onTestRunFinished?.({ | ||
testRun, | ||
@@ -188,3 +184,3 @@ sessions: Array.from(this.sessions.all()), | ||
} | ||
if (this.activeMenu !== exports.MENUS.OVERVIEW) { | ||
if (this.activeMenu !== MENUS.OVERVIEW) { | ||
return; | ||
@@ -204,8 +200,8 @@ } | ||
focusTestFileNr(i) { | ||
var _a; | ||
const focusedTestFile = (_a = this.menuFailedFiles[i - 1]) !== null && _a !== void 0 ? _a : this.menuSucceededAndPendingFiles[i - this.menuFailedFiles.length - 1]; | ||
const debug = this.activeMenu === exports.MENUS.DEBUG_SELECT_FILE; | ||
const focusedTestFile = this.menuFailedFiles[i - 1] ?? | ||
this.menuSucceededAndPendingFiles[i - this.menuFailedFiles.length - 1]; | ||
const debug = this.activeMenu === MENUS.DEBUG_SELECT_FILE; | ||
if (focusedTestFile) { | ||
this.runner.focusedTestFile = focusedTestFile; | ||
this.switchMenu(exports.MENUS.OVERVIEW); | ||
this.switchMenu(MENUS.OVERVIEW); | ||
if (debug) { | ||
@@ -228,6 +224,5 @@ this.runner.startDebugBrowser(focusedTestFile); | ||
reportTestResult(testFile, forceReport = false) { | ||
var _a; | ||
const testRun = this.runner.testRun; | ||
const sessionsForTestFile = Array.from(this.sessions.forTestFile(testFile)); | ||
const allFinished = sessionsForTestFile.every(s => s.status === TestSessionStatus_1.SESSION_STATUS.FINISHED); | ||
const allFinished = sessionsForTestFile.every(s => s.status === SESSION_STATUS.FINISHED); | ||
if (!allFinished) { | ||
@@ -247,6 +242,6 @@ // not all sessions for this file are finished | ||
reportedFiles.add(testFile); | ||
const bufferedLogger = new BufferedLogger_1.BufferedLogger(this.logger); | ||
const bufferedLogger = new BufferedLogger(this.logger); | ||
for (const reporter of this.config.reporters) { | ||
const sessionsForTestFile = Array.from(this.sessions.forTestFile(testFile)); | ||
(_a = reporter.reportTestFileResults) === null || _a === void 0 ? void 0 : _a.call(reporter, { | ||
reporter.reportTestFileResults?.({ | ||
logger: bufferedLogger, | ||
@@ -265,3 +260,2 @@ sessionsForTestFile, | ||
reportTestProgress(final = false) { | ||
var _a; | ||
if (this.config.manual) { | ||
@@ -281,3 +275,3 @@ return; | ||
for (const reporter of this.config.reporters) { | ||
const report = (_a = reporter.getTestProgress) === null || _a === void 0 ? void 0 : _a.call(reporter, { | ||
const report = reporter.getTestProgress?.({ | ||
sessions: Array.from(this.sessions.all()), | ||
@@ -294,5 +288,5 @@ testRun: this.runner.testRun, | ||
if (this.runner.focusedTestFile) { | ||
reports.push(`Focused on test file: ${nanocolors_1.cyan(path_1.default.relative(process.cwd(), this.runner.focusedTestFile))}\n`); | ||
reports.push(`Focused on test file: ${cyan(path.relative(process.cwd(), this.runner.focusedTestFile))}\n`); | ||
} | ||
reports.push(...getWatchCommands_1.getWatchCommands(!!this.config.coverage, this.runner.testFiles, !!this.runner.focusedTestFile), ''); | ||
reports.push(...getWatchCommands(!!this.config.coverage, this.runner.testFiles, !!this.runner.focusedTestFile), ''); | ||
} | ||
@@ -307,3 +301,2 @@ if (logStatic) { | ||
reportSyntaxErrors() { | ||
var _a; | ||
// TODO: this special cases the logger of @web/test-runner which implements | ||
@@ -317,9 +310,9 @@ // logging of syntax errors. we need to make this more generic | ||
const report = []; | ||
(_a = logger.clearLoggedSyntaxErrors) === null || _a === void 0 ? void 0 : _a.call(logger); | ||
logger.clearLoggedSyntaxErrors?.(); | ||
for (const [filePath, errors] of loggedSyntaxErrors.entries()) { | ||
for (const error of errors) { | ||
const { message, code, line, column } = error; | ||
const result = code_frame_1.codeFrameColumns(code, { start: { line, column } }, { highlightCode: true }); | ||
const relativePath = path_1.default.relative(process.cwd(), filePath); | ||
report.push(nanocolors_1.red(`Error while transforming ${nanocolors_1.cyan(relativePath)}: ${message}`)); | ||
const result = codeFrameColumns(code, { start: { line, column } }, { highlightCode: true }); | ||
const relativePath = path.relative(process.cwd(), filePath); | ||
report.push(red(`Error while transforming ${cyan(relativePath)}: ${message}`)); | ||
report.push(result); | ||
@@ -332,3 +325,3 @@ report.push(''); | ||
writeCoverageReport(testCoverage) { | ||
writeCoverageReport_1.writeCoverageReport(testCoverage, this.config.coverageConfig); | ||
writeCoverageReport(testCoverage, this.config.coverageConfig); | ||
} | ||
@@ -344,3 +337,3 @@ switchMenu(menu) { | ||
switch (menu) { | ||
case exports.MENUS.OVERVIEW: | ||
case MENUS.OVERVIEW: | ||
this.reportTestResults(true); | ||
@@ -352,7 +345,7 @@ this.reportTestProgress(); | ||
break; | ||
case exports.MENUS.FOCUS_SELECT_FILE: | ||
case exports.MENUS.DEBUG_SELECT_FILE: | ||
case MENUS.FOCUS_SELECT_FILE: | ||
case MENUS.DEBUG_SELECT_FILE: | ||
this.logSelectFilesMenu(); | ||
break; | ||
case exports.MENUS.MANUAL_DEBUG: | ||
case MENUS.MANUAL_DEBUG: | ||
this.logManualDebugMenu(); | ||
@@ -369,3 +362,3 @@ break; | ||
const sessions = Array.from(this.sessions.forTestFile(testFile)); | ||
if (sessions.every(t => t.status === TestSessionStatus_1.SESSION_STATUS.FINISHED && !t.passed)) { | ||
if (sessions.every(t => t.status === SESSION_STATUS.FINISHED && !t.passed)) { | ||
this.menuFailedFiles.push(testFile); | ||
@@ -377,19 +370,18 @@ } | ||
} | ||
const selectFilesEntries = getSelectFilesMenu_1.getSelectFilesMenu(this.menuSucceededAndPendingFiles, this.menuFailedFiles); | ||
const selectFilesEntries = getSelectFilesMenu(this.menuSucceededAndPendingFiles, this.menuFailedFiles); | ||
this.terminal.logDynamic([]); | ||
this.terminal.logStatic(selectFilesEntries); | ||
this.terminal.logPendingUserInput(`Number of the file to ${this.activeMenu === exports.MENUS.FOCUS_SELECT_FILE ? 'focus' : 'debug'}: `); | ||
this.terminal.logPendingUserInput(`Number of the file to ${this.activeMenu === MENUS.FOCUS_SELECT_FILE ? 'focus' : 'debug'}: `); | ||
this.terminal.observeConfirmedInput(); | ||
} | ||
logManualDebugMenu() { | ||
this.terminal.logDynamic(getManualDebugMenu_1.getManualDebugMenu(this.config)); | ||
this.terminal.logDynamic(getManualDebugMenu(this.config)); | ||
} | ||
async reportEnd() { | ||
var _a; | ||
for (const reporter of this.config.reporters) { | ||
await ((_a = reporter.stop) === null || _a === void 0 ? void 0 : _a.call(reporter, { | ||
await reporter.stop?.({ | ||
sessions: Array.from(this.sessions.all()), | ||
testCoverage: this.testCoverage, | ||
focusedTestFile: this.runner.focusedTestFile, | ||
})); | ||
}); | ||
} | ||
@@ -401,3 +393,2 @@ this.reportTestProgress(true); | ||
} | ||
exports.TestRunnerCli = TestRunnerCli; | ||
//# sourceMappingURL=TestRunnerCli.js.map |
@@ -1,12 +0,6 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.writeCoverageReport = void 0; | ||
const istanbul_reports_1 = __importDefault(require("istanbul-reports")); | ||
const istanbul_lib_report_1 = __importDefault(require("istanbul-lib-report")); | ||
function writeCoverageReport(testCoverage, config) { | ||
import reports from 'istanbul-reports'; | ||
import libReport from 'istanbul-lib-report'; | ||
export function writeCoverageReport(testCoverage, config) { | ||
// create a context for report generation | ||
const context = istanbul_lib_report_1.default.createContext({ | ||
const context = libReport.createContext({ | ||
dir: config.reportDir, | ||
@@ -23,3 +17,3 @@ watermarks: { | ||
for (const reporter of reporters) { | ||
const report = istanbul_reports_1.default.create(reporter, { | ||
const report = reports.create(reporter, { | ||
projectRoot: process.cwd(), | ||
@@ -31,3 +25,2 @@ maxCols: process.stdout.columns || 100, | ||
} | ||
exports.writeCoverageReport = writeCoverageReport; | ||
//# sourceMappingURL=writeCoverageReport.js.map |
import { Middleware } from '@web/dev-server-core'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
import { TestFramework } from '../test-framework/TestFramework.js'; | ||
import { TestSession } from '../test-session/TestSession.js'; | ||
import { Reporter } from '../reporter/Reporter.js'; | ||
@@ -44,3 +45,3 @@ import { Logger } from '../logger/Logger.js'; | ||
args: any[]; | ||
}) => boolean; | ||
}, session?: Partial<TestSession>) => boolean; | ||
coverage?: boolean; | ||
@@ -47,0 +48,0 @@ coverageConfig: CoverageConfig; |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=TestRunnerCoreConfig.js.map |
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestRunnerCoreConfig } from './TestRunnerCoreConfig'; | ||
import { TestRunnerCoreConfig } from './TestRunnerCoreConfig.js'; | ||
export interface TestRunnerGroupConfig { | ||
@@ -4,0 +4,0 @@ name: string; |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=TestRunnerGroupConfig.js.map |
@@ -1,6 +0,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getTestCoverage = exports.coverageTypes = void 0; | ||
const istanbul_lib_coverage_1 = require("istanbul-lib-coverage"); | ||
exports.coverageTypes = [ | ||
import pkg from 'istanbul-lib-coverage'; | ||
const { createCoverageMap } = pkg; | ||
export const coverageTypes = [ | ||
'lines', | ||
@@ -110,4 +108,4 @@ 'statements', | ||
} | ||
function getTestCoverage(sessions, config) { | ||
const coverageMap = istanbul_lib_coverage_1.createCoverageMap(); | ||
export function getTestCoverage(sessions, config) { | ||
const coverageMap = createCoverageMap(); | ||
let coverages = Array.from(sessions) | ||
@@ -125,4 +123,4 @@ .map(s => s.testCoverage) | ||
const summary = coverageMap.getCoverageSummary().data; | ||
if (config === null || config === void 0 ? void 0 : config.threshold) { | ||
for (const type of exports.coverageTypes) { | ||
if (config?.threshold) { | ||
for (const type of coverageTypes) { | ||
const { pct } = summary[type]; | ||
@@ -136,3 +134,2 @@ if (pct < config.threshold[type]) { | ||
} | ||
exports.getTestCoverage = getTestCoverage; | ||
//# sourceMappingURL=getTestCoverage.js.map |
export { CoverageMapData } from 'istanbul-lib-coverage'; | ||
import * as constants from './utils/constants'; | ||
import * as constants from './utils/constants.js'; | ||
export { constants }; | ||
export { BrowserLauncher, SessionResult } from './browser-launcher/BrowserLauncher'; | ||
export { Reporter, ReportTestResultsArgs, GetTestProgressArgs, ReporterArgs, TestRunArgs, TestRunStartedArgs, TestRunFinishedArgs, } from './reporter/Reporter'; | ||
export { TestRunner } from './runner/TestRunner'; | ||
export { TestRunnerCli } from './cli/TestRunnerCli'; | ||
export { BufferedLogger } from './cli/BufferedLogger'; | ||
export { TestRunnerPlugin } from './server/TestRunnerPlugin'; | ||
export { TestFramework } from './test-framework/TestFramework'; | ||
export { TestRunnerCoreConfig, CoverageConfig, CoverageThresholdConfig, } from './config/TestRunnerCoreConfig'; | ||
export { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig'; | ||
export { TestCoverage } from './coverage/getTestCoverage'; | ||
export { Logger, ErrorWithLocation } from './logger/Logger'; | ||
export { TestSession, TestResultError, TestResult, TestSuiteResult, } from './test-session/TestSession'; | ||
export { DebugTestSession } from './test-session/DebugTestSession'; | ||
export { BasicTestSession } from './test-session/BasicTestSession'; | ||
export { TestSessionManager } from './test-session/TestSessionManager'; | ||
export { TestSessionStatus, SESSION_STATUS } from './test-session/TestSessionStatus'; | ||
export { EventEmitter } from './utils/EventEmitter'; | ||
export { isTestFilePath } from './utils/isTestFilePath'; | ||
export { fetchSourceMap } from './utils/fetchSourceMap'; | ||
export { BrowserLauncher, SessionResult } from './browser-launcher/BrowserLauncher.js'; | ||
export { Reporter, ReportTestResultsArgs, GetTestProgressArgs, ReporterArgs, TestRunArgs, TestRunStartedArgs, TestRunFinishedArgs, } from './reporter/Reporter.js'; | ||
export { TestRunner } from './runner/TestRunner.js'; | ||
export { TestRunnerCli } from './cli/TestRunnerCli.js'; | ||
export { BufferedLogger } from './cli/BufferedLogger.js'; | ||
export { TestRunnerPlugin } from './server/TestRunnerPlugin.js'; | ||
export { TestFramework } from './test-framework/TestFramework.js'; | ||
export { TestRunnerCoreConfig, CoverageConfig, CoverageThresholdConfig, } from './config/TestRunnerCoreConfig.js'; | ||
export { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig.js'; | ||
export { TestCoverage } from './coverage/getTestCoverage.js'; | ||
export { Logger, ErrorWithLocation } from './logger/Logger.js'; | ||
export { TestSession, TestResultError, TestResult, TestSuiteResult, } from './test-session/TestSession.js'; | ||
export { DebugTestSession } from './test-session/DebugTestSession.js'; | ||
export { BasicTestSession } from './test-session/BasicTestSession.js'; | ||
export { TestSessionManager } from './test-session/TestSessionManager.js'; | ||
export { TestSessionStatus, SESSION_STATUS } from './test-session/TestSessionStatus.js'; | ||
export { EventEmitter } from './utils/EventEmitter.js'; | ||
export { isTestFilePath } from './utils/isTestFilePath.js'; | ||
export { fetchSourceMap } from './utils/fetchSourceMap.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,41 +0,11 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.fetchSourceMap = exports.isTestFilePath = exports.EventEmitter = exports.SESSION_STATUS = exports.TestSessionManager = exports.BufferedLogger = exports.TestRunnerCli = exports.TestRunner = exports.constants = void 0; | ||
const constants = __importStar(require("./utils/constants")); | ||
exports.constants = constants; | ||
var TestRunner_1 = require("./runner/TestRunner"); | ||
Object.defineProperty(exports, "TestRunner", { enumerable: true, get: function () { return TestRunner_1.TestRunner; } }); | ||
var TestRunnerCli_1 = require("./cli/TestRunnerCli"); | ||
Object.defineProperty(exports, "TestRunnerCli", { enumerable: true, get: function () { return TestRunnerCli_1.TestRunnerCli; } }); | ||
var BufferedLogger_1 = require("./cli/BufferedLogger"); | ||
Object.defineProperty(exports, "BufferedLogger", { enumerable: true, get: function () { return BufferedLogger_1.BufferedLogger; } }); | ||
var TestSessionManager_1 = require("./test-session/TestSessionManager"); | ||
Object.defineProperty(exports, "TestSessionManager", { enumerable: true, get: function () { return TestSessionManager_1.TestSessionManager; } }); | ||
var TestSessionStatus_1 = require("./test-session/TestSessionStatus"); | ||
Object.defineProperty(exports, "SESSION_STATUS", { enumerable: true, get: function () { return TestSessionStatus_1.SESSION_STATUS; } }); | ||
var EventEmitter_1 = require("./utils/EventEmitter"); | ||
Object.defineProperty(exports, "EventEmitter", { enumerable: true, get: function () { return EventEmitter_1.EventEmitter; } }); | ||
var isTestFilePath_1 = require("./utils/isTestFilePath"); | ||
Object.defineProperty(exports, "isTestFilePath", { enumerable: true, get: function () { return isTestFilePath_1.isTestFilePath; } }); | ||
var fetchSourceMap_1 = require("./utils/fetchSourceMap"); | ||
Object.defineProperty(exports, "fetchSourceMap", { enumerable: true, get: function () { return fetchSourceMap_1.fetchSourceMap; } }); | ||
import * as constants from './utils/constants.js'; | ||
export { constants }; | ||
export { TestRunner } from './runner/TestRunner.js'; | ||
export { TestRunnerCli } from './cli/TestRunnerCli.js'; | ||
export { BufferedLogger } from './cli/BufferedLogger.js'; | ||
export { TestSessionManager } from './test-session/TestSessionManager.js'; | ||
export { SESSION_STATUS } from './test-session/TestSessionStatus.js'; | ||
export { EventEmitter } from './utils/EventEmitter.js'; | ||
export { isTestFilePath } from './utils/isTestFilePath.js'; | ||
export { fetchSourceMap } from './utils/fetchSourceMap.js'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=Logger.js.map |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=Reporter.js.map |
@@ -1,14 +0,7 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.collectTestFiles = void 0; | ||
const globby_1 = __importDefault(require("globby")); | ||
const path_1 = require("path"); | ||
function collectTestFiles(patterns, baseDir = process.cwd()) { | ||
const normalizedPatterns = [patterns].flat().map(p => p.split(path_1.sep).join('/')); | ||
return globby_1.default.sync(normalizedPatterns, { cwd: baseDir, absolute: true }); | ||
import globby from 'globby'; | ||
import { sep } from 'path'; | ||
export function collectTestFiles(patterns, baseDir = process.cwd()) { | ||
const normalizedPatterns = [patterns].flat().map(p => p.split(sep).join('/')); | ||
return globby.sync(normalizedPatterns, { cwd: baseDir, absolute: true }); | ||
} | ||
exports.collectTestFiles = collectTestFiles; | ||
//# sourceMappingURL=collectTestFiles.js.map |
@@ -1,9 +0,10 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createDebugSessions = void 0; | ||
const nanoid_1 = require("nanoid"); | ||
function createDebugSessions(sessions) { | ||
import { nanoid } from 'nanoid'; | ||
export function createDebugSessions(sessions) { | ||
const debugSessions = []; | ||
for (const session of sessions) { | ||
const debugSession = Object.assign(Object.assign({}, session), { id: nanoid_1.nanoid(), debug: true }); | ||
const debugSession = { | ||
...session, | ||
id: nanoid(), | ||
debug: true, | ||
}; | ||
debugSessions.push(debugSession); | ||
@@ -13,3 +14,2 @@ } | ||
} | ||
exports.createDebugSessions = createDebugSessions; | ||
//# sourceMappingURL=createDebugSessions.js.map |
@@ -1,6 +0,6 @@ | ||
import { TestSession } from '../test-session/TestSession'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestSessionGroup } from '../test-session/TestSessionGroup'; | ||
import { TestSession } from '../test-session/TestSession.js'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
import { TestSessionGroup } from '../test-session/TestSessionGroup.js'; | ||
export declare function createTestSessions(config: TestRunnerCoreConfig, groupConfigs: TestRunnerGroupConfig[]): { | ||
@@ -7,0 +7,0 @@ sessionGroups: TestSessionGroup[]; |
@@ -1,13 +0,6 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createTestSessions = void 0; | ||
const nanoid_1 = require("nanoid"); | ||
const path_1 = __importDefault(require("path")); | ||
const TestSessionStatus_1 = require("../test-session/TestSessionStatus"); | ||
const collectTestFiles_1 = require("./collectTestFiles"); | ||
function createTestSessions(config, groupConfigs) { | ||
var _a; | ||
import { nanoid } from 'nanoid'; | ||
import path from 'path'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { collectTestFiles } from './collectTestFiles.js'; | ||
export function createTestSessions(config, groupConfigs) { | ||
const groups = []; | ||
@@ -28,3 +21,3 @@ if (config.files) { | ||
browsers: config.browsers, | ||
files: (_a = config.files) !== null && _a !== void 0 ? _a : [], | ||
files: config.files ?? [], | ||
}; | ||
@@ -50,7 +43,7 @@ if (typeof mergedGroupConfig.name !== 'string') { | ||
for (const group of groups) { | ||
const baseDir = group.configFilePath ? path_1.default.dirname(group.configFilePath) : process.cwd(); | ||
const testFilesForGroup = collectTestFiles_1.collectTestFiles(group.files, baseDir) | ||
const baseDir = group.configFilePath ? path.dirname(group.configFilePath) : process.cwd(); | ||
const testFilesForGroup = collectTestFiles(group.files, baseDir) | ||
// Normalize file path because glob returns windows paths with forward slashes: | ||
// C:/foo/bar -> C:\foo\bar | ||
.map(testFile => path_1.default.normalize(testFile)); | ||
.map(testFile => path.normalize(testFile)); | ||
if (testFilesForGroup.length === 0) { | ||
@@ -75,3 +68,3 @@ throw new Error(`Could not find any test files with pattern(s): ${group.files}`); | ||
const session = { | ||
id: nanoid_1.nanoid(), | ||
id: nanoid(), | ||
group: sessionGroup, | ||
@@ -81,3 +74,3 @@ debug: false, | ||
browser, | ||
status: TestSessionStatus_1.SESSION_STATUS.SCHEDULED, | ||
status: SESSION_STATUS.SCHEDULED, | ||
testFile, | ||
@@ -103,3 +96,2 @@ errors: [], | ||
} | ||
exports.createTestSessions = createTestSessions; | ||
//# sourceMappingURL=createSessionGroups.js.map |
@@ -1,5 +0,5 @@ | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { BasicTestSession } from '../test-session/BasicTestSession'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { BasicTestSession } from '../test-session/BasicTestSession.js'; | ||
export declare function toBrowserPath(filePath: string): string; | ||
export declare function createSessionUrl(config: TestRunnerCoreConfig, session: BasicTestSession): string; | ||
//# sourceMappingURL=createSessionUrl.d.ts.map |
@@ -1,19 +0,12 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createSessionUrl = exports.toBrowserPath = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
const constants_1 = require("../utils/constants"); | ||
const toBrowserPathRegExp = new RegExp(path_1.default.sep === '\\' ? '\\\\' : path_1.default.sep, 'g'); | ||
function toBrowserPath(filePath) { | ||
import path from 'path'; | ||
import { PARAM_SESSION_ID } from '../utils/constants.js'; | ||
const toBrowserPathRegExp = new RegExp(path.sep === '\\' ? '\\\\' : path.sep, 'g'); | ||
export function toBrowserPath(filePath) { | ||
return filePath.replace(toBrowserPathRegExp, '/'); | ||
} | ||
exports.toBrowserPath = toBrowserPath; | ||
function createSessionUrl(config, session) { | ||
export function createSessionUrl(config, session) { | ||
let browserPath; | ||
if (session.testFile.endsWith('.html')) { | ||
const resolvedPath = path_1.default.resolve(session.testFile); | ||
const relativePath = path_1.default.relative(config.rootDir, resolvedPath); | ||
const resolvedPath = path.resolve(session.testFile); | ||
const relativePath = path.relative(config.rootDir, resolvedPath); | ||
browserPath = `/${toBrowserPath(relativePath)}`; | ||
@@ -24,6 +17,5 @@ } | ||
} | ||
const params = `?${constants_1.PARAM_SESSION_ID}=${session.id}`; | ||
const params = `?${PARAM_SESSION_ID}=${session.id}`; | ||
return `${config.protocol}//${config.hostname}:${config.port}${browserPath}${params}`; | ||
} | ||
exports.createSessionUrl = createSessionUrl; | ||
//# sourceMappingURL=createSessionUrl.js.map |
@@ -1,8 +0,8 @@ | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestSession } from '../test-session/TestSession'; | ||
import { TestCoverage } from '../coverage/getTestCoverage'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager'; | ||
import { EventEmitter } from '../utils/EventEmitter'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestSession } from '../test-session/TestSession.js'; | ||
import { TestCoverage } from '../coverage/getTestCoverage.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { EventEmitter } from '../utils/EventEmitter.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig.js'; | ||
interface EventMap { | ||
@@ -9,0 +9,0 @@ 'test-run-started': { |
@@ -1,23 +0,28 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestRunner = void 0; | ||
const createSessionGroups_1 = require("./createSessionGroups"); | ||
const getTestCoverage_1 = require("../coverage/getTestCoverage"); | ||
const TestScheduler_1 = require("./TestScheduler"); | ||
const TestSessionManager_1 = require("../test-session/TestSessionManager"); | ||
const TestSessionStatus_1 = require("../test-session/TestSessionStatus"); | ||
const EventEmitter_1 = require("../utils/EventEmitter"); | ||
const createSessionUrl_1 = require("./createSessionUrl"); | ||
const createDebugSessions_1 = require("./createDebugSessions"); | ||
const TestRunnerServer_1 = require("../server/TestRunnerServer"); | ||
class TestRunner extends EventEmitter_1.EventEmitter { | ||
import { createTestSessions } from './createSessionGroups.js'; | ||
import { getTestCoverage } from '../coverage/getTestCoverage.js'; | ||
import { TestScheduler } from './TestScheduler.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { EventEmitter } from '../utils/EventEmitter.js'; | ||
import { createSessionUrl } from './createSessionUrl.js'; | ||
import { createDebugSessions } from './createDebugSessions.js'; | ||
import { TestRunnerServer } from '../server/TestRunnerServer.js'; | ||
export class TestRunner extends EventEmitter { | ||
config; | ||
sessions; | ||
testFiles; | ||
browsers; | ||
browserNames; | ||
startTime = -1; | ||
testRun = -1; | ||
started = false; | ||
stopped = false; | ||
running = false; | ||
passed = false; | ||
focusedTestFile; | ||
scheduler; | ||
server; | ||
pendingSessions = new Set(); | ||
constructor(config, groupConfigs = []) { | ||
super(); | ||
this.startTime = -1; | ||
this.testRun = -1; | ||
this.started = false; | ||
this.stopped = false; | ||
this.running = false; | ||
this.passed = false; | ||
this.pendingSessions = new Set(); | ||
if (!config.manual && (!config.browsers || config.browsers.length === 0)) { | ||
@@ -32,3 +37,3 @@ throw new Error('No browsers are configured to run tests'); | ||
} | ||
const { sessionGroups, testFiles, testSessions, browsers } = createSessionGroups_1.createTestSessions(config, groupConfigs); | ||
const { sessionGroups, testFiles, testSessions, browsers } = createTestSessions(config, groupConfigs); | ||
this.config = config; | ||
@@ -39,9 +44,9 @@ this.testFiles = testFiles; | ||
this.browserNames.sort((a, b) => this.browsers.findIndex(br => br.name === a) - this.browsers.findIndex(br => br.name === b)); | ||
this.sessions = new TestSessionManager_1.TestSessionManager(sessionGroups, testSessions); | ||
this.scheduler = new TestScheduler_1.TestScheduler(config, this.sessions, browsers); | ||
this.server = new TestRunnerServer_1.TestRunnerServer(this.config, this, this.sessions, this.testFiles, sessions => { | ||
this.sessions = new TestSessionManager(sessionGroups, testSessions); | ||
this.scheduler = new TestScheduler(config, this.sessions, browsers); | ||
this.server = new TestRunnerServer(this.config, this, this.sessions, this.testFiles, sessions => { | ||
this.runTests(sessions); | ||
}); | ||
this.sessions.on('session-status-updated', session => { | ||
if (session.status === TestSessionStatus_1.SESSION_STATUS.FINISHED) { | ||
if (session.status === SESSION_STATUS.FINISHED) { | ||
this.onSessionFinished(); | ||
@@ -135,7 +140,7 @@ } | ||
const sessions = this.sessions.forTestFile(testFile); | ||
const debugSessions = createDebugSessions_1.createDebugSessions(Array.from(sessions)); | ||
const debugSessions = createDebugSessions(Array.from(sessions)); | ||
this.sessions.addDebug(...debugSessions); | ||
for (const session of debugSessions) { | ||
session.browser | ||
.startDebugSession(session.id, createSessionUrl_1.createSessionUrl(this.config, session)) | ||
.startDebugSession(session.id, createSessionUrl(this.config, session)) | ||
.catch(error => { | ||
@@ -148,3 +153,3 @@ console.error(error); | ||
try { | ||
const finishedAll = Array.from(this.sessions.all()).every(s => s.status === TestSessionStatus_1.SESSION_STATUS.FINISHED); | ||
const finishedAll = Array.from(this.sessions.all()).every(s => s.status === SESSION_STATUS.FINISHED); | ||
if (finishedAll) { | ||
@@ -154,3 +159,3 @@ let passedCoverage = true; | ||
if (this.config.coverage) { | ||
testCoverage = getTestCoverage_1.getTestCoverage(this.sessions.all(), this.config.coverageConfig); | ||
testCoverage = getTestCoverage(this.sessions.all(), this.config.coverageConfig); | ||
passedCoverage = testCoverage.passed; | ||
@@ -180,3 +185,2 @@ } | ||
} | ||
exports.TestRunner = TestRunner; | ||
//# sourceMappingURL=TestRunner.js.map |
@@ -1,5 +0,5 @@ | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager'; | ||
import { TestSession, TestResultError } from '../test-session/TestSession'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { TestSession, TestResultError } from '../test-session/TestSession.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
export declare class TestScheduler { | ||
@@ -6,0 +6,0 @@ private config; |
@@ -1,16 +0,18 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestScheduler = void 0; | ||
const createSessionUrl_1 = require("./createSessionUrl"); | ||
const TestSessionStatus_1 = require("../test-session/TestSessionStatus"); | ||
const async_1 = require("../utils/async"); | ||
const TestSessionTimeoutHandler_1 = require("./TestSessionTimeoutHandler"); | ||
class TestScheduler { | ||
import { createSessionUrl } from './createSessionUrl.js'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { withTimeout } from '../utils/async.js'; | ||
import { TestSessionTimeoutHandler } from './TestSessionTimeoutHandler.js'; | ||
export class TestScheduler { | ||
config; | ||
sessions; | ||
timeoutHandler; | ||
browsers; | ||
finishedBrowsers = new Set(); | ||
stopPromises = new Set(); | ||
browserStartTimeoutMsg; | ||
constructor(config, sessions, browsers) { | ||
this.finishedBrowsers = new Set(); | ||
this.stopPromises = new Set(); | ||
this.config = config; | ||
this.sessions = sessions; | ||
this.browsers = [...browsers].sort((a, b) => (a.__experimentalWindowFocus__ ? 1 : 0) - (b.__experimentalWindowFocus__ ? 1 : 0)); | ||
this.timeoutHandler = new TestSessionTimeoutHandler_1.TestSessionTimeoutHandler(this.config, this.sessions, this); | ||
this.timeoutHandler = new TestSessionTimeoutHandler(this.config, this.sessions, this); | ||
this.browserStartTimeoutMsg = | ||
@@ -20,7 +22,7 @@ `The browser was unable to create and start a test page after ${this.config.browserStartTimeout}ms. ` + | ||
sessions.on('session-status-updated', async (session) => { | ||
if (session.status === TestSessionStatus_1.SESSION_STATUS.TEST_STARTED) { | ||
if (session.status === SESSION_STATUS.TEST_STARTED) { | ||
this.timeoutHandler.waitForTestsFinished(session.testRun, session.id); | ||
return; | ||
} | ||
if (session.status === TestSessionStatus_1.SESSION_STATUS.TEST_FINISHED) { | ||
if (session.status === SESSION_STATUS.TEST_FINISHED) { | ||
// the session finished executing tests, close the browser page | ||
@@ -30,3 +32,3 @@ await this.stopSession(session); | ||
} | ||
if (session.status === TestSessionStatus_1.SESSION_STATUS.FINISHED) { | ||
if (session.status === SESSION_STATUS.FINISHED) { | ||
this.timeoutHandler.clearTimeoutsForSession(session); | ||
@@ -47,3 +49,3 @@ setTimeout(() => { | ||
for (const session of sessionsToSchedule) { | ||
this.sessions.updateStatus(Object.assign(Object.assign({}, session), { testRun, request404s: [] }), TestSessionStatus_1.SESSION_STATUS.SCHEDULED); | ||
this.sessions.updateStatus({ ...session, testRun, request404s: [] }, SESSION_STATUS.SCHEDULED); | ||
} | ||
@@ -58,3 +60,2 @@ this.runNextScheduled(); | ||
runNextScheduled() { | ||
var _a; | ||
let runningBrowsers = 0; | ||
@@ -79,3 +80,3 @@ for (const browser of this.browsers) { | ||
else { | ||
maxBudget = (_a = browser.concurrency) !== null && _a !== void 0 ? _a : this.config.concurrency; | ||
maxBudget = browser.concurrency ?? this.config.concurrency; | ||
} | ||
@@ -95,4 +96,4 @@ const runBudget = Math.max(0, maxBudget - runningCount); | ||
async startSession(session) { | ||
const updatedSession = Object.assign(Object.assign({}, session), { status: TestSessionStatus_1.SESSION_STATUS.INITIALIZING }); | ||
this.sessions.updateStatus(updatedSession, TestSessionStatus_1.SESSION_STATUS.INITIALIZING); | ||
const updatedSession = { ...session, status: SESSION_STATUS.INITIALIZING }; | ||
this.sessions.updateStatus(updatedSession, SESSION_STATUS.INITIALIZING); | ||
let browserStarted = false; | ||
@@ -109,7 +110,8 @@ // browser should be started within the specified milliseconds | ||
try { | ||
await async_1.withTimeout(updatedSession.browser.startSession(updatedSession.id, createSessionUrl_1.createSessionUrl(this.config, updatedSession)), this.browserStartTimeoutMsg, this.config.browserStartTimeout); | ||
await withTimeout(updatedSession.browser.startSession(updatedSession.id, createSessionUrl(this.config, updatedSession)), this.browserStartTimeoutMsg, this.config.browserStartTimeout); | ||
// when the browser started, wait for session to ping back on time | ||
this.timeoutHandler.waitForTestsStarted(updatedSession.testRun, updatedSession.id); | ||
} | ||
catch (error) { | ||
catch (e) { | ||
const error = e; | ||
if (this.timeoutHandler.isStale(updatedSession)) { | ||
@@ -134,3 +136,2 @@ // something else has changed the test session, such as a the browser timeout | ||
async stopSession(session, errors = []) { | ||
var _a, _b; | ||
if (this.timeoutHandler.isStale(session)) { | ||
@@ -140,7 +141,7 @@ return; | ||
const sessionErrors = [...errors]; | ||
const updatedSession = Object.assign({}, session); | ||
const updatedSession = { ...session }; | ||
try { | ||
if (session.browser.isActive(session.id)) { | ||
const { testCoverage, errors } = await async_1.withTimeout(session.browser.stopSession(session.id), 'Timed out stopping the browser page', this.config.testsFinishTimeout); | ||
updatedSession.errors = [...((_a = updatedSession.errors) !== null && _a !== void 0 ? _a : []), ...(errors !== null && errors !== void 0 ? errors : [])]; | ||
const { testCoverage, errors } = await withTimeout(session.browser.stopSession(session.id), 'Timed out stopping the browser page', this.config.testsFinishTimeout); | ||
updatedSession.errors = [...(updatedSession.errors ?? []), ...(errors ?? [])]; | ||
updatedSession.testCoverage = testCoverage; | ||
@@ -155,6 +156,6 @@ } | ||
// merge with existing erors | ||
updatedSession.errors = [...((_b = updatedSession.errors) !== null && _b !== void 0 ? _b : []), ...sessionErrors]; | ||
updatedSession.errors = [...(updatedSession.errors ?? []), ...sessionErrors]; | ||
updatedSession.passed = false; | ||
} | ||
this.sessions.updateStatus(updatedSession, TestSessionStatus_1.SESSION_STATUS.FINISHED); | ||
this.sessions.updateStatus(updatedSession, SESSION_STATUS.FINISHED); | ||
const remaining = this.getUnfinishedSessions(session.browser); | ||
@@ -180,3 +181,3 @@ if (!this.config.watch && | ||
getScheduledSessions(browser) { | ||
return Array.from(this.sessions.filtered(s => s.browser === browser && s.status === TestSessionStatus_1.SESSION_STATUS.SCHEDULED)); | ||
return Array.from(this.sessions.filtered(s => s.browser === browser && s.status === SESSION_STATUS.SCHEDULED)); | ||
} | ||
@@ -186,12 +187,11 @@ getRunningSessions(browser) { | ||
[ | ||
TestSessionStatus_1.SESSION_STATUS.INITIALIZING, | ||
TestSessionStatus_1.SESSION_STATUS.TEST_STARTED, | ||
TestSessionStatus_1.SESSION_STATUS.TEST_FINISHED, | ||
SESSION_STATUS.INITIALIZING, | ||
SESSION_STATUS.TEST_STARTED, | ||
SESSION_STATUS.TEST_FINISHED, | ||
].includes(s.status))); | ||
} | ||
getUnfinishedSessions(browser) { | ||
return Array.from(this.sessions.filtered(s => s.browser === browser && s.status !== TestSessionStatus_1.SESSION_STATUS.FINISHED)); | ||
return Array.from(this.sessions.filtered(s => s.browser === browser && s.status !== SESSION_STATUS.FINISHED)); | ||
} | ||
} | ||
exports.TestScheduler = TestScheduler; | ||
//# sourceMappingURL=TestScheduler.js.map |
/// <reference types="node" /> | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager'; | ||
import { TestSession } from '../test-session/TestSession'; | ||
import { TestScheduler } from './TestScheduler'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { TestSession } from '../test-session/TestSession.js'; | ||
import { TestScheduler } from './TestScheduler.js'; | ||
export declare class TestSessionTimeoutHandler { | ||
@@ -7,0 +7,0 @@ private timeoutIdsPerSession; |
@@ -1,8 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestSessionTimeoutHandler = void 0; | ||
const TestSessionStatus_1 = require("../test-session/TestSessionStatus"); | ||
class TestSessionTimeoutHandler { | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
export class TestSessionTimeoutHandler { | ||
timeoutIdsPerSession = new Map(); | ||
config; | ||
sessions; | ||
scheduler; | ||
constructor(config, sessions, scheduler) { | ||
this.timeoutIdsPerSession = new Map(); | ||
this.config = config; | ||
@@ -19,3 +19,3 @@ this.sessions = sessions; | ||
} | ||
if (session.status === TestSessionStatus_1.SESSION_STATUS.INITIALIZING) { | ||
if (session.status === SESSION_STATUS.INITIALIZING) { | ||
this.setSessionFailed(session, { | ||
@@ -38,3 +38,3 @@ message: `Browser tests did not start after ${this.config.testsStartTimeout}ms ` + | ||
} | ||
if (session.status !== TestSessionStatus_1.SESSION_STATUS.TEST_FINISHED) { | ||
if (session.status !== SESSION_STATUS.TEST_FINISHED) { | ||
this.setSessionFailed(session, { | ||
@@ -89,3 +89,2 @@ message: `Browser tests did not finish within ${this.config.testsFinishTimeout}ms. ` + | ||
} | ||
exports.TestSessionTimeoutHandler = TestSessionTimeoutHandler; | ||
//# sourceMappingURL=TestSessionTimeoutHandler.js.map |
@@ -1,12 +0,6 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.cacheMiddleware = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
function cacheMiddleware(cachedPatterns, watch) { | ||
import path from 'path'; | ||
export function cacheMiddleware(cachedPatterns, watch) { | ||
return async (context, next) => { | ||
await next(); | ||
if (path_1.default.extname(context.path) && | ||
if (path.extname(context.path) && | ||
(!watch || cachedPatterns.some(pattern => context.path.includes(pattern)))) { | ||
@@ -17,3 +11,2 @@ context.response.set('cache-control', 'public, max-age=31536000'); | ||
} | ||
exports.cacheMiddleware = cacheMiddleware; | ||
//# sourceMappingURL=cacheMiddleware.js.map |
import { Middleware } from '@web/dev-server-core'; | ||
import { FSWatcher } from 'chokidar'; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager'; | ||
import { TestSession } from '../../test-session/TestSession'; | ||
export declare type RunSessions = (sessions: Iterable<TestSession>) => void; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager.js'; | ||
import { TestSession } from '../../test-session/TestSession.js'; | ||
export type RunSessions = (sessions: Iterable<TestSession>) => void; | ||
export interface DependencyGraphMiddlewareArgs { | ||
@@ -7,0 +7,0 @@ sessions: TestSessionManager; |
@@ -1,13 +0,7 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.watchFilesMiddleware = void 0; | ||
const dependency_graph_1 = require("dependency-graph"); | ||
const debounce_1 = __importDefault(require("debounce")); | ||
const path_1 = __importDefault(require("path")); | ||
const __1 = require("../.."); | ||
import { DepGraph } from 'dependency-graph'; | ||
import debounce from 'debounce'; | ||
import path from 'path'; | ||
import { constants } from '../../index.js'; | ||
const IGNORED_404s = ['favicon.ico']; | ||
const { PARAM_SESSION_ID } = __1.constants; | ||
const { PARAM_SESSION_ID } = constants; | ||
function onRerunSessions(runSessions, sessions, sessionIds) { | ||
@@ -37,11 +31,11 @@ const sessionsToRerun = sessionIds | ||
if (!request404s.includes(url) && !IGNORED_404s.some(i => url.endsWith(i))) { | ||
sessions.update(Object.assign(Object.assign({}, session), { request404s: [...request404s, url] })); | ||
sessions.update({ ...session, request404s: [...request404s, url] }); | ||
} | ||
} | ||
function toFilePath(browserPath) { | ||
return browserPath.replace(new RegExp('/', 'g'), path_1.default.sep); | ||
return browserPath.replace(new RegExp('/', 'g'), path.sep); | ||
} | ||
function watchFilesMiddleware({ rootDir, fileWatcher, sessions, runSessions, testFrameworkImport, }) { | ||
const fileGraph = new dependency_graph_1.DepGraph({ circular: true }); | ||
const urlGraph = new dependency_graph_1.DepGraph({ circular: true }); | ||
export function watchFilesMiddleware({ rootDir, fileWatcher, sessions, runSessions, testFrameworkImport, }) { | ||
const fileGraph = new DepGraph({ circular: true }); | ||
const urlGraph = new DepGraph({ circular: true }); | ||
let pendingChangedFiles = new Set(); | ||
@@ -98,3 +92,3 @@ function getSessionIdsForPath(path) { | ||
} | ||
const rerunSessions = debounce_1.default(syncRerunSessions, 300); | ||
const rerunSessions = debounce(syncRerunSessions, 300); | ||
function onFileChanged(filePath) { | ||
@@ -136,4 +130,4 @@ pendingChangedFiles.add(filePath); | ||
: // the dependant is a "regular" file, we resolve it to the file path | ||
path_1.default.join(rootDir, toFilePath(dependantUrl.pathname)); | ||
const dependencyFilePath = path_1.default.join(rootDir, toFilePath(dependencyPath)); | ||
path.join(rootDir, toFilePath(dependantUrl.pathname)); | ||
const dependencyFilePath = path.join(rootDir, toFilePath(dependencyPath)); | ||
const dependantPath = dependantUrl.searchParams.has(PARAM_SESSION_ID) | ||
@@ -159,3 +153,2 @@ ? dependantFilePath | ||
} | ||
exports.watchFilesMiddleware = watchFilesMiddleware; | ||
//# sourceMappingURL=watchFilesMiddleware.js.map |
import { StackLocation } from '@web/browser-logs'; | ||
export declare type SourceMapFunction = (loc: StackLocation, userAgent: string) => Promise<StackLocation | null>; | ||
export type SourceMapFunction = (loc: StackLocation, userAgent: string) => Promise<StackLocation | null>; | ||
/** | ||
@@ -4,0 +4,0 @@ * Creates a function that can map file path, line an column based on source maps. It maintains a cache of source maps, |
@@ -1,16 +0,10 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createSourceMapFunction = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
const source_map_1 = require("source-map"); | ||
const fetchSourceMap_1 = require("../../../utils/fetchSourceMap"); | ||
import path from 'path'; | ||
import { SourceMapConsumer } from 'source-map'; | ||
import { fetchSourceMap } from '../../../utils/fetchSourceMap.js'; | ||
function resolveRelativeTo(relativeTo, filePath) { | ||
if (path_1.default.isAbsolute(filePath)) { | ||
if (path.isAbsolute(filePath)) { | ||
return filePath; | ||
} | ||
const dir = path_1.default.dirname(relativeTo); | ||
return path_1.default.join(dir, filePath); | ||
const dir = path.dirname(relativeTo); | ||
return path.join(dir, filePath); | ||
} | ||
@@ -24,53 +18,22 @@ /** | ||
*/ | ||
function createSourceMapFunction(protocol, host, port) { | ||
export function createSourceMapFunction(protocol, host, port) { | ||
const cachedSourceMaps = new Map(); | ||
return async ({ browserUrl, filePath, line, column }, userAgent) => { | ||
var _a, _b; | ||
const cacheKey = `${filePath}${userAgent}`; | ||
if (!cachedSourceMaps.has(cacheKey)) { | ||
cachedSourceMaps.set(cacheKey, fetchSourceMap({ | ||
protocol, | ||
host, | ||
port, | ||
browserUrl, | ||
userAgent, | ||
}) | ||
.then(({ sourceMap }) => sourceMap) | ||
.catch(() => undefined)); | ||
} | ||
const sourceMap = await cachedSourceMaps.get(cacheKey); | ||
if (!sourceMap) { | ||
return null; | ||
} | ||
try { | ||
const cacheKey = `${filePath}${userAgent}`; | ||
let cached = cachedSourceMaps.get(cacheKey); | ||
if (cached) { | ||
if (cached.loadingPromise) { | ||
// a request for this source map is already being done in parallel, wait for it to finish | ||
await cached.loadingPromise; | ||
} | ||
if (!cached.sourceMap) { | ||
// we know there is no source map for this file | ||
return null; | ||
} | ||
} | ||
else { | ||
cached = {}; | ||
} | ||
cachedSourceMaps.set(cacheKey, cached); | ||
// get the raw source map, from cache or new | ||
let sourceMap; | ||
if (cached.sourceMap) { | ||
sourceMap = cached === null || cached === void 0 ? void 0 : cached.sourceMap; | ||
} | ||
else { | ||
// fetch source map, maintain a loading boolean for parallel calls to wait before resolving | ||
let resolveLoading; | ||
const loadingPromise = new Promise(resolve => { | ||
resolveLoading = resolve; | ||
}); | ||
cached.loadingPromise = loadingPromise; | ||
try { | ||
const result = await fetchSourceMap_1.fetchSourceMap({ | ||
protocol, | ||
host, | ||
port, | ||
browserUrl, | ||
userAgent, | ||
}); | ||
sourceMap = result.sourceMap; | ||
cached.sourceMap = sourceMap; | ||
} | ||
finally { | ||
resolveLoading(); | ||
} | ||
} | ||
if (!sourceMap) { | ||
return null; | ||
} | ||
// if there is no line and column we're looking for just the associated file, for example | ||
@@ -92,22 +55,16 @@ // the test file itself has source maps. if this is a single file source map, we can return | ||
// do the actual source mapping | ||
let consumer; | ||
if (cached === null || cached === void 0 ? void 0 : cached.consumer) { | ||
consumer = cached.consumer; | ||
} | ||
else { | ||
consumer = await new source_map_1.SourceMapConsumer(sourceMap.sourcemap); | ||
cachedSourceMaps.get(cacheKey).consumer = consumer; | ||
} | ||
const consumer = await new SourceMapConsumer(sourceMap.sourcemap); | ||
let originalPosition = consumer.originalPositionFor({ | ||
line: line !== null && line !== void 0 ? line : 0, | ||
column: column !== null && column !== void 0 ? column : 0, | ||
bias: source_map_1.SourceMapConsumer.GREATEST_LOWER_BOUND, | ||
line: line ?? 0, | ||
column: column ?? 0, | ||
bias: SourceMapConsumer.GREATEST_LOWER_BOUND, | ||
}); | ||
if (originalPosition.line == null) { | ||
originalPosition = consumer.originalPositionFor({ | ||
line: line !== null && line !== void 0 ? line : 0, | ||
column: column !== null && column !== void 0 ? column : 0, | ||
bias: source_map_1.SourceMapConsumer.LEAST_UPPER_BOUND, | ||
line: line ?? 0, | ||
column: column ?? 0, | ||
bias: SourceMapConsumer.LEAST_UPPER_BOUND, | ||
}); | ||
} | ||
consumer.destroy(); | ||
if (originalPosition.line == null) { | ||
@@ -119,8 +76,8 @@ return null; | ||
} | ||
const newFilePath = originalPosition.source.split('/').join(path_1.default.sep); | ||
const newFilePath = originalPosition.source.split('/').join(path.sep); | ||
return { | ||
filePath: resolveRelativeTo(filePath, newFilePath), | ||
browserUrl, | ||
line: (_a = originalPosition.line) !== null && _a !== void 0 ? _a : 0, | ||
column: (_b = originalPosition.column) !== null && _b !== void 0 ? _b : 0, | ||
line: originalPosition.line ?? 0, | ||
column: originalPosition.column ?? 0, | ||
}; | ||
@@ -135,3 +92,2 @@ } | ||
} | ||
exports.createSourceMapFunction = createSourceMapFunction; | ||
//# sourceMappingURL=createSourceMapFunction.js.map |
import { MapStackLocation } from '@web/browser-logs'; | ||
import { MapBrowserUrl } from '@web/browser-logs/src/parseStackTrace'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestResultError, TestSession } from '../../../test-session/TestSession'; | ||
import { MapBrowserUrl } from '@web/browser-logs'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig.js'; | ||
import { TestResultError, TestSession } from '../../../test-session/TestSession.js'; | ||
export declare function replaceErrorStack(error: TestResultError, mapBrowserUrl: MapBrowserUrl, mapStackLocation: MapStackLocation, rootDir: string): Promise<void>; | ||
@@ -6,0 +6,0 @@ export declare function parseSessionErrors(config: TestRunnerCoreConfig, mapBrowserUrl: MapBrowserUrl, mapStackLocation: MapStackLocation, result: Partial<TestSession>): Promise<void>; |
@@ -1,9 +0,6 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseTestResults = exports.parseSessionErrors = exports.replaceErrorStack = void 0; | ||
const browser_logs_1 = require("@web/browser-logs"); | ||
const async_1 = require("../../../utils/async"); | ||
async function replaceErrorStack(error, mapBrowserUrl, mapStackLocation, rootDir) { | ||
import { parseStackTrace } from '@web/browser-logs'; | ||
import { forEachAsync } from '../../../utils/async.js'; | ||
export async function replaceErrorStack(error, mapBrowserUrl, mapStackLocation, rootDir) { | ||
try { | ||
error.stack = await browser_logs_1.parseStackTrace(error.message, error.stack, { | ||
error.stack = await parseStackTrace(error.message, error.stack, { | ||
mapBrowserUrl, | ||
@@ -19,8 +16,7 @@ mapStackLocation, | ||
} | ||
exports.replaceErrorStack = replaceErrorStack; | ||
async function parseSessionErrors(config, mapBrowserUrl, mapStackLocation, result) { | ||
export async function parseSessionErrors(config, mapBrowserUrl, mapStackLocation, result) { | ||
if (!result.errors) { | ||
return; | ||
} | ||
await async_1.forEachAsync(result.errors, err => { | ||
await forEachAsync(result.errors, err => { | ||
if (err.stack) { | ||
@@ -31,4 +27,3 @@ return replaceErrorStack(err, mapBrowserUrl, mapStackLocation, config.rootDir); | ||
} | ||
exports.parseSessionErrors = parseSessionErrors; | ||
async function parseTestResults(config, mapBrowserUrl, mapStackLocation, result) { | ||
export async function parseTestResults(config, mapBrowserUrl, mapStackLocation, result) { | ||
if (!result.testResults) { | ||
@@ -38,5 +33,4 @@ return; | ||
async function iterateTests(tests) { | ||
await async_1.forEachAsync(tests, async (test) => { | ||
var _a; | ||
if ((_a = test.error) === null || _a === void 0 ? void 0 : _a.stack) { | ||
await forEachAsync(tests, async (test) => { | ||
if (test.error?.stack) { | ||
await replaceErrorStack(test.error, mapBrowserUrl, mapStackLocation, config.rootDir); | ||
@@ -50,7 +44,6 @@ } | ||
async function iterateSuites(suites) { | ||
await async_1.forEachAsync(suites, s => iterateSuite(s)); | ||
await forEachAsync(suites, s => iterateSuite(s)); | ||
} | ||
await iterateSuite(result.testResults); | ||
} | ||
exports.parseTestResults = parseTestResults; | ||
//# sourceMappingURL=parseBrowserErrors.js.map |
import { MapStackLocation } from '@web/browser-logs'; | ||
import { MapBrowserUrl } from '@web/browser-logs/src/parseStackTrace'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestSession } from '../../../test-session/TestSession'; | ||
import { MapBrowserUrl } from '@web/browser-logs'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig.js'; | ||
import { TestSession } from '../../../test-session/TestSession.js'; | ||
export declare function parseBrowserLogs(config: TestRunnerCoreConfig, mapBrowserUrl: MapBrowserUrl, mapStackLocation: MapStackLocation, result: Partial<TestSession>): Promise<void>; | ||
//# sourceMappingURL=parseBrowserLogs.d.ts.map |
@@ -1,12 +0,9 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseBrowserLogs = void 0; | ||
const browser_logs_1 = require("@web/browser-logs"); | ||
const async_1 = require("../../../utils/async"); | ||
import { deserialize } from '@web/browser-logs'; | ||
import { mapAsync } from '../../../utils/async.js'; | ||
async function parseBrowserLog(browserLog, mapBrowserUrl, mapStackLocation, config) { | ||
const browserRootDir = config.rootDir; | ||
const args = await async_1.mapAsync(browserLog.args, arg => browser_logs_1.deserialize(arg, { browserRootDir, mapBrowserUrl, mapStackLocation })); | ||
const args = await mapAsync(browserLog.args, arg => deserialize(arg, { browserRootDir, mapBrowserUrl, mapStackLocation })); | ||
return { type: browserLog.type, args }; | ||
} | ||
async function parseBrowserLogs(config, mapBrowserUrl, mapStackLocation, result) { | ||
export async function parseBrowserLogs(config, mapBrowserUrl, mapStackLocation, result) { | ||
if (!result.logs) { | ||
@@ -16,6 +13,6 @@ return; | ||
const browserLogs = result.logs; | ||
const logsWithType = await async_1.mapAsync(browserLogs, b => parseBrowserLog(b, mapBrowserUrl, mapStackLocation, config)); | ||
const logsWithType = await mapAsync(browserLogs, b => parseBrowserLog(b, mapBrowserUrl, mapStackLocation, config)); | ||
const logs = []; | ||
for (const log of logsWithType) { | ||
if (!config.filterBrowserLogs || config.filterBrowserLogs(log)) { | ||
if (!config.filterBrowserLogs || config.filterBrowserLogs(log, result)) { | ||
logs.push(log.args); | ||
@@ -26,3 +23,2 @@ } | ||
} | ||
exports.parseBrowserLogs = parseBrowserLogs; | ||
//# sourceMappingURL=parseBrowserLogs.js.map |
@@ -1,6 +0,6 @@ | ||
import { MapBrowserUrl } from '@web/browser-logs/src/parseStackTrace'; | ||
import { MapBrowserUrl } from '@web/browser-logs'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestSession } from '../../../test-session/TestSession'; | ||
import { SourceMapFunction } from './createSourceMapFunction'; | ||
import { SourceMapFunction } from './createSourceMapFunction.js'; | ||
export declare function parseBrowserResult(config: TestRunnerCoreConfig, mapBrowserUrl: MapBrowserUrl, sourceMapFunction: SourceMapFunction, userAgent: string, result: Partial<TestSession>): Promise<Partial<TestSession>>; | ||
//# sourceMappingURL=parseBrowserResult.d.ts.map |
@@ -1,6 +0,3 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseBrowserResult = void 0; | ||
const parseBrowserErrors_1 = require("./parseBrowserErrors"); | ||
const parseBrowserLogs_1 = require("./parseBrowserLogs"); | ||
import { parseSessionErrors, parseTestResults } from './parseBrowserErrors.js'; | ||
import { parseBrowserLogs } from './parseBrowserLogs.js'; | ||
function createMapStackLocation(smFn, userAgent) { | ||
@@ -12,12 +9,12 @@ return async function mapStackLocation(originalLoc) { | ||
} | ||
async function parseBrowserResult(config, mapBrowserUrl, sourceMapFunction, userAgent, result) { | ||
export async function parseBrowserResult(config, mapBrowserUrl, sourceMapFunction, userAgent, result) { | ||
const mapStackLocation = createMapStackLocation(sourceMapFunction, userAgent); | ||
await Promise.all([ | ||
parseBrowserLogs_1.parseBrowserLogs(config, mapBrowserUrl, mapStackLocation, result).catch(error => { | ||
parseBrowserLogs(config, mapBrowserUrl, mapStackLocation, result).catch(error => { | ||
console.error(error); | ||
}), | ||
parseBrowserErrors_1.parseSessionErrors(config, mapBrowserUrl, mapStackLocation, result).catch(error => { | ||
parseSessionErrors(config, mapBrowserUrl, mapStackLocation, result).catch(error => { | ||
console.error(error); | ||
}), | ||
parseBrowserErrors_1.parseTestResults(config, mapBrowserUrl, mapStackLocation, result).catch(error => { | ||
parseTestResults(config, mapBrowserUrl, mapStackLocation, result).catch(error => { | ||
console.error(error); | ||
@@ -28,3 +25,2 @@ }), | ||
} | ||
exports.parseBrowserResult = parseBrowserResult; | ||
//# sourceMappingURL=parseBrowserResult.js.map |
import { Context, ServerStartParams } from '@web/dev-server-core'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../../../test-session/TestSessionManager'; | ||
import { TestRunnerPlugin } from '../../TestRunnerPlugin'; | ||
import { TestSession } from '../../../test-session/TestSession'; | ||
import { TestRunner } from '../../../runner/TestRunner'; | ||
import { DebugTestSession } from '../../../test-session/DebugTestSession'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../../../test-session/TestSessionManager.js'; | ||
import { TestRunnerPlugin } from '../../TestRunnerPlugin.js'; | ||
import { TestSession } from '../../../test-session/TestSession.js'; | ||
import { TestRunner } from '../../../runner/TestRunner.js'; | ||
import { DebugTestSession } from '../../../test-session/DebugTestSession.js'; | ||
interface SessionMessage extends Record<string, unknown> { | ||
@@ -9,0 +9,0 @@ sessionId: string; |
@@ -1,13 +0,7 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.testRunnerApiPlugin = void 0; | ||
const dev_server_core_1 = require("@web/dev-server-core"); | ||
const co_body_1 = __importDefault(require("co-body")); | ||
const constants_1 = require("../../../utils/constants"); | ||
const TestSessionStatus_1 = require("../../../test-session/TestSessionStatus"); | ||
const parseBrowserResult_1 = require("./parseBrowserResult"); | ||
const createSourceMapFunction_1 = require("./createSourceMapFunction"); | ||
import { getRequestFilePath } from '@web/dev-server-core'; | ||
import parse from 'co-body'; | ||
import { PARAM_SESSION_ID } from '../../../utils/constants.js'; | ||
import { SESSION_STATUS } from '../../../test-session/TestSessionStatus.js'; | ||
import { parseBrowserResult } from './parseBrowserResult.js'; | ||
import { createSourceMapFunction } from './createSourceMapFunction.js'; | ||
function createMapBrowserUrl(rootDir) { | ||
@@ -18,11 +12,17 @@ return function mapBrowserUrl(url) { | ||
} | ||
return dev_server_core_1.getRequestFilePath(url.href, rootDir); | ||
return getRequestFilePath(url.href, rootDir); | ||
}; | ||
} | ||
class TestRunnerApiPlugin { | ||
name = 'test-runner-api'; | ||
injectWebSocket = true; | ||
config; | ||
plugins; | ||
testRunner; | ||
sessions; | ||
sourceMapFunction; | ||
mapBrowserUrl; | ||
/** key: session id, value: browser url */ | ||
testSessionUrls = new Map(); | ||
constructor(config, testRunner, sessions, plugins) { | ||
this.name = 'test-runner-api'; | ||
this.injectWebSocket = true; | ||
/** key: session id, value: browser url */ | ||
this.testSessionUrls = new Map(); | ||
this.config = config; | ||
@@ -33,7 +33,7 @@ this.testRunner = testRunner; | ||
this.mapBrowserUrl = createMapBrowserUrl(config.rootDir); | ||
this.sourceMapFunction = createSourceMapFunction_1.createSourceMapFunction(this.config.protocol, this.config.hostname, this.config.port); | ||
this.sourceMapFunction = createSourceMapFunction(this.config.protocol, this.config.hostname, this.config.port); | ||
this.testRunner.on('test-run-started', ({ testRun }) => { | ||
if (testRun !== 0) { | ||
// create a new source map function to clear the cached source maps | ||
this.sourceMapFunction = createSourceMapFunction_1.createSourceMapFunction(this.config.protocol, this.config.hostname, this.config.port); | ||
this.sourceMapFunction = createSourceMapFunction(this.config.protocol, this.config.hostname, this.config.port); | ||
} | ||
@@ -57,3 +57,3 @@ }); | ||
if (context.response.is('html')) { | ||
const sessionId = context.URL.searchParams.get(constants_1.PARAM_SESSION_ID); | ||
const sessionId = context.URL.searchParams.get(PARAM_SESSION_ID); | ||
if (!sessionId) { | ||
@@ -100,3 +100,3 @@ return; | ||
if (context.path === '/__web-test-runner__/wtr-legacy-browser-api') { | ||
const data = await co_body_1.default.json(context); | ||
const data = await parse.json(context); | ||
const { session, message } = this.parseSessionMessage(data); | ||
@@ -121,3 +121,3 @@ if (data.type === 'wtr-session-started') { | ||
_onSessionStarted(session) { | ||
if (session.status !== TestSessionStatus_1.SESSION_STATUS.INITIALIZING) { | ||
if (session.status !== SESSION_STATUS.INITIALIZING) { | ||
this._onMultiInitialized(session); | ||
@@ -127,3 +127,3 @@ return; | ||
// mark the session as started | ||
this.sessions.updateStatus(session, TestSessionStatus_1.SESSION_STATUS.TEST_STARTED); | ||
this.sessions.updateStatus(session, SESSION_STATUS.TEST_STARTED); | ||
} | ||
@@ -139,7 +139,6 @@ async _onSessionFinished(rawData, session, message) { | ||
} | ||
const result = await parseBrowserResult_1.parseBrowserResult(this.config, this.mapBrowserUrl, this.sourceMapFunction, rawData.userAgent, message.result); | ||
this.sessions.updateStatus(Object.assign(Object.assign({}, session), result), TestSessionStatus_1.SESSION_STATUS.TEST_FINISHED); | ||
const result = await parseBrowserResult(this.config, this.mapBrowserUrl, this.sourceMapFunction, rawData.userAgent, message.result); | ||
this.sessions.updateStatus({ ...session, ...result }, SESSION_STATUS.TEST_FINISHED); | ||
} | ||
async _onCommand(webSocket, session, message) { | ||
var _a; | ||
const { id, command, payload } = message; | ||
@@ -152,3 +151,3 @@ if (typeof id !== 'number') | ||
try { | ||
const result = await ((_a = plugin.executeCommand) === null || _a === void 0 ? void 0 : _a.call(plugin, { command, payload, session })); | ||
const result = await plugin.executeCommand?.({ command, payload, session }); | ||
if (result != null) { | ||
@@ -178,7 +177,7 @@ webSocket.send(JSON.stringify({ | ||
const session = this.sessions.get(sessionId); | ||
if ((session === null || session === void 0 ? void 0 : session.testRun) !== testRun) { | ||
if (session?.testRun !== testRun) { | ||
// a new testrun was started | ||
return; | ||
} | ||
if ((session === null || session === void 0 ? void 0 : session.status) !== TestSessionStatus_1.SESSION_STATUS.TEST_STARTED) { | ||
if (session?.status !== SESSION_STATUS.TEST_STARTED) { | ||
// websocket closed after finishing the tests, this is expected | ||
@@ -191,7 +190,7 @@ return; | ||
const updatedSession = this.sessions.get(sessionId); | ||
if ((updatedSession === null || updatedSession === void 0 ? void 0 : updatedSession.status) !== TestSessionStatus_1.SESSION_STATUS.TEST_STARTED) { | ||
if (updatedSession?.status !== SESSION_STATUS.TEST_STARTED) { | ||
// something else handled the disconnect | ||
return; | ||
} | ||
if ((updatedSession === null || updatedSession === void 0 ? void 0 : updatedSession.testRun) !== testRun) { | ||
if (updatedSession?.testRun !== testRun) { | ||
// a new testrun was started | ||
@@ -215,10 +214,8 @@ return; | ||
_setSessionFailed(session, message) { | ||
var _a; | ||
this.sessions.updateStatus(Object.assign(Object.assign({}, session), { errors: [...((_a = session.errors) !== null && _a !== void 0 ? _a : []), { message }] }), TestSessionStatus_1.SESSION_STATUS.TEST_FINISHED); | ||
this.sessions.updateStatus({ ...session, errors: [...(session.errors ?? []), { message }] }, SESSION_STATUS.TEST_FINISHED); | ||
} | ||
} | ||
function testRunnerApiPlugin(config, testRunner, sessions, plugins) { | ||
export function testRunnerApiPlugin(config, testRunner, sessions, plugins) { | ||
return new TestRunnerApiPlugin(config, testRunner, sessions, plugins); | ||
} | ||
exports.testRunnerApiPlugin = testRunnerApiPlugin; | ||
//# sourceMappingURL=testRunnerApiPlugin.js.map |
@@ -1,17 +0,11 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.serveTestFrameworkPlugin = void 0; | ||
const fs_1 = __importDefault(require("fs")); | ||
const path_1 = __importDefault(require("path")); | ||
const util_1 = require("util"); | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import { promisify } from 'util'; | ||
const TEST_FRAMEWORK_IMPORT_ROOT = '/__web-test-runner__/test-framework/'; | ||
async function readFile(codePath) { | ||
if (!fs_1.default.existsSync(codePath)) { | ||
if (!fs.existsSync(codePath)) { | ||
throw new Error(`The test framework at ${codePath} could not be loaded. ` + | ||
'Are your dependencies installed correctly? Is there a server plugin or middleware that interferes?'); | ||
} | ||
return await util_1.promisify(fs_1.default.readFile)(codePath, 'utf-8'); | ||
return await promisify(fs.readFile)(codePath, 'utf-8'); | ||
} | ||
@@ -21,6 +15,6 @@ /** | ||
*/ | ||
function serveTestFrameworkPlugin(testFramework) { | ||
const testFrameworkFilePath = path_1.default.resolve(testFramework.path); | ||
const testFrameworkBrowserPath = testFrameworkFilePath.split(path_1.default.sep).join('/'); | ||
const testFrameworkImport = encodeURI(path_1.default.posix.join(TEST_FRAMEWORK_IMPORT_ROOT, testFrameworkBrowserPath)); | ||
export function serveTestFrameworkPlugin(testFramework) { | ||
const testFrameworkFilePath = path.resolve(testFramework.path); | ||
const testFrameworkBrowserPath = testFrameworkFilePath.split(path.sep).join('/'); | ||
const testFrameworkImport = encodeURI(path.posix.join(TEST_FRAMEWORK_IMPORT_ROOT, testFrameworkBrowserPath)); | ||
const testFrameworkPlugin = { | ||
@@ -31,5 +25,5 @@ name: 'wtr-serve-test-framework', | ||
const importPath = decodeURI(context.path.replace(TEST_FRAMEWORK_IMPORT_ROOT, '')); | ||
let filePath = importPath.split('/').join(path_1.default.sep); | ||
let filePath = importPath.split('/').join(path.sep); | ||
// for posix the leading / will be stripped by path.join above | ||
if (path_1.default.sep === '/') { | ||
if (path.sep === '/') { | ||
filePath = `/${filePath}`; | ||
@@ -44,3 +38,2 @@ } | ||
} | ||
exports.serveTestFrameworkPlugin = serveTestFrameworkPlugin; | ||
//# sourceMappingURL=serveTestFrameworkPlugin.js.map |
import { Context } from '@web/dev-server-core'; | ||
import { TestRunnerCoreConfig } from '../../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager'; | ||
import { TestRunnerCoreConfig } from '../../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager.js'; | ||
export declare function serveTestRunnerHtmlPlugin(config: TestRunnerCoreConfig, testFiles: string[], sessions: TestSessionManager, testFrameworkImport?: string): { | ||
@@ -5,0 +5,0 @@ name: string; |
@@ -1,8 +0,5 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.serveTestRunnerHtmlPlugin = void 0; | ||
const dev_server_core_1 = require("@web/dev-server-core"); | ||
const constants_1 = require("../../utils/constants"); | ||
const utils_1 = require("../utils"); | ||
const trackBrowserLogs_1 = require("./trackBrowserLogs"); | ||
import { getRequestFilePath } from '@web/dev-server-core'; | ||
import { PARAM_SESSION_ID, PARAM_TEST_FILE } from '../../utils/constants.js'; | ||
import { createTestFileImportPath } from '../utils.js'; | ||
import { trackBrowserLogs } from './trackBrowserLogs.js'; | ||
const iframeModePage = ` | ||
@@ -27,6 +24,6 @@ <!DOCTYPE html> | ||
async function getManualListItem(config, context, testFile) { | ||
const testImportPath = await utils_1.createTestFileImportPath(config, context, testFile); | ||
const testImportPath = await createTestFileImportPath(config, context, testFile); | ||
const displayedPath = testImportPath.split('?')[0].substring(1); | ||
const pagename = displayedPath.endsWith('.html') ? displayedPath : '/'; | ||
const href = `${pagename}?${constants_1.PARAM_TEST_FILE}=${encodeURIComponent(testImportPath)}`; | ||
const href = `${pagename}?${PARAM_TEST_FILE}=${encodeURIComponent(testImportPath)}`; | ||
return `<li><a href="${href}">${displayedPath}</a></li>`; | ||
@@ -77,3 +74,3 @@ } | ||
const configScript = `<script type="module">window.__WTR_CONFIG__ = ${JSON.stringify(config)}</script>`; | ||
const injectedHtml = `${preloadLink}${browserLogs ? `${trackBrowserLogs_1.trackBrowserLogs}` : ''}${configScript}`; | ||
const injectedHtml = `${preloadLink}${browserLogs ? `${trackBrowserLogs}` : ''}${configScript}`; | ||
const injectLocation = getInjectIndex(html); | ||
@@ -84,3 +81,3 @@ return `${html.substring(0, injectLocation)}${injectedHtml}${html.substring(injectLocation)}`; | ||
let body; | ||
if (groupConfig === null || groupConfig === void 0 ? void 0 : groupConfig.testRunnerHtml) { | ||
if (groupConfig?.testRunnerHtml) { | ||
// there is a group in scope, regular test or debug | ||
@@ -99,7 +96,6 @@ body = groupConfig.testRunnerHtml(testFrameworkImport, config, groupConfig); | ||
} | ||
function serveTestRunnerHtmlPlugin(config, testFiles, sessions, testFrameworkImport) { | ||
export function serveTestRunnerHtmlPlugin(config, testFiles, sessions, testFrameworkImport) { | ||
return { | ||
name: 'wtr-test-runner-html', | ||
async serve(context) { | ||
var _a; | ||
if (!testFrameworkImport) { | ||
@@ -110,8 +106,8 @@ throw new Error('Cannot test javascript files without a testFramework configured.'); | ||
const { searchParams } = context.URL; | ||
if (searchParams.has(constants_1.PARAM_TEST_FILE)) { | ||
if (searchParams.has(PARAM_TEST_FILE)) { | ||
return createTestRunnerHtml(testFrameworkImport, config); | ||
} | ||
const sessionId = searchParams.get(constants_1.PARAM_SESSION_ID); | ||
const sessionId = searchParams.get(PARAM_SESSION_ID); | ||
if (sessionId) { | ||
const session = (_a = sessions.get(sessionId)) !== null && _a !== void 0 ? _a : sessions.getDebug(sessionId); | ||
const session = sessions.get(sessionId) ?? sessions.getDebug(sessionId); | ||
if (!session) { | ||
@@ -135,3 +131,2 @@ throw new Error(`Could not find session ${sessionId}`); | ||
async transform(context) { | ||
var _a, _b, _c; | ||
if (!context.response.is('html')) { | ||
@@ -142,13 +137,13 @@ return; | ||
if (!isTestRunnerHtml && | ||
!testFiles.includes(dev_server_core_1.getRequestFilePath(context.url, config.rootDir))) { | ||
!testFiles.includes(getRequestFilePath(context.url, config.rootDir))) { | ||
return; | ||
} | ||
const { searchParams } = context.URL; | ||
const sessionId = searchParams.get(constants_1.PARAM_SESSION_ID); | ||
const sessionId = searchParams.get(PARAM_SESSION_ID); | ||
if (sessionId) { | ||
const session = (_a = sessions.get(sessionId)) !== null && _a !== void 0 ? _a : sessions.getDebug(sessionId); | ||
const session = sessions.get(sessionId) ?? sessions.getDebug(sessionId); | ||
if (!session) { | ||
throw new Error(`Could not find session ${sessionId}`); | ||
} | ||
const testFile = await utils_1.createTestFileImportPath(config, context, session.testFile, sessionId); | ||
const testFile = await createTestFileImportPath(config, context, session.testFile, sessionId); | ||
const runtimeConfig = { | ||
@@ -158,3 +153,3 @@ testFile, | ||
debug: session.debug, | ||
testFrameworkConfig: (_b = config.testFramework) === null || _b === void 0 ? void 0 : _b.config, | ||
testFrameworkConfig: config.testFramework?.config, | ||
}; | ||
@@ -164,3 +159,3 @@ context.body = injectRuntime(context.body, runtimeConfig, !!config.browserLogs, isTestRunnerHtml ? testFile : undefined); | ||
} | ||
const testFile = searchParams.get(constants_1.PARAM_TEST_FILE); | ||
const testFile = searchParams.get(PARAM_TEST_FILE); | ||
if (testFile) { | ||
@@ -171,3 +166,3 @@ const runtimeConfig = { | ||
debug: true, | ||
testFrameworkConfig: (_c = config.testFramework) === null || _c === void 0 ? void 0 : _c.config, | ||
testFrameworkConfig: config.testFramework?.config, | ||
}; | ||
@@ -180,3 +175,2 @@ context.body = injectRuntime(context.body, runtimeConfig, !!config.browserLogs, isTestRunnerHtml ? testFile : undefined); | ||
} | ||
exports.serveTestRunnerHtmlPlugin = serveTestRunnerHtmlPlugin; | ||
//# sourceMappingURL=serveTestRunnerHtmlPlugin.js.map |
@@ -1,7 +0,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.trackBrowserLogs = void 0; | ||
const browser_logs_1 = require("@web/browser-logs"); | ||
exports.trackBrowserLogs = `<script type="module">(function () { | ||
${browser_logs_1.browserScript} | ||
import { browserScript } from '@web/browser-logs'; | ||
export const trackBrowserLogs = `<script type="module">(function () { | ||
${browserScript} | ||
window.__wtr_browser_logs__.logs = []; | ||
@@ -8,0 +5,0 @@ |
import { Plugin } from '@web/dev-server-core'; | ||
import { BasicTestSession } from '../test-session/BasicTestSession'; | ||
export declare type ExecuteCommandResult = void | unknown | Promise<void> | Promise<unknown>; | ||
export type ExecuteCommandResult = void | unknown | Promise<void> | Promise<unknown>; | ||
export interface ExecuteCommandArgs<TPayload> { | ||
@@ -5,0 +5,0 @@ command: string; |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=TestRunnerPlugin.js.map |
@@ -1,2 +0,2 @@ | ||
import { RunSessions } from './middleware/watchFilesMiddleware'; | ||
import { RunSessions } from './middleware/watchFilesMiddleware.js'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
@@ -3,0 +3,0 @@ import { TestSessionManager } from '../test-session/TestSessionManager'; |
@@ -1,14 +0,8 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestRunnerServer = void 0; | ||
const dev_server_core_1 = require("@web/dev-server-core"); | ||
const chokidar_1 = __importDefault(require("chokidar")); | ||
const watchFilesMiddleware_1 = require("./middleware/watchFilesMiddleware"); | ||
const cacheMiddleware_1 = require("./middleware/cacheMiddleware"); | ||
const serveTestRunnerHtmlPlugin_1 = require("./plugins/serveTestRunnerHtmlPlugin"); | ||
const serveTestFrameworkPlugin_1 = require("./plugins/serveTestFrameworkPlugin"); | ||
const testRunnerApiPlugin_1 = require("./plugins/api/testRunnerApiPlugin"); | ||
import { DevServer } from '@web/dev-server-core'; | ||
import chokidar from 'chokidar'; | ||
import { watchFilesMiddleware } from './middleware/watchFilesMiddleware.js'; | ||
import { cacheMiddleware } from './middleware/cacheMiddleware.js'; | ||
import { serveTestRunnerHtmlPlugin } from './plugins/serveTestRunnerHtmlPlugin.js'; | ||
import { serveTestFrameworkPlugin } from './plugins/serveTestFrameworkPlugin.js'; | ||
import { testRunnerApiPlugin } from './plugins/api/testRunnerApiPlugin.js'; | ||
const CACHED_PATTERNS = [ | ||
@@ -21,8 +15,9 @@ 'node_modules/@web/test-runner-', | ||
const isDefined = (_) => Boolean(_); | ||
class TestRunnerServer { | ||
export class TestRunnerServer { | ||
devServer; | ||
fileWatcher = chokidar.watch([]); | ||
constructor(config, testRunner, sessions, testFiles, runSessions) { | ||
this.fileWatcher = chokidar_1.default.watch([]); | ||
const { plugins = [], testFramework, rootDir } = config; | ||
const { testFrameworkImport, testFrameworkPlugin } = testFramework | ||
? serveTestFrameworkPlugin_1.serveTestFrameworkPlugin(testFramework) | ||
? serveTestFrameworkPlugin(testFramework) | ||
: {}; | ||
@@ -40,9 +35,9 @@ const serverConfig = { | ||
middleware: [ | ||
watchFilesMiddleware_1.watchFilesMiddleware({ runSessions, sessions, rootDir, fileWatcher: this.fileWatcher }), | ||
cacheMiddleware_1.cacheMiddleware(CACHED_PATTERNS, config.watch), | ||
watchFilesMiddleware({ runSessions, sessions, rootDir, fileWatcher: this.fileWatcher }), | ||
cacheMiddleware(CACHED_PATTERNS, config.watch), | ||
...(config.middleware || []), | ||
], | ||
plugins: [ | ||
testRunnerApiPlugin_1.testRunnerApiPlugin(config, testRunner, sessions, plugins), | ||
serveTestRunnerHtmlPlugin_1.serveTestRunnerHtmlPlugin(config, testFiles, sessions, testFrameworkImport), | ||
testRunnerApiPlugin(config, testRunner, sessions, plugins), | ||
serveTestRunnerHtmlPlugin(config, testFiles, sessions, testFrameworkImport), | ||
testFrameworkPlugin, | ||
@@ -52,3 +47,3 @@ ...(config.plugins || []), | ||
}; | ||
this.devServer = new dev_server_core_1.DevServer(serverConfig, config.logger, this.fileWatcher); | ||
this.devServer = new DevServer(serverConfig, config.logger, this.fileWatcher); | ||
} | ||
@@ -62,3 +57,2 @@ async start() { | ||
} | ||
exports.TestRunnerServer = TestRunnerServer; | ||
//# sourceMappingURL=TestRunnerServer.js.map |
import { Context } from '@web/dev-server-core'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
export declare function toBrowserPath(filePath: string): string; | ||
@@ -4,0 +4,0 @@ export declare function toFilePath(browserPath: string): string; |
@@ -1,28 +0,19 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createTestFileImportPath = exports.toFilePath = exports.toBrowserPath = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
const constants_1 = require("../utils/constants"); | ||
const toBrowserPathRegExp = new RegExp(path_1.default.sep === '\\' ? '\\\\' : path_1.default.sep, 'g'); | ||
import path from 'path'; | ||
import { PARAM_SESSION_ID, PARAM_MANUAL_SESSION } from '../utils/constants.js'; | ||
const toBrowserPathRegExp = new RegExp(path.sep === '\\' ? '\\\\' : path.sep, 'g'); | ||
const toFilePathRegeExp = new RegExp('/', 'g'); | ||
function toBrowserPath(filePath) { | ||
export function toBrowserPath(filePath) { | ||
return filePath.replace(toBrowserPathRegExp, '/'); | ||
} | ||
exports.toBrowserPath = toBrowserPath; | ||
function toFilePath(browserPath) { | ||
return browserPath.replace(toFilePathRegeExp, path_1.default.sep); | ||
export function toFilePath(browserPath) { | ||
return browserPath.replace(toFilePathRegeExp, path.sep); | ||
} | ||
exports.toFilePath = toFilePath; | ||
async function createTestFileImportPath(config, context, filePath, sessionId) { | ||
var _a; | ||
const fullFilePath = path_1.default.resolve(filePath); | ||
const relativeToRootDir = path_1.default.relative(config.rootDir, fullFilePath); | ||
export async function createTestFileImportPath(config, context, filePath, sessionId) { | ||
const fullFilePath = path.resolve(filePath); | ||
const relativeToRootDir = path.relative(config.rootDir, fullFilePath); | ||
const browserPath = `/${toBrowserPath(relativeToRootDir)}`; | ||
const params = sessionId ? `?${constants_1.PARAM_SESSION_ID}=${sessionId}` : `?${constants_1.PARAM_MANUAL_SESSION}=true`; | ||
const params = sessionId ? `?${PARAM_SESSION_ID}=${sessionId}` : `?${PARAM_MANUAL_SESSION}=true`; | ||
let importPath = encodeURI(`${browserPath}${params}`); | ||
// allow plugins to transform the import path | ||
for (const p of (_a = config.plugins) !== null && _a !== void 0 ? _a : []) { | ||
for (const p of config.plugins ?? []) { | ||
if (p.transformImport) { | ||
@@ -40,3 +31,2 @@ const transformResult = await p.transformImport({ source: importPath, context }); | ||
} | ||
exports.createTestFileImportPath = createTestFileImportPath; | ||
//# sourceMappingURL=utils.js.map |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=TestFramework.js.map |
@@ -1,4 +0,4 @@ | ||
import { TestRunner, TestRunnerCoreConfig } from './index'; | ||
import { TestSession } from './test-session/TestSession'; | ||
import { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig'; | ||
import { TestRunner, TestRunnerCoreConfig } from './index.js'; | ||
import { TestSession } from './test-session/TestSession.js'; | ||
import { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig.js'; | ||
export declare function runTests(config: Partial<TestRunnerCoreConfig>, groupConfigs?: TestRunnerGroupConfig[], { allowFailure, reportErrors, }?: { | ||
@@ -5,0 +5,0 @@ allowFailure?: boolean; |
@@ -1,13 +0,13 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.runTests = void 0; | ||
/* eslint-disable no-async-promise-executor, no-inner-declarations */ | ||
const portfinder_1 = require("portfinder"); | ||
const path_1 = __importDefault(require("path")); | ||
const index_1 = require("./index"); | ||
const TestSessionStatus_1 = require("./test-session/TestSessionStatus"); | ||
const logger = Object.assign(Object.assign({}, console), { debug() { | ||
import { getPortPromise } from 'portfinder'; | ||
import path from 'path'; | ||
import * as url from 'url'; | ||
import { createRequire } from 'node:module'; | ||
import { TestRunner } from './index.js'; | ||
import { SESSION_STATUS } from './test-session/TestSessionStatus.js'; | ||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); | ||
const require = createRequire(import.meta.url); | ||
const logger = { | ||
...console, | ||
debug() { | ||
// | ||
@@ -17,3 +17,4 @@ }, | ||
console.error(error); | ||
} }); | ||
}, | ||
}; | ||
const secondMs = 1000; | ||
@@ -23,3 +24,3 @@ const minuteMs = secondMs * 60; | ||
watch: false, | ||
rootDir: path_1.default.join(__dirname, '..', '..', '..'), | ||
rootDir: path.join(__dirname, '..', '..', '..'), | ||
testFramework: { | ||
@@ -38,16 +39,22 @@ path: require.resolve('@web/test-runner-mocha/dist/autorun.js'), | ||
logger, | ||
//manual: true, | ||
//port: 9999 | ||
}; | ||
async function runTests(config, groupConfigs, { allowFailure = false, reportErrors = true, } = {}) { | ||
export async function runTests(config, groupConfigs, { allowFailure = false, reportErrors = true, } = {}) { | ||
return new Promise(async (resolve, reject) => { | ||
const port = await portfinder_1.getPortPromise({ port: 9000 + Math.floor(Math.random() * 1000) }); | ||
const finalConfig = Object.assign(Object.assign(Object.assign({ port }, defaultBaseConfig), config), { testFramework: Object.assign(Object.assign({}, defaultBaseConfig.testFramework), config.testFramework) }); | ||
const runner = new index_1.TestRunner(finalConfig, groupConfigs); | ||
// runner.sessions.on('session-status-updated', session => { | ||
// console.log(session.browser.name, session.id, session.status); | ||
// }); | ||
const port = await getPortPromise({ port: 9000 + Math.floor(Math.random() * 1000) }); | ||
const finalConfig = { | ||
port, | ||
...defaultBaseConfig, | ||
...config, | ||
testFramework: { | ||
...defaultBaseConfig.testFramework, | ||
...config.testFramework, | ||
}, | ||
}; | ||
const runner = new TestRunner(finalConfig, groupConfigs); | ||
let finished = false; | ||
runner.on('test-run-finished', ({ testRun, testCoverage }) => { | ||
var _a; | ||
for (const reporter of finalConfig.reporters) { | ||
(_a = reporter.onTestRunFinished) === null || _a === void 0 ? void 0 : _a.call(reporter, { | ||
reporter.onTestRunFinished?.({ | ||
testRun, | ||
@@ -61,8 +68,7 @@ sessions: Array.from(runner.sessions.all()), | ||
runner.on('finished', async () => { | ||
var _a; | ||
for (const reporter of finalConfig.reporters) { | ||
await ((_a = reporter.stop) === null || _a === void 0 ? void 0 : _a.call(reporter, { | ||
await reporter.stop?.({ | ||
sessions: Array.from(runner.sessions.all()), | ||
focusedTestFile: runner.focusedTestFile, | ||
})); | ||
}); | ||
} | ||
@@ -79,3 +85,2 @@ finished = true; | ||
runner.on('stopped', passed => { | ||
var _a; | ||
const sessions = Array.from(runner.sessions.all()); | ||
@@ -86,3 +91,3 @@ if (reportErrors) { | ||
console.log(''); | ||
console.log('Failed test file:', session.browser.name, path_1.default.relative(process.cwd(), session.testFile)); | ||
console.log('Failed test file:', session.browser.name, path.relative(process.cwd(), session.testFile)); | ||
} | ||
@@ -99,9 +104,8 @@ for (const log of session.logs) { | ||
for (const error of session.errors) { | ||
console.error((_a = error.stack) !== null && _a !== void 0 ? _a : error.message); | ||
console.error(error.stack ?? error.message); | ||
} | ||
function iterateTests(tests) { | ||
var _a, _b, _c; | ||
for (const test of tests) { | ||
if (!test.passed) { | ||
console.log(test.name, (_b = (_a = test.error) === null || _a === void 0 ? void 0 : _a.stack) !== null && _b !== void 0 ? _b : (_c = test.error) === null || _c === void 0 ? void 0 : _c.message); | ||
console.log(test.name, test.error?.stack ?? test.error?.message); | ||
} | ||
@@ -122,3 +126,3 @@ } | ||
} | ||
if (!sessions.every(s => s.status === TestSessionStatus_1.SESSION_STATUS.FINISHED)) { | ||
if (!sessions.every(s => s.status === SESSION_STATUS.FINISHED)) { | ||
reject(new Error('Tests did not finish')); | ||
@@ -137,3 +141,2 @@ return; | ||
} | ||
exports.runTests = runTests; | ||
//# sourceMappingURL=test-helpers.js.map |
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestSessionGroup } from './TestSessionGroup'; | ||
import { TestSessionGroup } from './TestSessionGroup.js'; | ||
export interface BasicTestSession { | ||
@@ -4,0 +4,0 @@ id: string; |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=BasicTestSession.js.map |
@@ -1,2 +0,2 @@ | ||
import { BasicTestSession } from './BasicTestSession'; | ||
import { BasicTestSession } from './BasicTestSession.js'; | ||
export interface DebugTestSession extends BasicTestSession { | ||
@@ -3,0 +3,0 @@ debug: true; |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=DebugTestSession.js.map |
import { CoverageMapData } from 'istanbul-lib-coverage'; | ||
import { TestSessionStatus } from './TestSessionStatus'; | ||
import { BasicTestSession } from './BasicTestSession'; | ||
import { TestSessionStatus } from './TestSessionStatus.js'; | ||
import { BasicTestSession } from './BasicTestSession.js'; | ||
export interface TestResultError { | ||
@@ -5,0 +5,0 @@ message: string; |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=TestSession.js.map |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; | ||
//# sourceMappingURL=TestSessionGroup.js.map |
@@ -1,7 +0,7 @@ | ||
import { TestSession } from './TestSession'; | ||
import { TestSessionStatus } from './TestSessionStatus'; | ||
import { EventEmitter } from '../utils/EventEmitter'; | ||
import { DebugTestSession } from './DebugTestSession'; | ||
import { TestSessionGroup } from './TestSessionGroup'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestSession } from './TestSession.js'; | ||
import { TestSessionStatus } from './TestSessionStatus.js'; | ||
import { EventEmitter } from '../utils/EventEmitter.js'; | ||
import { DebugTestSession } from './DebugTestSession.js'; | ||
import { TestSessionGroup } from './TestSessionGroup.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
interface EventMap { | ||
@@ -8,0 +8,0 @@ 'session-status-updated': TestSession; |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TestSessionManager = void 0; | ||
const EventEmitter_1 = require("../utils/EventEmitter"); | ||
import { EventEmitter } from '../utils/EventEmitter.js'; | ||
function* filtered(it, filter) { | ||
@@ -14,7 +11,8 @@ while (true) { | ||
} | ||
class TestSessionManager extends EventEmitter_1.EventEmitter { | ||
export class TestSessionManager extends EventEmitter { | ||
_groups; | ||
sessionsMap = new Map(); | ||
debugSessions = new Map(); | ||
constructor(groups, sessions) { | ||
super(); | ||
this.sessionsMap = new Map(); | ||
this.debugSessions = new Map(); | ||
this._groups = groups; | ||
@@ -31,3 +29,3 @@ for (const session of sessions) { | ||
updateStatus(session, status) { | ||
const updatedSession = Object.assign(Object.assign({}, session), { status }); | ||
const updatedSession = { ...session, status }; | ||
this.update(updatedSession); | ||
@@ -95,3 +93,2 @@ this.emit('session-status-updated', updatedSession); | ||
} | ||
exports.TestSessionManager = TestSessionManager; | ||
//# sourceMappingURL=TestSessionManager.js.map |
@@ -1,2 +0,2 @@ | ||
export declare type TestSessionStatus = 'SCHEDULED' | 'INITIALIZING' | 'STARTED' | 'FINISHED'; | ||
export type TestSessionStatus = 'SCHEDULED' | 'INITIALIZING' | 'STARTED' | 'FINISHED'; | ||
export declare const SESSION_STATUS: { | ||
@@ -3,0 +3,0 @@ SCHEDULED: TestSessionStatus; |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.SESSION_STATUS = void 0; | ||
exports.SESSION_STATUS = { | ||
export const SESSION_STATUS = { | ||
// waiting for a browser to free up and run this test session | ||
@@ -6,0 +3,0 @@ SCHEDULED: 'SCHEDULED', |
@@ -1,8 +0,5 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.mapAsync = exports.forEachAsync = exports.withTimeout = void 0; | ||
/** | ||
* Wraps a Promise with a timeout, rejecing the promise with the timeout. | ||
*/ | ||
function withTimeout(promise, message, timeout) { | ||
export function withTimeout(promise, message, timeout) { | ||
return new Promise((resolve, reject) => { | ||
@@ -28,3 +25,2 @@ if (!(promise instanceof Promise)) { | ||
} | ||
exports.withTimeout = withTimeout; | ||
/** | ||
@@ -34,3 +30,3 @@ * Iterates iterable, executes each function in parallel and awaits | ||
*/ | ||
async function forEachAsync(it, fn) { | ||
export async function forEachAsync(it, fn) { | ||
const result = []; | ||
@@ -42,3 +38,2 @@ for (const e of it) { | ||
} | ||
exports.forEachAsync = forEachAsync; | ||
/** | ||
@@ -48,3 +43,3 @@ * Iterates iterable, executes each function in parallel and awaits | ||
*/ | ||
function mapAsync(it, fn) { | ||
export function mapAsync(it, fn) { | ||
const result = []; | ||
@@ -56,3 +51,2 @@ for (const e of it) { | ||
} | ||
exports.mapAsync = mapAsync; | ||
//# sourceMappingURL=async.js.map |
@@ -1,7 +0,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PARAM_TEST_FILE = exports.PARAM_MANUAL_SESSION = exports.PARAM_SESSION_ID = void 0; | ||
exports.PARAM_SESSION_ID = 'wtr-session-id'; | ||
exports.PARAM_MANUAL_SESSION = 'wtr-manual-session'; | ||
exports.PARAM_TEST_FILE = 'wtr-test-file'; | ||
export const PARAM_SESSION_ID = 'wtr-session-id'; | ||
export const PARAM_MANUAL_SESSION = 'wtr-manual-session'; | ||
export const PARAM_TEST_FILE = 'wtr-test-file'; | ||
//# sourceMappingURL=constants.js.map |
@@ -1,4 +0,4 @@ | ||
declare type EventMap = Record<string, any>; | ||
declare type EventKey<T extends EventMap> = string & keyof T; | ||
declare type EventReceiver<T> = (params: T) => void; | ||
type EventMap = Record<string, any>; | ||
type EventKey<T extends EventMap> = string & keyof T; | ||
type EventReceiver<T> = (params: T) => void; | ||
interface Emitter<T extends EventMap> { | ||
@@ -5,0 +5,0 @@ on<K extends EventKey<T>>(eventName: K, fn: EventReceiver<T[K]>): void; |
@@ -1,9 +0,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.EventEmitter = void 0; | ||
const events_1 = require("events"); | ||
class EventEmitter { | ||
constructor() { | ||
this.__emitter = new events_1.EventEmitter(); | ||
} | ||
import { EventEmitter as NodeEventEmitter } from 'events'; | ||
export class EventEmitter { | ||
__emitter = new NodeEventEmitter(); | ||
on(eventName, fn) { | ||
@@ -19,3 +14,2 @@ this.__emitter.on(eventName, fn); | ||
} | ||
exports.EventEmitter = EventEmitter; | ||
//# sourceMappingURL=EventEmitter.js.map |
@@ -1,10 +0,5 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.fetchSourceMap = void 0; | ||
const convert_source_map_1 = require("convert-source-map"); | ||
const path_1 = __importDefault(require("path")); | ||
const request_1 = require("./request"); | ||
import pkg from 'convert-source-map'; | ||
const { mapFileCommentRegex, fromSource, fromJSON } = pkg; | ||
import path from 'path'; | ||
import { request } from './request.js'; | ||
function is2xxResponse(status) { | ||
@@ -14,5 +9,4 @@ return typeof status === 'number' && status >= 200 && status < 300; | ||
async function doFetchSourceMap(code, browserUrl, reqOpts) { | ||
var _a; | ||
try { | ||
const match = code.match(convert_source_map_1.mapFileCommentRegex); | ||
const match = code.match(mapFileCommentRegex); | ||
if (!match || !match[0]) { | ||
@@ -25,12 +19,15 @@ return; | ||
// this is a data url | ||
return (_a = convert_source_map_1.fromSource(code)) !== null && _a !== void 0 ? _a : undefined; | ||
return fromSource(code) ?? undefined; | ||
} | ||
// this is a source map pointing to another file, fetch it | ||
const dir = path_1.default.posix.dirname(browserUrl.split('?')[0].split('#')[0]); | ||
const sourcMapPath = path_1.default.join(dir, sourceMapUrl); | ||
const { response: sourceMapResponse, body: sourceMap } = await request_1.request(Object.assign(Object.assign({}, reqOpts), { path: encodeURI(sourcMapPath) })); | ||
const dir = path.posix.dirname(browserUrl.split('?')[0].split('#')[0]); | ||
const sourcMapPath = path.join(dir, sourceMapUrl); | ||
const { response: sourceMapResponse, body: sourceMap } = await request({ | ||
...reqOpts, | ||
path: encodeURI(sourcMapPath), | ||
}); | ||
if (!is2xxResponse(sourceMapResponse.statusCode) || !sourceMap) { | ||
return; | ||
} | ||
return convert_source_map_1.fromJSON(sourceMap); | ||
return fromJSON(sourceMap); | ||
} | ||
@@ -46,3 +43,3 @@ catch (error) { | ||
*/ | ||
async function fetchSourceMap(args) { | ||
export async function fetchSourceMap(args) { | ||
const headers = args.userAgent ? { 'user-agent': args.userAgent } : {}; | ||
@@ -59,3 +56,6 @@ const reqOpts = { | ||
// account for accurate transformation | ||
const { response, body: source } = await request_1.request(Object.assign(Object.assign({}, reqOpts), { path: encodeURI(args.browserUrl) })); | ||
const { response, body: source } = await request({ | ||
...reqOpts, | ||
path: encodeURI(args.browserUrl), | ||
}); | ||
// we couldn't retreive this file, this could be because it is a generated file | ||
@@ -72,3 +72,2 @@ // from a server plugin which no longer exists | ||
} | ||
exports.fetchSourceMap = fetchSourceMap; | ||
//# sourceMappingURL=fetchSourceMap.js.map |
@@ -1,5 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isTestFilePath = void 0; | ||
const constants_1 = require("./constants"); | ||
import { PARAM_MANUAL_SESSION, PARAM_SESSION_ID } from './constants.js'; | ||
/** | ||
@@ -10,8 +7,7 @@ * Returns where a given path points to a test file. This should be | ||
*/ | ||
function isTestFilePath(path) { | ||
export function isTestFilePath(path) { | ||
// create a URL with a dummy domain | ||
const url = new URL(path, 'http://localhost:123'); | ||
return url.searchParams.has(constants_1.PARAM_SESSION_ID) || url.searchParams.has(constants_1.PARAM_MANUAL_SESSION); | ||
return url.searchParams.has(PARAM_SESSION_ID) || url.searchParams.has(PARAM_MANUAL_SESSION); | ||
} | ||
exports.isTestFilePath = isTestFilePath; | ||
//# sourceMappingURL=isTestFilePath.js.map |
@@ -1,9 +0,6 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.request = void 0; | ||
const http_1 = require("http"); | ||
const https_1 = require("https"); | ||
function request(options) { | ||
import { request as httpRequest } from 'http'; | ||
import { request as httpsRequest } from 'https'; | ||
export function request(options) { | ||
const isHttps = options.protocol === 'https:'; | ||
const requestFn = isHttps ? https_1.request : http_1.request; | ||
const requestFn = isHttps ? httpsRequest : httpRequest; | ||
if (isHttps) { | ||
@@ -28,3 +25,2 @@ options.rejectUnauthorized = false; | ||
} | ||
exports.request = request; | ||
//# sourceMappingURL=request.js.map |
// this file is autogenerated with the generate-mjs-dts-entrypoints script | ||
export * from './dist/index'; | ||
export * from './dist/index.js'; |
{ | ||
"name": "@web/test-runner-core", | ||
"version": "0.0.0-canary-20230420104136", | ||
"version": "0.0.0-canary-20231122093600", | ||
"publishConfig": { | ||
@@ -18,4 +18,6 @@ "access": "public" | ||
"module": "./index.mjs", | ||
"type": "module", | ||
"exports": { | ||
".": { | ||
"types": "./index.d.ts", | ||
"import": "./index.mjs", | ||
@@ -25,2 +27,3 @@ "require": "./dist/index.js" | ||
"./test-helpers": { | ||
"types": "./dist/test-helpers.d.ts", | ||
"import": "./test-helpers.mjs", | ||
@@ -32,3 +35,3 @@ "require": "./dist/test-helpers.js" | ||
"engines": { | ||
"node": ">=16.0.0" | ||
"node": ">=18.0.0" | ||
}, | ||
@@ -63,4 +66,4 @@ "scripts": { | ||
"@types/istanbul-reports": "^3.0.0", | ||
"@web/browser-logs": "0.0.0-canary-20230420104136", | ||
"@web/dev-server-core": "0.0.0-canary-20230420104136", | ||
"@web/browser-logs": "0.0.0-canary-20231122093600", | ||
"@web/dev-server-core": "0.0.0-canary-20231122093600", | ||
"chokidar": "^3.4.3", | ||
@@ -75,3 +78,3 @@ "cli-cursor": "^3.1.0", | ||
"istanbul-lib-coverage": "^3.0.0", | ||
"istanbul-lib-report": "^3.0.0", | ||
"istanbul-lib-report": "^3.0.1", | ||
"istanbul-reports": "^3.0.2", | ||
@@ -78,0 +81,0 @@ "log-update": "^4.0.0", |
import logUpdate from 'log-update'; | ||
import cliCursor from 'cli-cursor'; | ||
import { BufferedConsole } from './BufferedConsole'; | ||
import { EventEmitter } from '../../utils/EventEmitter'; | ||
import { BufferedConsole } from './BufferedConsole.js'; | ||
import { EventEmitter } from '../../utils/EventEmitter.js'; | ||
@@ -14,3 +14,3 @@ const CLEAR_COMMAND = process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H'; | ||
export class DynamicTerminal extends EventEmitter<EventMap> { | ||
private originalFunctions: Partial<Record<keyof Console, (...args: any[]) => any>> = {}; | ||
private originalFunctions: Partial<Console> = {}; | ||
private previousDynamic: string[] = []; | ||
@@ -66,3 +66,4 @@ private started = false; | ||
for (const [key, fn] of Object.entries(this.originalFunctions)) { | ||
console[key as keyof Console] = fn; | ||
// @ts-ignore | ||
console[key] = fn; | ||
} | ||
@@ -114,7 +115,7 @@ this.started = false; | ||
if (typeof console[key] === 'function') { | ||
this.originalFunctions[key] = console[key]; | ||
this.originalFunctions[key] = console[key] as any; | ||
console[key] = new Proxy(console[key], { | ||
apply: (target, thisArg, argArray) => { | ||
this.bufferedConsole.console[key](...argArray); | ||
(this.bufferedConsole.console[key] as any)(...argArray); | ||
if (this.pendingConsoleFlush) { | ||
@@ -129,3 +130,3 @@ return; | ||
}, | ||
}); | ||
}) as any; | ||
} | ||
@@ -132,0 +133,0 @@ } |
@@ -6,15 +6,15 @@ import { codeFrameColumns } from '@babel/code-frame'; | ||
import { writeCoverageReport } from './writeCoverageReport'; | ||
import { getSelectFilesMenu } from './getSelectFilesMenu'; | ||
import { getWatchCommands } from './getWatchCommands'; | ||
import { DynamicTerminal } from './terminal/DynamicTerminal'; | ||
import { BufferedLogger } from './BufferedLogger'; | ||
import { getManualDebugMenu } from './getManualDebugMenu'; | ||
import { ErrorWithLocation } from '../logger/Logger'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus'; | ||
import { Logger } from '../logger/Logger'; | ||
import { TestRunner } from '../runner/TestRunner'; | ||
import { TestCoverage } from '../coverage/getTestCoverage'; | ||
import { writeCoverageReport } from './writeCoverageReport.js'; | ||
import { getSelectFilesMenu } from './getSelectFilesMenu.js'; | ||
import { getWatchCommands } from './getWatchCommands.js'; | ||
import { DynamicTerminal } from './terminal/DynamicTerminal.js'; | ||
import { BufferedLogger } from './BufferedLogger.js'; | ||
import { getManualDebugMenu } from './getManualDebugMenu.js'; | ||
import { ErrorWithLocation } from '../logger/Logger.js'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { Logger } from '../logger/Logger.js'; | ||
import { TestRunner } from '../runner/TestRunner.js'; | ||
import { TestCoverage } from '../coverage/getTestCoverage.js'; | ||
@@ -21,0 +21,0 @@ export type MenuType = 'none' | 'overview' | 'focus' | 'debug' | 'manual-debug'; |
import { Middleware } from '@web/dev-server-core'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
import { TestFramework } from '../test-framework/TestFramework.js'; | ||
import { TestSession } from '../test-session/TestSession.js'; | ||
import { Reporter } from '../reporter/Reporter.js'; | ||
@@ -49,3 +50,6 @@ import { Logger } from '../logger/Logger.js'; | ||
browserLogs?: boolean; | ||
filterBrowserLogs?: (log: { type: string; args: any[] }) => boolean; | ||
filterBrowserLogs?: ( | ||
log: { type: string; args: any[] }, | ||
session?: Partial<TestSession>, | ||
) => boolean; | ||
coverage?: boolean; | ||
@@ -52,0 +56,0 @@ coverageConfig: CoverageConfig; |
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestRunnerCoreConfig } from './TestRunnerCoreConfig'; | ||
import { TestRunnerCoreConfig } from './TestRunnerCoreConfig.js'; | ||
@@ -4,0 +4,0 @@ export interface TestRunnerGroupConfig { |
@@ -1,3 +0,2 @@ | ||
import { | ||
createCoverageMap, | ||
import pkg, { | ||
CoverageSummaryData, | ||
@@ -11,2 +10,3 @@ CoverageMap, | ||
} from 'istanbul-lib-coverage'; | ||
const { createCoverageMap } = pkg; | ||
import { TestSession } from '../test-session/TestSession'; | ||
@@ -13,0 +13,0 @@ import { CoverageConfig } from '../config/TestRunnerCoreConfig'; |
export { CoverageMapData } from 'istanbul-lib-coverage'; | ||
import * as constants from './utils/constants'; | ||
import * as constants from './utils/constants.js'; | ||
export { constants }; | ||
export { BrowserLauncher, SessionResult } from './browser-launcher/BrowserLauncher'; | ||
export { BrowserLauncher, SessionResult } from './browser-launcher/BrowserLauncher.js'; | ||
export { | ||
@@ -14,8 +14,8 @@ Reporter, | ||
TestRunFinishedArgs, | ||
} from './reporter/Reporter'; | ||
export { TestRunner } from './runner/TestRunner'; | ||
export { TestRunnerCli } from './cli/TestRunnerCli'; | ||
export { BufferedLogger } from './cli/BufferedLogger'; | ||
export { TestRunnerPlugin } from './server/TestRunnerPlugin'; | ||
export { TestFramework } from './test-framework/TestFramework'; | ||
} from './reporter/Reporter.js'; | ||
export { TestRunner } from './runner/TestRunner.js'; | ||
export { TestRunnerCli } from './cli/TestRunnerCli.js'; | ||
export { BufferedLogger } from './cli/BufferedLogger.js'; | ||
export { TestRunnerPlugin } from './server/TestRunnerPlugin.js'; | ||
export { TestFramework } from './test-framework/TestFramework.js'; | ||
export { | ||
@@ -25,6 +25,6 @@ TestRunnerCoreConfig, | ||
CoverageThresholdConfig, | ||
} from './config/TestRunnerCoreConfig'; | ||
export { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig'; | ||
export { TestCoverage } from './coverage/getTestCoverage'; | ||
export { Logger, ErrorWithLocation } from './logger/Logger'; | ||
} from './config/TestRunnerCoreConfig.js'; | ||
export { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig.js'; | ||
export { TestCoverage } from './coverage/getTestCoverage.js'; | ||
export { Logger, ErrorWithLocation } from './logger/Logger.js'; | ||
export { | ||
@@ -35,9 +35,9 @@ TestSession, | ||
TestSuiteResult, | ||
} from './test-session/TestSession'; | ||
export { DebugTestSession } from './test-session/DebugTestSession'; | ||
export { BasicTestSession } from './test-session/BasicTestSession'; | ||
export { TestSessionManager } from './test-session/TestSessionManager'; | ||
export { TestSessionStatus, SESSION_STATUS } from './test-session/TestSessionStatus'; | ||
export { EventEmitter } from './utils/EventEmitter'; | ||
export { isTestFilePath } from './utils/isTestFilePath'; | ||
export { fetchSourceMap } from './utils/fetchSourceMap'; | ||
} from './test-session/TestSession.js'; | ||
export { DebugTestSession } from './test-session/DebugTestSession.js'; | ||
export { BasicTestSession } from './test-session/BasicTestSession.js'; | ||
export { TestSessionManager } from './test-session/TestSessionManager.js'; | ||
export { TestSessionStatus, SESSION_STATUS } from './test-session/TestSessionStatus.js'; | ||
export { EventEmitter } from './utils/EventEmitter.js'; | ||
export { isTestFilePath } from './utils/isTestFilePath.js'; | ||
export { fetchSourceMap } from './utils/fetchSourceMap.js'; |
import { nanoid } from 'nanoid'; | ||
import path from 'path'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus'; | ||
import { TestSession } from '../test-session/TestSession'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { collectTestFiles } from './collectTestFiles'; | ||
import { TestSessionGroup } from '../test-session/TestSessionGroup'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { TestSession } from '../test-session/TestSession.js'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
import { collectTestFiles } from './collectTestFiles.js'; | ||
import { TestSessionGroup } from '../test-session/TestSessionGroup.js'; | ||
@@ -12,0 +12,0 @@ interface GroupConfigWithoutOptionals extends TestRunnerGroupConfig { |
import path from 'path'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { PARAM_SESSION_ID } from '../utils/constants'; | ||
import { BasicTestSession } from '../test-session/BasicTestSession'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { PARAM_SESSION_ID } from '../utils/constants.js'; | ||
import { BasicTestSession } from '../test-session/BasicTestSession.js'; | ||
@@ -6,0 +6,0 @@ const toBrowserPathRegExp = new RegExp(path.sep === '\\' ? '\\\\' : path.sep, 'g'); |
@@ -1,14 +0,14 @@ | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { createTestSessions } from './createSessionGroups'; | ||
import { TestSession } from '../test-session/TestSession'; | ||
import { getTestCoverage, TestCoverage } from '../coverage/getTestCoverage'; | ||
import { TestScheduler } from './TestScheduler'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus'; | ||
import { EventEmitter } from '../utils/EventEmitter'; | ||
import { createSessionUrl } from './createSessionUrl'; | ||
import { createDebugSessions } from './createDebugSessions'; | ||
import { TestRunnerServer } from '../server/TestRunnerServer'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { createTestSessions } from './createSessionGroups.js'; | ||
import { TestSession } from '../test-session/TestSession.js'; | ||
import { getTestCoverage, TestCoverage } from '../coverage/getTestCoverage.js'; | ||
import { TestScheduler } from './TestScheduler.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { EventEmitter } from '../utils/EventEmitter.js'; | ||
import { createSessionUrl } from './createSessionUrl.js'; | ||
import { createDebugSessions } from './createDebugSessions.js'; | ||
import { TestRunnerServer } from '../server/TestRunnerServer.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
import { TestRunnerGroupConfig } from '../config/TestRunnerGroupConfig.js'; | ||
@@ -15,0 +15,0 @@ interface EventMap { |
@@ -1,9 +0,9 @@ | ||
import { createSessionUrl } from './createSessionUrl'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager'; | ||
import { TestSession, TestResultError } from '../test-session/TestSession'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus'; | ||
import { withTimeout } from '../utils/async'; | ||
import { TestSessionTimeoutHandler } from './TestSessionTimeoutHandler'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { createSessionUrl } from './createSessionUrl.js'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { TestSession, TestResultError } from '../test-session/TestSession.js'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { withTimeout } from '../utils/async.js'; | ||
import { TestSessionTimeoutHandler } from './TestSessionTimeoutHandler.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
@@ -145,3 +145,4 @@ export class TestScheduler { | ||
this.timeoutHandler.waitForTestsStarted(updatedSession.testRun, updatedSession.id); | ||
} catch (error) { | ||
} catch (e) { | ||
const error = e as Error; | ||
if (this.timeoutHandler.isStale(updatedSession)) { | ||
@@ -183,3 +184,3 @@ // something else has changed the test session, such as a the browser timeout | ||
} catch (error) { | ||
sessionErrors.push(error); | ||
sessionErrors.push(error as Error); | ||
} finally { | ||
@@ -186,0 +187,0 @@ if (sessionErrors.length > 0) { |
@@ -1,6 +0,6 @@ | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager'; | ||
import { TestSession, TestResultError } from '../test-session/TestSession'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus'; | ||
import { TestScheduler } from './TestScheduler'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../test-session/TestSessionManager.js'; | ||
import { TestSession, TestResultError } from '../test-session/TestSession.js'; | ||
import { SESSION_STATUS } from '../test-session/TestSessionStatus.js'; | ||
import { TestScheduler } from './TestScheduler.js'; | ||
@@ -7,0 +7,0 @@ export class TestSessionTimeoutHandler { |
@@ -7,5 +7,5 @@ import { Middleware, Context } from '@web/dev-server-core'; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager'; | ||
import { constants } from '../..'; | ||
import { TestSession } from '../../test-session/TestSession'; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager.js'; | ||
import { constants } from '../../index.js'; | ||
import { TestSession } from '../../test-session/TestSession.js'; | ||
@@ -12,0 +12,0 @@ const IGNORED_404s = ['favicon.ico']; |
@@ -5,3 +5,3 @@ import path from 'path'; | ||
import { fetchSourceMap } from '../../../utils/fetchSourceMap'; | ||
import { fetchSourceMap } from '../../../utils/fetchSourceMap.js'; | ||
import { StackLocation } from '@web/browser-logs'; | ||
@@ -14,8 +14,2 @@ | ||
interface CachedSourceMap { | ||
sourceMap?: SourceMapConverter; | ||
consumer?: SourceMapConsumer; | ||
loadingPromise?: Promise<void>; | ||
} | ||
function resolveRelativeTo(relativeTo: string, filePath: string): string { | ||
@@ -41,53 +35,28 @@ if (path.isAbsolute(filePath)) { | ||
): SourceMapFunction { | ||
const cachedSourceMaps = new Map<string, CachedSourceMap | null>(); | ||
const cachedSourceMaps = new Map<string, Promise<SourceMapConverter | undefined>>(); | ||
return async ({ browserUrl, filePath, line, column }, userAgent) => { | ||
try { | ||
const cacheKey = `${filePath}${userAgent}`; | ||
let cached = cachedSourceMaps.get(cacheKey); | ||
if (cached) { | ||
if (cached.loadingPromise) { | ||
// a request for this source map is already being done in parallel, wait for it to finish | ||
await cached.loadingPromise; | ||
} | ||
const cacheKey = `${filePath}${userAgent}`; | ||
if (!cached.sourceMap) { | ||
// we know there is no source map for this file | ||
return null; | ||
} | ||
} else { | ||
cached = {}; | ||
} | ||
cachedSourceMaps.set(cacheKey, cached); | ||
if (!cachedSourceMaps.has(cacheKey)) { | ||
cachedSourceMaps.set( | ||
cacheKey, | ||
fetchSourceMap({ | ||
protocol, | ||
host, | ||
port, | ||
browserUrl, | ||
userAgent, | ||
}) | ||
.then(({ sourceMap }) => sourceMap) | ||
.catch(() => undefined), | ||
); | ||
} | ||
// get the raw source map, from cache or new | ||
let sourceMap: SourceMapConverter | undefined; | ||
if (cached.sourceMap) { | ||
sourceMap = cached?.sourceMap; | ||
} else { | ||
// fetch source map, maintain a loading boolean for parallel calls to wait before resolving | ||
let resolveLoading: () => void; | ||
const loadingPromise = new Promise<void>(resolve => { | ||
resolveLoading = resolve; | ||
}); | ||
cached.loadingPromise = loadingPromise; | ||
const sourceMap = await cachedSourceMaps.get(cacheKey); | ||
if (!sourceMap) { | ||
return null; | ||
} | ||
try { | ||
const result = await fetchSourceMap({ | ||
protocol, | ||
host, | ||
port, | ||
browserUrl, | ||
userAgent, | ||
}); | ||
sourceMap = result.sourceMap; | ||
cached.sourceMap = sourceMap; | ||
} finally { | ||
resolveLoading!(); | ||
} | ||
} | ||
if (!sourceMap) { | ||
return null; | ||
} | ||
try { | ||
// if there is no line and column we're looking for just the associated file, for example | ||
@@ -110,9 +79,3 @@ // the test file itself has source maps. if this is a single file source map, we can return | ||
// do the actual source mapping | ||
let consumer: SourceMapConsumer; | ||
if (cached?.consumer) { | ||
consumer = cached.consumer; | ||
} else { | ||
consumer = await new SourceMapConsumer(sourceMap.sourcemap); | ||
cachedSourceMaps.get(cacheKey)!.consumer = consumer; | ||
} | ||
const consumer: SourceMapConsumer = await new SourceMapConsumer(sourceMap.sourcemap); | ||
@@ -133,2 +96,4 @@ let originalPosition = consumer.originalPositionFor({ | ||
consumer.destroy(); | ||
if (originalPosition.line == null) { | ||
@@ -135,0 +100,0 @@ return null; |
import { MapStackLocation, parseStackTrace } from '@web/browser-logs'; | ||
import { MapBrowserUrl } from '@web/browser-logs/src/parseStackTrace'; | ||
import { MapBrowserUrl } from '@web/browser-logs'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig.js'; | ||
import { | ||
@@ -10,4 +10,4 @@ TestResult, | ||
TestSuiteResult, | ||
} from '../../../test-session/TestSession'; | ||
import { forEachAsync } from '../../../utils/async'; | ||
} from '../../../test-session/TestSession.js'; | ||
import { forEachAsync } from '../../../utils/async.js'; | ||
@@ -14,0 +14,0 @@ export async function replaceErrorStack( |
import { deserialize, MapStackLocation } from '@web/browser-logs'; | ||
import { MapBrowserUrl } from '@web/browser-logs/src/parseStackTrace'; | ||
import { MapBrowserUrl } from '@web/browser-logs'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestSession } from '../../../test-session/TestSession'; | ||
import { mapAsync } from '../../../utils/async'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig.js'; | ||
import { TestSession } from '../../../test-session/TestSession.js'; | ||
import { mapAsync } from '../../../utils/async.js'; | ||
@@ -43,3 +43,3 @@ interface BrowserLog { | ||
for (const log of logsWithType) { | ||
if (!config.filterBrowserLogs || config.filterBrowserLogs(log)) { | ||
if (!config.filterBrowserLogs || config.filterBrowserLogs(log, result)) { | ||
logs.push(log.args); | ||
@@ -46,0 +46,0 @@ } |
@@ -1,9 +0,8 @@ | ||
import { MapStackLocation, StackLocation } from '@web/browser-logs'; | ||
import { MapBrowserUrl } from '@web/browser-logs/src/parseStackTrace'; | ||
import { MapStackLocation, StackLocation, MapBrowserUrl } from '@web/browser-logs'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestSession } from '../../../test-session/TestSession'; | ||
import { SourceMapFunction } from './createSourceMapFunction'; | ||
import { parseSessionErrors, parseTestResults } from './parseBrowserErrors'; | ||
import { parseBrowserLogs } from './parseBrowserLogs'; | ||
import { SourceMapFunction } from './createSourceMapFunction.js'; | ||
import { parseSessionErrors, parseTestResults } from './parseBrowserErrors.js'; | ||
import { parseBrowserLogs } from './parseBrowserLogs.js'; | ||
@@ -10,0 +9,0 @@ function createMapStackLocation(smFn: SourceMapFunction, userAgent: string): MapStackLocation { |
import { Context, getRequestFilePath, ServerStartParams, WebSocket } from '@web/dev-server-core'; | ||
import { MapBrowserUrl } from '@web/browser-logs/src/parseStackTrace'; | ||
import { MapBrowserUrl } from '@web/browser-logs'; | ||
import parse from 'co-body'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig'; | ||
import { TestSessionManager } from '../../../test-session/TestSessionManager'; | ||
import { PARAM_SESSION_ID } from '../../../utils/constants'; | ||
import { TestRunnerPlugin } from '../../TestRunnerPlugin'; | ||
import { SESSION_STATUS } from '../../../test-session/TestSessionStatus'; | ||
import { TestSession } from '../../../test-session/TestSession'; | ||
import { parseBrowserResult } from './parseBrowserResult'; | ||
import { TestRunner } from '../../../runner/TestRunner'; | ||
import { createSourceMapFunction, SourceMapFunction } from './createSourceMapFunction'; | ||
import { DebugTestSession } from '../../../test-session/DebugTestSession'; | ||
import { TestRunnerCoreConfig } from '../../../config/TestRunnerCoreConfig.js'; | ||
import { TestSessionManager } from '../../../test-session/TestSessionManager.js'; | ||
import { PARAM_SESSION_ID } from '../../../utils/constants.js'; | ||
import { TestRunnerPlugin } from '../../TestRunnerPlugin.js'; | ||
import { SESSION_STATUS } from '../../../test-session/TestSessionStatus.js'; | ||
import { TestSession } from '../../../test-session/TestSession.js'; | ||
import { parseBrowserResult } from './parseBrowserResult.js'; | ||
import { TestRunner } from '../../../runner/TestRunner.js'; | ||
import { createSourceMapFunction, SourceMapFunction } from './createSourceMapFunction.js'; | ||
import { DebugTestSession } from '../../../test-session/DebugTestSession.js'; | ||
@@ -220,3 +220,5 @@ interface SessionMessage extends Record<string, unknown> { | ||
this.config.logger.error(error); | ||
webSocket.send(JSON.stringify({ type: 'message-response', id, error: error.message })); | ||
webSocket.send( | ||
JSON.stringify({ type: 'message-response', id, error: (error as Error).message }), | ||
); | ||
return; | ||
@@ -223,0 +225,0 @@ } |
import { Context, getRequestFilePath } from '@web/dev-server-core'; | ||
import { PARAM_SESSION_ID, PARAM_TEST_FILE } from '../../utils/constants'; | ||
import { TestRunnerCoreConfig } from '../../config/TestRunnerCoreConfig'; | ||
import { createTestFileImportPath } from '../utils'; | ||
import { trackBrowserLogs } from './trackBrowserLogs'; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager'; | ||
import { TestRunnerGroupConfig } from '../../config/TestRunnerGroupConfig'; | ||
import { PARAM_SESSION_ID, PARAM_TEST_FILE } from '../../utils/constants.js'; | ||
import { TestRunnerCoreConfig } from '../../config/TestRunnerCoreConfig.js'; | ||
import { createTestFileImportPath } from '../utils.js'; | ||
import { trackBrowserLogs } from './trackBrowserLogs.js'; | ||
import { TestSessionManager } from '../../test-session/TestSessionManager.js'; | ||
import { TestRunnerGroupConfig } from '../../config/TestRunnerGroupConfig.js'; | ||
@@ -10,0 +10,0 @@ const iframeModePage = ` |
import { DevServer, Plugin } from '@web/dev-server-core'; | ||
import chokidar from 'chokidar'; | ||
import { RunSessions, watchFilesMiddleware } from './middleware/watchFilesMiddleware'; | ||
import { cacheMiddleware } from './middleware/cacheMiddleware'; | ||
import { serveTestRunnerHtmlPlugin } from './plugins/serveTestRunnerHtmlPlugin'; | ||
import { serveTestFrameworkPlugin } from './plugins/serveTestFrameworkPlugin'; | ||
import { testRunnerApiPlugin } from './plugins/api/testRunnerApiPlugin'; | ||
import { RunSessions, watchFilesMiddleware } from './middleware/watchFilesMiddleware.js'; | ||
import { cacheMiddleware } from './middleware/cacheMiddleware.js'; | ||
import { serveTestRunnerHtmlPlugin } from './plugins/serveTestRunnerHtmlPlugin.js'; | ||
import { serveTestFrameworkPlugin } from './plugins/serveTestFrameworkPlugin.js'; | ||
import { testRunnerApiPlugin } from './plugins/api/testRunnerApiPlugin.js'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
@@ -10,0 +10,0 @@ import { TestSessionManager } from '../test-session/TestSessionManager'; |
import path from 'path'; | ||
import { Context } from '@web/dev-server-core'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig'; | ||
import { PARAM_SESSION_ID, PARAM_MANUAL_SESSION } from '../utils/constants'; | ||
import { TestRunnerCoreConfig } from '../config/TestRunnerCoreConfig.js'; | ||
import { PARAM_SESSION_ID, PARAM_MANUAL_SESSION } from '../utils/constants.js'; | ||
@@ -6,0 +6,0 @@ const toBrowserPathRegExp = new RegExp(path.sep === '\\' ? '\\\\' : path.sep, 'g'); |
/* eslint-disable no-async-promise-executor, no-inner-declarations */ | ||
import { getPortPromise } from 'portfinder'; | ||
import path from 'path'; | ||
import { TestRunner, TestRunnerCoreConfig } from './index'; | ||
import { Logger } from './logger/Logger'; | ||
import { TestResult, TestSession, TestSuiteResult } from './test-session/TestSession'; | ||
import { SESSION_STATUS } from './test-session/TestSessionStatus'; | ||
import { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig'; | ||
import * as url from 'url'; | ||
import { createRequire } from 'node:module'; | ||
import { TestRunner, TestRunnerCoreConfig } from './index.js'; | ||
import { Logger } from './logger/Logger.js'; | ||
import { TestResult, TestSession, TestSuiteResult } from './test-session/TestSession.js'; | ||
import { SESSION_STATUS } from './test-session/TestSessionStatus.js'; | ||
import { TestRunnerGroupConfig } from './config/TestRunnerGroupConfig.js'; | ||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); | ||
const require = createRequire(import.meta.url); | ||
const logger: Logger = { | ||
@@ -39,2 +45,4 @@ ...console, | ||
logger, | ||
//manual: true, | ||
//port: 9999 | ||
}; | ||
@@ -64,6 +72,2 @@ | ||
// runner.sessions.on('session-status-updated', session => { | ||
// console.log(session.browser.name, session.id, session.status); | ||
// }); | ||
let finished = false; | ||
@@ -70,0 +74,0 @@ |
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestSessionGroup } from './TestSessionGroup'; | ||
import { TestSessionGroup } from './TestSessionGroup.js'; | ||
@@ -4,0 +4,0 @@ export interface BasicTestSession { |
@@ -1,2 +0,2 @@ | ||
import { BasicTestSession } from './BasicTestSession'; | ||
import { BasicTestSession } from './BasicTestSession.js'; | ||
@@ -3,0 +3,0 @@ export interface DebugTestSession extends BasicTestSession { |
import { CoverageMapData } from 'istanbul-lib-coverage'; | ||
import { TestSessionStatus } from './TestSessionStatus'; | ||
import { BasicTestSession } from './BasicTestSession'; | ||
import { TestSessionStatus } from './TestSessionStatus.js'; | ||
import { BasicTestSession } from './BasicTestSession.js'; | ||
@@ -5,0 +5,0 @@ export interface TestResultError { |
@@ -1,7 +0,7 @@ | ||
import { TestSession } from './TestSession'; | ||
import { TestSessionStatus } from './TestSessionStatus'; | ||
import { EventEmitter } from '../utils/EventEmitter'; | ||
import { DebugTestSession } from './DebugTestSession'; | ||
import { TestSessionGroup } from './TestSessionGroup'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher'; | ||
import { TestSession } from './TestSession.js'; | ||
import { TestSessionStatus } from './TestSessionStatus.js'; | ||
import { EventEmitter } from '../utils/EventEmitter.js'; | ||
import { DebugTestSession } from './DebugTestSession.js'; | ||
import { TestSessionGroup } from './TestSessionGroup.js'; | ||
import { BrowserLauncher } from '../browser-launcher/BrowserLauncher.js'; | ||
@@ -8,0 +8,0 @@ interface EventMap { |
@@ -1,6 +0,8 @@ | ||
import { mapFileCommentRegex, fromSource, SourceMapConverter, fromJSON } from 'convert-source-map'; | ||
import { SourceMapConverter } from 'convert-source-map'; | ||
import pkg from 'convert-source-map'; | ||
const { mapFileCommentRegex, fromSource, fromJSON } = pkg; | ||
import path from 'path'; | ||
import { RequestOptions } from 'http'; | ||
import { request } from './request'; | ||
import { request } from './request.js'; | ||
@@ -7,0 +9,0 @@ function is2xxResponse(status?: number) { |
@@ -1,2 +0,2 @@ | ||
import { PARAM_MANUAL_SESSION, PARAM_SESSION_ID } from './constants'; | ||
import { PARAM_MANUAL_SESSION, PARAM_SESSION_ID } from './constants.js'; | ||
@@ -3,0 +3,0 @@ /** |
// this file is autogenerated with the generate-mjs-dts-entrypoints script | ||
export * from './dist/test-helpers'; | ||
export * from './dist/test-helpers.js'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Yes
389244
6832
+ Added@koddsson/errorstacks@2.4.1(transitive)
+ Added@web/browser-logs@0.0.0-canary-20231122093600(transitive)
+ Added@web/dev-server-core@0.0.0-canary-20231122093600(transitive)
+ Added@web/parse5-utils@0.0.0-canary-20231122093600(transitive)
- Removed@web/browser-logs@0.0.0-canary-20230420104136(transitive)
- Removed@web/dev-server-core@0.0.0-canary-20230420104136(transitive)
- Removed@web/parse5-utils@0.0.0-canary-20230420104136(transitive)
- Removederrorstacks@2.4.1(transitive)
Updatedistanbul-lib-report@^3.0.1