From c3407e60333bb472aab498acd210d0893abccaf3 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Wed, 3 Jun 2026 00:04:43 +0300 Subject: [PATCH 1/9] test(test-runner): migrate integration tests from mocha/chai to node:test Migrate the shared integration test framework and all three browser launcher test wrappers (chrome, playwright, puppeteer) from mocha/chai to node:test/node:assert/strict. Changes: - integration/test-runner: chai assertions to node:assert, mocha globals to node:test imports, `__dirname` to `import.meta.dirname`, internal imports use .ts extension for strip-types - test-runner-chrome: this.timeout to describe options, src -> dist imports, integration import uses .ts extension - test-runner-playwright: same as chrome - test-runner-puppeteer: same as chrome - All test scripts: mocha -> node --experimental-strip-types --test No published code changes. All packages' src/ directories are untouched. Assisted-By: Claude Opus 4.6 (1M context) --- integration/test-runner/index.ts | 17 +- integration/test-runner/package.json | 5 +- .../test-runner/tests/basic/runBasicTest.ts | 41 +++-- .../config-groups/runConfigGroupsTest.ts | 12 +- .../test-runner/tests/focus/runFocusTest.ts | 10 +- .../location-change/runLocationChangeTest.ts | 59 +++--- .../test-runner/tests/many/runManyTests.ts | 5 +- .../tests/parallel/runParallelTest.ts | 7 +- .../tests/test-failure/runTestFailureTest.ts | 174 ++++++++++-------- packages/test-runner-chrome/package.json | 4 +- .../test/chromeLauncher.test.ts | 9 +- packages/test-runner-playwright/package.json | 4 +- .../test/playwrightLauncher.test.ts | 22 +-- packages/test-runner-puppeteer/package.json | 4 +- .../test/puppeteerLauncher.test.ts | 9 +- 15 files changed, 200 insertions(+), 182 deletions(-) diff --git a/integration/test-runner/index.ts b/integration/test-runner/index.ts index c6fe56365..8cdb7a95e 100644 --- a/integration/test-runner/index.ts +++ b/integration/test-runner/index.ts @@ -1,11 +1,12 @@ -import { BrowserLauncher, TestRunnerCoreConfig } from '@web/test-runner-core'; -import { runBasicTest } from './tests/basic/runBasicTest.js'; -import { runConfigGroupsTest } from './tests/config-groups/runConfigGroupsTest.js'; -import { runParallelTest } from './tests/parallel/runParallelTest.js'; -import { runTestFailureTest } from './tests/test-failure/runTestFailureTest.js'; -import { runLocationChangeTest } from './tests/location-change/runLocationChangeTest.js'; -import { runFocusTest } from './tests/focus/runFocusTest.js'; -import { runManyTests } from './tests/many/runManyTests.js'; +import { describe } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig } from '@web/test-runner-core'; +import { runBasicTest } from './tests/basic/runBasicTest.ts'; +import { runConfigGroupsTest } from './tests/config-groups/runConfigGroupsTest.ts'; +import { runParallelTest } from './tests/parallel/runParallelTest.ts'; +import { runTestFailureTest } from './tests/test-failure/runTestFailureTest.ts'; +import { runLocationChangeTest } from './tests/location-change/runLocationChangeTest.ts'; +import { runFocusTest } from './tests/focus/runFocusTest.ts'; +import { runManyTests } from './tests/many/runManyTests.ts'; export interface Tests { basic: boolean; diff --git a/integration/test-runner/package.json b/integration/test-runner/package.json index 7d1dd86a9..a7c7e0e26 100644 --- a/integration/test-runner/package.json +++ b/integration/test-runner/package.json @@ -16,8 +16,9 @@ "homepage": "https://github.com/modernweb-dev/web/tree/master/packages/test-runner-integration-tests", "main": "index.js", "scripts": { - "test": "mocha test/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test/**/*.test.ts --require ts-node/register --watch --watch-files src,test --reporter dot" + "test": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", + "test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\"" }, "dependencies": { "@web/dev-server-legacy": "^2.1.0", diff --git a/integration/test-runner/tests/basic/runBasicTest.ts b/integration/test-runner/tests/basic/runBasicTest.ts index ce9d9c4b1..4e95f18c1 100644 --- a/integration/test-runner/tests/basic/runBasicTest.ts +++ b/integration/test-runner/tests/basic/runBasicTest.ts @@ -1,8 +1,9 @@ -import { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; -import { expect } from 'chai'; export function runBasicTest( config: Partial & { browsers: BrowserLauncher[] }, @@ -14,36 +15,34 @@ export function runBasicTest( before(async () => { const result = await runTests({ ...config, - files: [...(config.files ?? []), resolve(__dirname, 'browser-tests', '*.test.js')], + files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], plugins: [...(config.plugins ?? []), legacyPlugin()], }); allSessions = result.sessions; - expect(allSessions.every(s => s.passed)).to.equal(true, 'All sessions should have passed'); + assert.equal(allSessions.every(s => s.passed), true, 'All sessions should have passed'); }); it('passes basic test', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('basic.test.js')); - expect(sessions.length === browserCount).to.equal( - true, - 'Each browser should run basic.test.js', - ); + assert.equal(sessions.length === browserCount, true, 'Each browser should run basic.test.js'); for (const session of sessions) { - expect(session.testResults!.tests.length).to.equal(0); - expect(session.testResults!.suites.length).to.equal(1); - expect(session.testResults!.suites[0].tests.length).to.equal(1); - expect(session.testResults!.suites[0].tests.map(t => t.name)).to.eql(['works']); + assert.equal(session.testResults!.tests.length, 0); + assert.equal(session.testResults!.suites.length, 1); + assert.equal(session.testResults!.suites[0].tests.length, 1); + assert.deepEqual(session.testResults!.suites[0].tests.map(t => t.name), ['works']); } }); it('passes js-syntax test', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('js-syntax.test.js')); - expect(sessions.length === browserCount).to.equal( + assert.equal( + sessions.length === browserCount, true, 'Each browser should run js-syntax.test.js', ); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql([ + assert.deepEqual(session.testResults!.tests.map(t => t.name), [ 'supports object spread', 'supports async functions', 'supports exponentiation', @@ -57,12 +56,13 @@ export function runBasicTest( it('passes module-features test', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('module-features.test.js')); - expect(sessions.length === browserCount).to.equal( + assert.equal( + sessions.length === browserCount, true, 'Each browser should run module-features.test.js', ); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql([ + assert.deepEqual(session.testResults!.tests.map(t => t.name), [ 'supports static imports', 'supports dynamic imports', 'supports import meta', @@ -72,14 +72,15 @@ export function runBasicTest( it('passes timers test', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('timers.test.js')); - expect(sessions.length === browserCount).to.equal( + assert.equal( + sessions.length === browserCount, true, 'Each browser should run timers.test.js', ); for (const session of sessions) { - expect(session.testResults!.tests.length).to.equal(0); - expect(session.testResults!.suites.length).to.equal(1); - expect(session.testResults!.suites[0].tests.map(t => t.name)).to.eql([ + assert.equal(session.testResults!.tests.length, 0); + assert.equal(session.testResults!.suites.length, 1); + assert.deepEqual(session.testResults!.suites[0].tests.map(t => t.name), [ 'can call setTimeout', 'can cancel setTimeout', 'can call and cancel setInterval', diff --git a/integration/test-runner/tests/config-groups/runConfigGroupsTest.ts b/integration/test-runner/tests/config-groups/runConfigGroupsTest.ts index 0e8b0aec1..ddd1171bf 100644 --- a/integration/test-runner/tests/config-groups/runConfigGroupsTest.ts +++ b/integration/test-runner/tests/config-groups/runConfigGroupsTest.ts @@ -1,4 +1,6 @@ -import { +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig, TestRunnerGroupConfig, @@ -6,7 +8,6 @@ import { import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; -import { expect } from 'chai'; export function runConfigGroupsTest( config: Partial & { browsers: BrowserLauncher[] }, @@ -18,13 +19,13 @@ export function runConfigGroupsTest( name: 'a', testRunnerHtml: path => ``, - files: [resolve(__dirname, 'browser-tests', 'test-runner-html-a.test.js')], + files: [resolve(import.meta.dirname, 'browser-tests', 'test-runner-html-a.test.js')], }, { name: 'b', testRunnerHtml: path => ``, - files: [resolve(__dirname, 'browser-tests', 'test-runner-html-b.test.js')], + files: [resolve(import.meta.dirname, 'browser-tests', 'test-runner-html-b.test.js')], }, ]; const result = await runTests( @@ -35,7 +36,8 @@ export function runConfigGroupsTest( groupConfigs, ); - expect(result.sessions.every(s => s.passed)).to.equal( + assert.equal( + result.sessions.every(s => s.passed), true, 'All sessions should have passed', ); diff --git a/integration/test-runner/tests/focus/runFocusTest.ts b/integration/test-runner/tests/focus/runFocusTest.ts index f32b5247d..3c98f5a0a 100644 --- a/integration/test-runner/tests/focus/runFocusTest.ts +++ b/integration/test-runner/tests/focus/runFocusTest.ts @@ -1,8 +1,9 @@ -import { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; -import { expect } from 'chai'; export function runFocusTest( config: Partial & { browsers: BrowserLauncher[] }, @@ -13,16 +14,15 @@ export function runFocusTest( before(async () => { const result = await runTests({ ...config, - // 2 means some are executed concurrently, and some sequentially concurrency: 2, - files: [...(config.files ?? []), resolve(__dirname, 'browser-tests', '*.test.js')], + files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], plugins: [...(config.plugins ?? []), legacyPlugin()], }); allSessions = result.sessions; }); it.skip('can run tests with focus, concurrently and sequentially', () => { - expect(allSessions.every(s => s.passed)).to.equal(true, 'All sessions should have passed'); + assert.equal(allSessions.every(s => s.passed), true, 'All sessions should have passed'); }); }); } diff --git a/integration/test-runner/tests/location-change/runLocationChangeTest.ts b/integration/test-runner/tests/location-change/runLocationChangeTest.ts index 820ffff69..f3b9ca2a1 100644 --- a/integration/test-runner/tests/location-change/runLocationChangeTest.ts +++ b/integration/test-runner/tests/location-change/runLocationChangeTest.ts @@ -1,8 +1,9 @@ -import { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; -import { expect } from 'chai'; export function runLocationChangeTest( config: Partial & { browsers: BrowserLauncher[] }, @@ -15,7 +16,7 @@ export function runLocationChangeTest( const result = await runTests( { ...config, - files: [...(config.files ?? []), resolve(__dirname, 'browser-tests', '*.test.js')], + files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], plugins: [...(config.plugins ?? []), legacyPlugin()], }, undefined, @@ -23,32 +24,36 @@ export function runLocationChangeTest( ); allSessions = result.sessions; - expect(allSessions.every(s => s.passed)).to.equal(false, 'All sessions should have failed'); + assert.equal(allSessions.every(s => s.passed), false, 'All sessions should have failed'); }); it('handles tests which assign to window.location.href', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-location-href.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults).to.equal(undefined); - expect(session.logs).to.eql([]); - expect(session.errors.length).to.equal(1); - expect(session.errors[0].message).to.include( - 'Tests were interrupted because the page navigated to', + assert.equal(session.testResults, undefined); + assert.deepEqual(session.logs, []); + assert.equal(session.errors.length, 1); + assert.ok( + session.errors[0].message.includes( + 'Tests were interrupted because the page navigated to', + ), ); - expect(session.errors[0].message).to.include( - 'This can happen when clicking a link, submitting a form or interacting with window.location.', + assert.ok( + session.errors[0].message.includes( + 'This can happen when clicking a link, submitting a form or interacting with window.location.', + ), ); } }); it('handles tests which call window.location.reload()', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-location-reload.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults).to.equal(undefined); - expect(session.logs).to.eql([]); - expect(session.errors).to.eql([ + assert.equal(session.testResults, undefined); + assert.deepEqual(session.logs, []); + assert.deepEqual(session.errors, [ { message: 'Tests were interrupted because the page was reloaded. This can happen when clicking a link, submitting a form or interacting with window.location.', @@ -61,17 +66,21 @@ export function runLocationChangeTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-location-replace.test.js'), ); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults).to.equal(undefined); - expect(session.logs).to.eql([]); - expect(session.errors.length).to.equal(1); - expect(session.errors[0].message).to.include( - 'Tests were interrupted because the page navigated to', + assert.equal(session.testResults, undefined); + assert.deepEqual(session.logs, []); + assert.equal(session.errors.length, 1); + assert.ok( + session.errors[0].message.includes( + 'Tests were interrupted because the page navigated to', + ), ); - expect(session.errors[0].message).to.include('/new-page/'); - expect(session.errors[0].message).to.include( - 'This can happen when clicking a link, submitting a form or interacting with window.location.', + assert.ok(session.errors[0].message.includes('/new-page/')); + assert.ok( + session.errors[0].message.includes( + 'This can happen when clicking a link, submitting a form or interacting with window.location.', + ), ); } }); diff --git a/integration/test-runner/tests/many/runManyTests.ts b/integration/test-runner/tests/many/runManyTests.ts index 6ef326bc5..0cb5c68cb 100644 --- a/integration/test-runner/tests/many/runManyTests.ts +++ b/integration/test-runner/tests/many/runManyTests.ts @@ -1,4 +1,5 @@ -import { BrowserLauncher, TestRunnerCoreConfig } from '@web/test-runner-core'; +import { describe, it } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; @@ -11,7 +12,7 @@ export function runManyTests( await Promise.all([ runTests({ ...config, - files: [...(config.files ?? []), resolve(__dirname, 'browser-tests', '*.test.js')], + files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], plugins: [...(config.plugins ?? []), legacyPlugin()], }), ]); diff --git a/integration/test-runner/tests/parallel/runParallelTest.ts b/integration/test-runner/tests/parallel/runParallelTest.ts index 244d8ad76..dc22f853f 100644 --- a/integration/test-runner/tests/parallel/runParallelTest.ts +++ b/integration/test-runner/tests/parallel/runParallelTest.ts @@ -1,4 +1,5 @@ -import { BrowserLauncher, TestRunnerCoreConfig } from '@web/test-runner-core'; +import { describe, it } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; @@ -14,13 +15,13 @@ export function runParallelTest( await Promise.all([ runTests({ ...configA, - files: [...(configA.files ?? []), resolve(__dirname, 'browser-tests', '*.test.js')], + files: [...(configA.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], plugins: [...(configA.plugins ?? []), legacyPlugin()], }), runTests({ ...configB, - files: [...(configB.files ?? []), resolve(__dirname, 'browser-tests', '*.test.js')], + files: [...(configB.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], plugins: [...(configB.plugins ?? []), legacyPlugin()], }), ]); diff --git a/integration/test-runner/tests/test-failure/runTestFailureTest.ts b/integration/test-runner/tests/test-failure/runTestFailureTest.ts index 85be1a0c2..5a1d7f900 100644 --- a/integration/test-runner/tests/test-failure/runTestFailureTest.ts +++ b/integration/test-runner/tests/test-failure/runTestFailureTest.ts @@ -1,8 +1,9 @@ -import { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; +import type { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve, sep } from 'path'; -import { expect } from 'chai'; const ERROR_NOT_IMPORTABLE = { message: @@ -34,7 +35,7 @@ export function runTestFailureTest( const result = await runTests( { ...config, - files: [...(config.files ?? []), resolve(__dirname, 'browser-tests', '*.test.js')], + files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], plugins: [...(config.plugins ?? []), legacyPlugin()], }, undefined, @@ -42,31 +43,32 @@ export function runTestFailureTest( ); allSessions = result.sessions; - expect(allSessions.every(s => s.passed)).to.equal(false, 'All sessions should have failed'); + assert.equal(allSessions.every(s => s.passed), false, 'All sessions should have failed'); }); it('handles tests with 404 imports', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-404-import.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.suites.length).to.equal(0); - expect(session.testResults!.tests.length).to.equal(0); - expect(session.request404s).to.eql([ + assert.equal(session.testResults!.suites.length, 0); + assert.equal(session.testResults!.tests.length, 0); + assert.deepEqual(session.request404s, [ 'integration/test-runner/tests/test-failure/browser-tests/non-existing.js', ]); - expect(session.errors).to.eql([ERROR_NOT_IMPORTABLE]); - expect(session.logs.length).to.equal(1); + assert.deepEqual(session.errors, [ERROR_NOT_IMPORTABLE]); + assert.equal(session.logs.length, 1); expectFetchModuleFailed((session.logs[0] as any)[0]); } }); it('handles tests that error with a circular reference', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-circular-error.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql(['bad predicate']); - expect(session.passed).to.be.false; - expect(session.testResults!.tests![0].error!.message).to.equal( + assert.deepEqual(session.testResults!.tests.map(t => t.name), ['bad predicate']); + assert.equal(session.passed, false); + assert.equal( + session.testResults!.tests![0].error!.message, "expected { x: 'x', circle: [Circular] } to equal null", ); } @@ -74,86 +76,93 @@ export function runTestFailureTest( it('handles tests that throw in afterEach', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-after-each.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql([ + assert.deepEqual(session.testResults!.tests.map(t => t.name), [ 'true is true', 'true is really true', ]); - expect(session.errors.length).to.equal(1); - expect(session.errors[0].message).to.include('error thrown in afterEach hook'); - expect(session.errors[0].stack).to.include( - `test-failure${sep}browser-tests${sep}fail-after-each.test.js`, + assert.equal(session.errors.length, 1); + assert.ok(session.errors[0].message.includes('error thrown in afterEach hook')); + assert.ok( + session.errors[0].stack!.includes( + `test-failure${sep}browser-tests${sep}fail-after-each.test.js`, + ), ); - expect(session.logs).to.eql([]); + assert.deepEqual(session.logs, []); } }); it('handles tests that throw in after', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-after.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql([ + assert.deepEqual(session.testResults!.tests.map(t => t.name), [ 'true is true', 'true is really true', ]); - expect(session.errors.length).to.equal(1); - expect(session.errors[0].message).to.include('error thrown in after hook'); - - expect(session.errors[0].stack).to.include( - `test-failure${sep}browser-tests${sep}fail-after.test.js`, + assert.equal(session.errors.length, 1); + assert.ok(session.errors[0].message.includes('error thrown in after hook')); + assert.ok( + session.errors[0].stack!.includes( + `test-failure${sep}browser-tests${sep}fail-after.test.js`, + ), ); - expect(session.logs).to.eql([]); + assert.deepEqual(session.logs, []); } }); it('handles tests that throw in beforeEach', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-before-each.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql([ + assert.deepEqual(session.testResults!.tests.map(t => t.name), [ 'true is true', 'true is really true', ]); - expect(session.errors.length).to.equal(1); - expect(session.errors[0].message).to.include('error thrown in beforeEach hook'); - - expect(session.errors[0].stack).to.include( - `test-failure${sep}browser-tests${sep}fail-before-each.test.js`, + assert.equal(session.errors.length, 1); + assert.ok(session.errors[0].message.includes('error thrown in beforeEach hook')); + assert.ok( + session.errors[0].stack!.includes( + `test-failure${sep}browser-tests${sep}fail-before-each.test.js`, + ), ); - expect(session.logs).to.eql([]); + assert.deepEqual(session.logs, []); } }); it('handles tests that throw in before', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-before.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql([ + assert.deepEqual(session.testResults!.tests.map(t => t.name), [ 'true is true', 'true is really true', ]); - expect(session.errors.length).to.equal(1); - expect(session.errors[0].message).to.include('error thrown in before hook'); - - expect(session.errors[0].stack).to.include( - `test-failure${sep}browser-tests${sep}fail-before.test.js`, + assert.equal(session.errors.length, 1); + assert.ok(session.errors[0].message.includes('error thrown in before hook')); + assert.ok( + session.errors[0].stack!.includes( + `test-failure${sep}browser-tests${sep}fail-before.test.js`, + ), ); - expect(session.logs).to.eql([]); + assert.deepEqual(session.logs, []); } }); it('handles a custom thrown error', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-custom-error.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql(['custom error']); - expect(session.testResults!.tests[0].error!.message).to.include('a custom error thrown'); - expect(session.testResults!.tests[0].error!.stack).to.include( - `browser-tests${sep}fail-custom-error.test.js`, + assert.deepEqual(session.testResults!.tests.map(t => t.name), ['custom error']); + assert.ok(session.testResults!.tests[0].error!.message.includes('a custom error thrown')); + assert.ok( + session.testResults!.tests[0].error!.stack!.includes( + `browser-tests${sep}fail-custom-error.test.js`, + ), ); - expect(session.errors).to.eql([]); - expect(session.logs).to.eql([]); + assert.deepEqual(session.errors, []); + assert.deepEqual(session.logs, []); } }); @@ -161,61 +170,64 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-error-module-exec.test.js'), ); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.suites.length).to.equal(0); - expect(session.testResults!.tests.length).to.equal(0); - expect(session.errors).to.eql([ERROR_NOT_IMPORTABLE]); - expect(session.logs[0][0]).to.include('This is thrown before running tests'); + assert.equal(session.testResults!.suites.length, 0); + assert.equal(session.testResults!.tests.length, 0); + assert.deepEqual(session.errors, [ERROR_NOT_IMPORTABLE]); + assert.ok((session.logs[0][0] as any).includes('This is thrown before running tests')); } }); it('handles error stack traces correctly', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-stack-trace.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.length).to.equal(1); - expect(session.testResults!.tests[0]!.error!.message).to.include('My error'); - expect(session.testResults!.tests[0]!.error!.stack).to.include('throwErrorC'); - expect(session.testResults!.tests[0]!.error!.stack).to.include('fail-stack-trace-c.js'); - expect(session.errors).to.eql([]); - expect(session.logs).to.eql([]); + assert.equal(session.testResults!.tests.length, 1); + assert.ok(session.testResults!.tests[0]!.error!.message.includes('My error')); + assert.ok(session.testResults!.tests[0]!.error!.stack!.includes('throwErrorC')); + assert.ok( + session.testResults!.tests[0]!.error!.stack!.includes('fail-stack-trace-c.js'), + ); + assert.deepEqual(session.errors, []); + assert.deepEqual(session.logs, []); } }); it('handles string diffs correctly', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-string-diff.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests[0]!.name).to.equal('string diff'); - expect(session.testResults!.tests[0]!.error!.message).to.include( - "expected 'foo' to equal 'bar'", + assert.equal(session.testResults!.tests[0]!.name, 'string diff'); + assert.ok( + session.testResults!.tests[0]!.error!.message.includes("expected 'foo' to equal 'bar'"), ); - expect(session.testResults!.tests[0]!.error!.expected).to.equal('bar'); - expect(session.testResults!.tests[0]!.error!.actual).to.equal('foo'); - expect(session.testResults!.tests.length).to.equal(1); - expect(session.errors).to.eql([]); - expect(session.logs).to.eql([]); + assert.equal(session.testResults!.tests[0]!.error!.expected, 'bar'); + assert.equal(session.testResults!.tests[0]!.error!.actual, 'foo'); + assert.equal(session.testResults!.tests.length, 1); + assert.deepEqual(session.errors, []); + assert.deepEqual(session.logs, []); } }); it('handles syntax errors', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-syntax-error.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.suites.length).to.eql(0); - expect(session.testResults!.tests.length).to.eql(0); - expect(session.errors).to.eql([ERROR_NOT_IMPORTABLE]); + assert.equal(session.testResults!.suites.length, 0); + assert.equal(session.testResults!.tests.length, 0); + assert.deepEqual(session.errors, [ERROR_NOT_IMPORTABLE]); } }); it('handles tests that error with a readonly actual', () => { const sessions = allSessions.filter(s => s.testFile.endsWith('fail-readonly-actual.test.js')); - expect(sessions.length === browserCount).to.equal(true); + assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - expect(session.testResults!.tests.map(t => t.name)).to.eql(['readonly actual']); - expect(session.passed).to.be.false; - expect(session.testResults!.tests![0].error!.message).to.equal( + assert.deepEqual(session.testResults!.tests.map(t => t.name), ['readonly actual']); + assert.equal(session.passed, false); + assert.equal( + session.testResults!.tests![0].error!.message, 'expected { x: {} } to equal null', ); } diff --git a/packages/test-runner-chrome/package.json b/packages/test-runner-chrome/package.json index 4dc77f206..579497faf 100644 --- a/packages/test-runner-chrome/package.json +++ b/packages/test-runner-chrome/package.json @@ -26,8 +26,8 @@ }, "scripts": { "build": "tsc", - "test:node": "mocha test/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test/**/*.test.ts --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\"" }, "files": [ "*.d.ts", diff --git a/packages/test-runner-chrome/test/chromeLauncher.test.ts b/packages/test-runner-chrome/test/chromeLauncher.test.ts index 7e129d103..e714740e9 100644 --- a/packages/test-runner-chrome/test/chromeLauncher.test.ts +++ b/packages/test-runner-chrome/test/chromeLauncher.test.ts @@ -1,9 +1,8 @@ -import { runIntegrationTests } from '../../../integration/test-runner/index.js'; -import { chromeLauncher } from '../src/index.js'; - -describe('test-runner-chrome', function testRunnerChrome() { - this.timeout(20000); +import { describe } from 'node:test'; +import { runIntegrationTests } from '../../../integration/test-runner/index.ts'; +import { chromeLauncher } from '../dist/index.js'; +describe('test-runner-chrome', { timeout: 20000 }, () => { function createConfig() { return { browsers: [chromeLauncher()], diff --git a/packages/test-runner-playwright/package.json b/packages/test-runner-playwright/package.json index d7429b928..18666409f 100644 --- a/packages/test-runner-playwright/package.json +++ b/packages/test-runner-playwright/package.json @@ -26,8 +26,8 @@ }, "scripts": { "build": "tsc", - "test:node": "mocha test/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test/**/*.test.ts --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\"" }, "files": [ "*.d.ts", diff --git a/packages/test-runner-playwright/test/playwrightLauncher.test.ts b/packages/test-runner-playwright/test/playwrightLauncher.test.ts index 37eceac5c..39904c2b0 100644 --- a/packages/test-runner-playwright/test/playwrightLauncher.test.ts +++ b/packages/test-runner-playwright/test/playwrightLauncher.test.ts @@ -1,10 +1,9 @@ import os from 'os'; -import { runIntegrationTests } from '../../../integration/test-runner/index.js'; -import { playwrightLauncher } from '../src/index.js'; - -describe('test-runner-playwright chromium', function testRunnerPlaywright() { - this.timeout(100000); +import { describe } from 'node:test'; +import { runIntegrationTests } from '../../../integration/test-runner/index.ts'; +import { playwrightLauncher } from '../dist/index.js'; +describe('test-runner-playwright chromium', { timeout: 100000 }, () => { function createConfig() { return { browsers: [playwrightLauncher({ product: 'chromium' })] }; } @@ -20,9 +19,7 @@ describe('test-runner-playwright chromium', function testRunnerPlaywright() { }); }); -describe('test-runner-playwright webkit', function testRunnerPlaywright() { - this.timeout(100000); - +describe('test-runner-playwright webkit', { timeout: 100000 }, () => { function createConfig() { return { browsers: [playwrightLauncher({ product: 'webkit' })] }; } @@ -38,11 +35,8 @@ describe('test-runner-playwright webkit', function testRunnerPlaywright() { }); }); -// we don't run all tests in the windows CI if (os.platform() !== 'win32') { - describe('test-runner-playwright firefox', function testRunnerPlaywright() { - this.timeout(100000); - + describe('test-runner-playwright firefox', { timeout: 100000 }, () => { function createConfig() { return { browsers: [playwrightLauncher({ product: 'firefox' })] }; } @@ -59,9 +53,7 @@ if (os.platform() !== 'win32') { }); }); - describe('test-runner-playwright all', function testRunnerPlaywright() { - this.timeout(100000); - + describe('test-runner-playwright all', { timeout: 100000 }, () => { function createConfig() { return { browsers: [ diff --git a/packages/test-runner-puppeteer/package.json b/packages/test-runner-puppeteer/package.json index 088d0262b..373aae812 100644 --- a/packages/test-runner-puppeteer/package.json +++ b/packages/test-runner-puppeteer/package.json @@ -26,8 +26,8 @@ }, "scripts": { "build": "tsc", - "test:node": "mocha test/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test/**/*.test.ts --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\"" }, "files": [ "*.d.ts", diff --git a/packages/test-runner-puppeteer/test/puppeteerLauncher.test.ts b/packages/test-runner-puppeteer/test/puppeteerLauncher.test.ts index 718410a81..f418554f4 100644 --- a/packages/test-runner-puppeteer/test/puppeteerLauncher.test.ts +++ b/packages/test-runner-puppeteer/test/puppeteerLauncher.test.ts @@ -1,9 +1,8 @@ -import { runIntegrationTests } from '../../../integration/test-runner/index.js'; -import { puppeteerLauncher } from '../src/index.js'; - -describe('test-runner-puppeteer', function testRunnerPuppeteer() { - this.timeout(20000); +import { describe } from 'node:test'; +import { runIntegrationTests } from '../../../integration/test-runner/index.ts'; +import { puppeteerLauncher } from '../dist/index.js'; +describe('test-runner-puppeteer', { timeout: 20000 }, () => { function createConfig() { return { browsers: [puppeteerLauncher()], From e842b981af5301303029ab0b4ab509c185817a66 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Wed, 3 Jun 2026 00:09:34 +0300 Subject: [PATCH 2/9] style(test-runner): fix prettier formatting in integration test files Assisted-By: Claude Opus 4.6 (1M context) --- .../test-runner/tests/basic/runBasicTest.ts | 63 ++++++++++++------- .../test-runner/tests/focus/runFocusTest.ts | 11 +++- .../location-change/runLocationChangeTest.ts | 11 +++- .../test-runner/tests/many/runManyTests.ts | 5 +- .../tests/parallel/runParallelTest.ts | 10 ++- .../tests/test-failure/runTestFailureTest.ts | 62 +++++++++++------- 6 files changed, 107 insertions(+), 55 deletions(-) diff --git a/integration/test-runner/tests/basic/runBasicTest.ts b/integration/test-runner/tests/basic/runBasicTest.ts index 4e95f18c1..d50ca5c8f 100644 --- a/integration/test-runner/tests/basic/runBasicTest.ts +++ b/integration/test-runner/tests/basic/runBasicTest.ts @@ -15,12 +15,19 @@ export function runBasicTest( before(async () => { const result = await runTests({ ...config, - files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], + files: [ + ...(config.files ?? []), + resolve(import.meta.dirname, 'browser-tests', '*.test.js'), + ], plugins: [...(config.plugins ?? []), legacyPlugin()], }); allSessions = result.sessions; - assert.equal(allSessions.every(s => s.passed), true, 'All sessions should have passed'); + assert.equal( + allSessions.every(s => s.passed), + true, + 'All sessions should have passed', + ); }); it('passes basic test', () => { @@ -30,7 +37,10 @@ export function runBasicTest( assert.equal(session.testResults!.tests.length, 0); assert.equal(session.testResults!.suites.length, 1); assert.equal(session.testResults!.suites[0].tests.length, 1); - assert.deepEqual(session.testResults!.suites[0].tests.map(t => t.name), ['works']); + assert.deepEqual( + session.testResults!.suites[0].tests.map(t => t.name), + ['works'], + ); } }); @@ -42,15 +52,18 @@ export function runBasicTest( 'Each browser should run js-syntax.test.js', ); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), [ - 'supports object spread', - 'supports async functions', - 'supports exponentiation', - 'supports classes', - 'supports template literals', - 'supports optional chaining', - 'supports nullish coalescing', - ]); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + [ + 'supports object spread', + 'supports async functions', + 'supports exponentiation', + 'supports classes', + 'supports template literals', + 'supports optional chaining', + 'supports nullish coalescing', + ], + ); } }); @@ -62,11 +75,10 @@ export function runBasicTest( 'Each browser should run module-features.test.js', ); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), [ - 'supports static imports', - 'supports dynamic imports', - 'supports import meta', - ]); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['supports static imports', 'supports dynamic imports', 'supports import meta'], + ); } }); @@ -80,13 +92,16 @@ export function runBasicTest( for (const session of sessions) { assert.equal(session.testResults!.tests.length, 0); assert.equal(session.testResults!.suites.length, 1); - assert.deepEqual(session.testResults!.suites[0].tests.map(t => t.name), [ - 'can call setTimeout', - 'can cancel setTimeout', - 'can call and cancel setInterval', - 'can call requestAnimationFrame', - 'can cancel requestAnimationFrame', - ]); + assert.deepEqual( + session.testResults!.suites[0].tests.map(t => t.name), + [ + 'can call setTimeout', + 'can cancel setTimeout', + 'can call and cancel setInterval', + 'can call requestAnimationFrame', + 'can cancel requestAnimationFrame', + ], + ); } }); }); diff --git a/integration/test-runner/tests/focus/runFocusTest.ts b/integration/test-runner/tests/focus/runFocusTest.ts index 3c98f5a0a..e13bdaf54 100644 --- a/integration/test-runner/tests/focus/runFocusTest.ts +++ b/integration/test-runner/tests/focus/runFocusTest.ts @@ -15,14 +15,21 @@ export function runFocusTest( const result = await runTests({ ...config, concurrency: 2, - files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], + files: [ + ...(config.files ?? []), + resolve(import.meta.dirname, 'browser-tests', '*.test.js'), + ], plugins: [...(config.plugins ?? []), legacyPlugin()], }); allSessions = result.sessions; }); it.skip('can run tests with focus, concurrently and sequentially', () => { - assert.equal(allSessions.every(s => s.passed), true, 'All sessions should have passed'); + assert.equal( + allSessions.every(s => s.passed), + true, + 'All sessions should have passed', + ); }); }); } diff --git a/integration/test-runner/tests/location-change/runLocationChangeTest.ts b/integration/test-runner/tests/location-change/runLocationChangeTest.ts index f3b9ca2a1..08bc8922e 100644 --- a/integration/test-runner/tests/location-change/runLocationChangeTest.ts +++ b/integration/test-runner/tests/location-change/runLocationChangeTest.ts @@ -16,7 +16,10 @@ export function runLocationChangeTest( const result = await runTests( { ...config, - files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], + files: [ + ...(config.files ?? []), + resolve(import.meta.dirname, 'browser-tests', '*.test.js'), + ], plugins: [...(config.plugins ?? []), legacyPlugin()], }, undefined, @@ -24,7 +27,11 @@ export function runLocationChangeTest( ); allSessions = result.sessions; - assert.equal(allSessions.every(s => s.passed), false, 'All sessions should have failed'); + assert.equal( + allSessions.every(s => s.passed), + false, + 'All sessions should have failed', + ); }); it('handles tests which assign to window.location.href', () => { diff --git a/integration/test-runner/tests/many/runManyTests.ts b/integration/test-runner/tests/many/runManyTests.ts index 0cb5c68cb..526fbbfeb 100644 --- a/integration/test-runner/tests/many/runManyTests.ts +++ b/integration/test-runner/tests/many/runManyTests.ts @@ -12,7 +12,10 @@ export function runManyTests( await Promise.all([ runTests({ ...config, - files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], + files: [ + ...(config.files ?? []), + resolve(import.meta.dirname, 'browser-tests', '*.test.js'), + ], plugins: [...(config.plugins ?? []), legacyPlugin()], }), ]); diff --git a/integration/test-runner/tests/parallel/runParallelTest.ts b/integration/test-runner/tests/parallel/runParallelTest.ts index dc22f853f..2858975d7 100644 --- a/integration/test-runner/tests/parallel/runParallelTest.ts +++ b/integration/test-runner/tests/parallel/runParallelTest.ts @@ -15,13 +15,19 @@ export function runParallelTest( await Promise.all([ runTests({ ...configA, - files: [...(configA.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], + files: [ + ...(configA.files ?? []), + resolve(import.meta.dirname, 'browser-tests', '*.test.js'), + ], plugins: [...(configA.plugins ?? []), legacyPlugin()], }), runTests({ ...configB, - files: [...(configB.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], + files: [ + ...(configB.files ?? []), + resolve(import.meta.dirname, 'browser-tests', '*.test.js'), + ], plugins: [...(configB.plugins ?? []), legacyPlugin()], }), ]); diff --git a/integration/test-runner/tests/test-failure/runTestFailureTest.ts b/integration/test-runner/tests/test-failure/runTestFailureTest.ts index 5a1d7f900..223f9d97a 100644 --- a/integration/test-runner/tests/test-failure/runTestFailureTest.ts +++ b/integration/test-runner/tests/test-failure/runTestFailureTest.ts @@ -35,7 +35,10 @@ export function runTestFailureTest( const result = await runTests( { ...config, - files: [...(config.files ?? []), resolve(import.meta.dirname, 'browser-tests', '*.test.js')], + files: [ + ...(config.files ?? []), + resolve(import.meta.dirname, 'browser-tests', '*.test.js'), + ], plugins: [...(config.plugins ?? []), legacyPlugin()], }, undefined, @@ -43,7 +46,11 @@ export function runTestFailureTest( ); allSessions = result.sessions; - assert.equal(allSessions.every(s => s.passed), false, 'All sessions should have failed'); + assert.equal( + allSessions.every(s => s.passed), + false, + 'All sessions should have failed', + ); }); it('handles tests with 404 imports', () => { @@ -65,7 +72,10 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-circular-error.test.js')); assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), ['bad predicate']); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['bad predicate'], + ); assert.equal(session.passed, false); assert.equal( session.testResults!.tests![0].error!.message, @@ -78,10 +88,10 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-after-each.test.js')); assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), [ - 'true is true', - 'true is really true', - ]); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['true is true', 'true is really true'], + ); assert.equal(session.errors.length, 1); assert.ok(session.errors[0].message.includes('error thrown in afterEach hook')); assert.ok( @@ -97,10 +107,10 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-after.test.js')); assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), [ - 'true is true', - 'true is really true', - ]); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['true is true', 'true is really true'], + ); assert.equal(session.errors.length, 1); assert.ok(session.errors[0].message.includes('error thrown in after hook')); assert.ok( @@ -116,10 +126,10 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-before-each.test.js')); assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), [ - 'true is true', - 'true is really true', - ]); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['true is true', 'true is really true'], + ); assert.equal(session.errors.length, 1); assert.ok(session.errors[0].message.includes('error thrown in beforeEach hook')); assert.ok( @@ -135,10 +145,10 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-before.test.js')); assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), [ - 'true is true', - 'true is really true', - ]); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['true is true', 'true is really true'], + ); assert.equal(session.errors.length, 1); assert.ok(session.errors[0].message.includes('error thrown in before hook')); assert.ok( @@ -154,7 +164,10 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-custom-error.test.js')); assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), ['custom error']); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['custom error'], + ); assert.ok(session.testResults!.tests[0].error!.message.includes('a custom error thrown')); assert.ok( session.testResults!.tests[0].error!.stack!.includes( @@ -186,9 +199,7 @@ export function runTestFailureTest( assert.equal(session.testResults!.tests.length, 1); assert.ok(session.testResults!.tests[0]!.error!.message.includes('My error')); assert.ok(session.testResults!.tests[0]!.error!.stack!.includes('throwErrorC')); - assert.ok( - session.testResults!.tests[0]!.error!.stack!.includes('fail-stack-trace-c.js'), - ); + assert.ok(session.testResults!.tests[0]!.error!.stack!.includes('fail-stack-trace-c.js')); assert.deepEqual(session.errors, []); assert.deepEqual(session.logs, []); } @@ -224,7 +235,10 @@ export function runTestFailureTest( const sessions = allSessions.filter(s => s.testFile.endsWith('fail-readonly-actual.test.js')); assert.equal(sessions.length === browserCount, true); for (const session of sessions) { - assert.deepEqual(session.testResults!.tests.map(t => t.name), ['readonly actual']); + assert.deepEqual( + session.testResults!.tests.map(t => t.name), + ['readonly actual'], + ); assert.equal(session.passed, false); assert.equal( session.testResults!.tests![0].error!.message, From c94513bd34d08e682295e9da1448af73747f713c Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Wed, 3 Jun 2026 00:11:49 +0300 Subject: [PATCH 3/9] fix(test-runner): remove unused describe import from integration index Assisted-By: Claude Opus 4.6 (1M context) --- integration/test-runner/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/integration/test-runner/index.ts b/integration/test-runner/index.ts index 8cdb7a95e..454473244 100644 --- a/integration/test-runner/index.ts +++ b/integration/test-runner/index.ts @@ -1,4 +1,3 @@ -import { describe } from 'node:test'; import type { BrowserLauncher, TestRunnerCoreConfig } from '@web/test-runner-core'; import { runBasicTest } from './tests/basic/runBasicTest.ts'; import { runConfigGroupsTest } from './tests/config-groups/runConfigGroupsTest.ts'; From 33f0fe364c8fdaac341753fa57cd666a2da81fd0 Mon Sep 17 00:00:00 2001 From: Benny Powers Date: Tue, 9 Jun 2026 22:35:30 +0300 Subject: [PATCH 4/9] fix(test-runner): use expectIncludes for better assertion errors in integration tests Add local expectIncludes helper to replace assert.ok(x.includes(y)) for better error messages on failure. Assisted-By: Claude Opus 4.6 (1M context) --- .../location-change/runLocationChangeTest.ts | 10 ++++++- .../tests/test-failure/runTestFailureTest.ts | 26 ++++++++++++------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/integration/test-runner/tests/location-change/runLocationChangeTest.ts b/integration/test-runner/tests/location-change/runLocationChangeTest.ts index 08bc8922e..0f7fd21d6 100644 --- a/integration/test-runner/tests/location-change/runLocationChangeTest.ts +++ b/integration/test-runner/tests/location-change/runLocationChangeTest.ts @@ -5,6 +5,14 @@ import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; +function expectIncludes(actual: string, expected: string) { + if (!actual.includes(expected)) { + throw new Error( + `Expected substring not found.\n\nExpected:\n${expected}\n\nActual:\n${actual}`, + ); + } +} + export function runLocationChangeTest( config: Partial & { browsers: BrowserLauncher[] }, ) { @@ -83,7 +91,7 @@ export function runLocationChangeTest( 'Tests were interrupted because the page navigated to', ), ); - assert.ok(session.errors[0].message.includes('/new-page/')); + expectIncludes(session.errors[0].message, '/new-page/'); assert.ok( session.errors[0].message.includes( 'This can happen when clicking a link, submitting a form or interacting with window.location.', diff --git a/integration/test-runner/tests/test-failure/runTestFailureTest.ts b/integration/test-runner/tests/test-failure/runTestFailureTest.ts index 223f9d97a..f62b24921 100644 --- a/integration/test-runner/tests/test-failure/runTestFailureTest.ts +++ b/integration/test-runner/tests/test-failure/runTestFailureTest.ts @@ -5,6 +5,14 @@ import { runTests } from '@web/test-runner-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve, sep } from 'path'; +function expectIncludes(actual: string, expected: string) { + if (!actual.includes(expected)) { + throw new Error( + `Expected substring not found.\n\nExpected:\n${expected}\n\nActual:\n${actual}`, + ); + } +} + const ERROR_NOT_IMPORTABLE = { message: 'Could not import your test module. Check the browser logs or open the browser in debug mode for more information.', @@ -93,7 +101,7 @@ export function runTestFailureTest( ['true is true', 'true is really true'], ); assert.equal(session.errors.length, 1); - assert.ok(session.errors[0].message.includes('error thrown in afterEach hook')); + expectIncludes(session.errors[0].message, 'error thrown in afterEach hook'); assert.ok( session.errors[0].stack!.includes( `test-failure${sep}browser-tests${sep}fail-after-each.test.js`, @@ -112,7 +120,7 @@ export function runTestFailureTest( ['true is true', 'true is really true'], ); assert.equal(session.errors.length, 1); - assert.ok(session.errors[0].message.includes('error thrown in after hook')); + expectIncludes(session.errors[0].message, 'error thrown in after hook'); assert.ok( session.errors[0].stack!.includes( `test-failure${sep}browser-tests${sep}fail-after.test.js`, @@ -131,7 +139,7 @@ export function runTestFailureTest( ['true is true', 'true is really true'], ); assert.equal(session.errors.length, 1); - assert.ok(session.errors[0].message.includes('error thrown in beforeEach hook')); + expectIncludes(session.errors[0].message, 'error thrown in beforeEach hook'); assert.ok( session.errors[0].stack!.includes( `test-failure${sep}browser-tests${sep}fail-before-each.test.js`, @@ -150,7 +158,7 @@ export function runTestFailureTest( ['true is true', 'true is really true'], ); assert.equal(session.errors.length, 1); - assert.ok(session.errors[0].message.includes('error thrown in before hook')); + expectIncludes(session.errors[0].message, 'error thrown in before hook'); assert.ok( session.errors[0].stack!.includes( `test-failure${sep}browser-tests${sep}fail-before.test.js`, @@ -168,7 +176,7 @@ export function runTestFailureTest( session.testResults!.tests.map(t => t.name), ['custom error'], ); - assert.ok(session.testResults!.tests[0].error!.message.includes('a custom error thrown')); + expectIncludes(session.testResults!.tests[0].error!.message, 'a custom error thrown'); assert.ok( session.testResults!.tests[0].error!.stack!.includes( `browser-tests${sep}fail-custom-error.test.js`, @@ -188,7 +196,7 @@ export function runTestFailureTest( assert.equal(session.testResults!.suites.length, 0); assert.equal(session.testResults!.tests.length, 0); assert.deepEqual(session.errors, [ERROR_NOT_IMPORTABLE]); - assert.ok((session.logs[0][0] as any).includes('This is thrown before running tests')); + expectIncludes(session.logs[0][0] as string, 'This is thrown before running tests'); } }); @@ -197,9 +205,9 @@ export function runTestFailureTest( assert.equal(sessions.length === browserCount, true); for (const session of sessions) { assert.equal(session.testResults!.tests.length, 1); - assert.ok(session.testResults!.tests[0]!.error!.message.includes('My error')); - assert.ok(session.testResults!.tests[0]!.error!.stack!.includes('throwErrorC')); - assert.ok(session.testResults!.tests[0]!.error!.stack!.includes('fail-stack-trace-c.js')); + expectIncludes(session.testResults!.tests[0]!.error!.message, 'My error'); + expectIncludes(session.testResults!.tests[0]!.error!.stack!, 'throwErrorC'); + expectIncludes(session.testResults!.tests[0]!.error!.stack!, 'fail-stack-trace-c.js'); assert.deepEqual(session.errors, []); assert.deepEqual(session.logs, []); } From 7525b847d68edd95a09a8e2a4752cf092d691a6c Mon Sep 17 00:00:00 2001 From: Mikhail Bashkirov Date: Wed, 17 Jun 2026 15:17:45 +0200 Subject: [PATCH 5/9] test: reuse existing expectIncludes --- .../location-change/runLocationChangeTest.ts | 37 +++++++------------ .../tests/test-failure/runTestFailureTest.ts | 9 +---- 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/integration/test-runner/tests/location-change/runLocationChangeTest.ts b/integration/test-runner/tests/location-change/runLocationChangeTest.ts index 0f7fd21d6..8991b2c85 100644 --- a/integration/test-runner/tests/location-change/runLocationChangeTest.ts +++ b/integration/test-runner/tests/location-change/runLocationChangeTest.ts @@ -2,17 +2,10 @@ import assert from 'node:assert/strict'; import { describe, before, it } from 'node:test'; import type { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; +import { expectIncludes } from '@web/dev-server-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve } from 'path'; -function expectIncludes(actual: string, expected: string) { - if (!actual.includes(expected)) { - throw new Error( - `Expected substring not found.\n\nExpected:\n${expected}\n\nActual:\n${actual}`, - ); - } -} - export function runLocationChangeTest( config: Partial & { browsers: BrowserLauncher[] }, ) { @@ -49,15 +42,13 @@ export function runLocationChangeTest( assert.equal(session.testResults, undefined); assert.deepEqual(session.logs, []); assert.equal(session.errors.length, 1); - assert.ok( - session.errors[0].message.includes( - 'Tests were interrupted because the page navigated to', - ), + expectIncludes( + session.errors[0].message, + 'Tests were interrupted because the page navigated to', ); - assert.ok( - session.errors[0].message.includes( - 'This can happen when clicking a link, submitting a form or interacting with window.location.', - ), + expectIncludes( + session.errors[0].message, + 'This can happen when clicking a link, submitting a form or interacting with window.location.', ); } }); @@ -86,16 +77,14 @@ export function runLocationChangeTest( assert.equal(session.testResults, undefined); assert.deepEqual(session.logs, []); assert.equal(session.errors.length, 1); - assert.ok( - session.errors[0].message.includes( - 'Tests were interrupted because the page navigated to', - ), + expectIncludes( + session.errors[0].message, + 'Tests were interrupted because the page navigated to', ); expectIncludes(session.errors[0].message, '/new-page/'); - assert.ok( - session.errors[0].message.includes( - 'This can happen when clicking a link, submitting a form or interacting with window.location.', - ), + expectIncludes( + session.errors[0].message, + 'This can happen when clicking a link, submitting a form or interacting with window.location.', ); } }); diff --git a/integration/test-runner/tests/test-failure/runTestFailureTest.ts b/integration/test-runner/tests/test-failure/runTestFailureTest.ts index f62b24921..430c9e2c2 100644 --- a/integration/test-runner/tests/test-failure/runTestFailureTest.ts +++ b/integration/test-runner/tests/test-failure/runTestFailureTest.ts @@ -2,17 +2,10 @@ import assert from 'node:assert/strict'; import { describe, before, it } from 'node:test'; import type { BrowserLauncher, TestRunnerCoreConfig, TestSession } from '@web/test-runner-core'; import { runTests } from '@web/test-runner-core/test-helpers'; +import { expectIncludes } from '@web/dev-server-core/test-helpers'; import { legacyPlugin } from '@web/dev-server-legacy'; import { resolve, sep } from 'path'; -function expectIncludes(actual: string, expected: string) { - if (!actual.includes(expected)) { - throw new Error( - `Expected substring not found.\n\nExpected:\n${expected}\n\nActual:\n${actual}`, - ); - } -} - const ERROR_NOT_IMPORTABLE = { message: 'Could not import your test module. Check the browser logs or open the browser in debug mode for more information.', From ccfed622451836a149293de4a6abfc7784443643 Mon Sep 17 00:00:00 2001 From: Mikhail Bashkirov Date: Wed, 17 Jun 2026 15:27:32 +0200 Subject: [PATCH 6/9] test: remove unused test scripts --- integration/test-runner/package.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/integration/test-runner/package.json b/integration/test-runner/package.json index a7c7e0e26..0122a2bb4 100644 --- a/integration/test-runner/package.json +++ b/integration/test-runner/package.json @@ -15,11 +15,7 @@ "author": "modern-web", "homepage": "https://github.com/modernweb-dev/web/tree/master/packages/test-runner-integration-tests", "main": "index.js", - "scripts": { - "test": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", - "test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", - "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\"" - }, + "scripts": {}, "dependencies": { "@web/dev-server-legacy": "^2.1.0", "@web/test-runner-core": "^0.13.4" From 6cd7efa255a281d8c36aa0b7efd3ccbecf257448 Mon Sep 17 00:00:00 2001 From: Mikhail Bashkirov Date: Wed, 17 Jun 2026 16:09:05 +0200 Subject: [PATCH 7/9] test: migrate remaining test-runner integrations to node:test --- packages/test-runner-browserstack/package.json | 4 ++-- .../test-remote/browserstackLauncher.test.ts | 9 ++++----- packages/test-runner-saucelabs/package.json | 4 ++-- .../test-remote/saucelabsLauncher.test.ts | 9 ++++----- packages/test-runner-selenium/package.json | 4 ++-- .../test/seleniumLauncher.test.ts | 13 ++++++------- packages/test-runner-webdriver/package.json | 4 ++-- .../test/webdriverLauncher.test.ts | 9 ++++----- 8 files changed, 26 insertions(+), 30 deletions(-) diff --git a/packages/test-runner-browserstack/package.json b/packages/test-runner-browserstack/package.json index ff742f0ec..d5d126601 100644 --- a/packages/test-runner-browserstack/package.json +++ b/packages/test-runner-browserstack/package.json @@ -26,8 +26,8 @@ }, "scripts": { "build": "tsc", - "test": "mocha test-remote/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test-remote/**/*.test.ts --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit \"test-remote/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test-remote/**/*.test.ts\"" }, "files": [ "*.d.ts", diff --git a/packages/test-runner-browserstack/test-remote/browserstackLauncher.test.ts b/packages/test-runner-browserstack/test-remote/browserstackLauncher.test.ts index 7417149cc..f88f72124 100644 --- a/packages/test-runner-browserstack/test-remote/browserstackLauncher.test.ts +++ b/packages/test-runner-browserstack/test-remote/browserstackLauncher.test.ts @@ -1,5 +1,6 @@ -import { runIntegrationTests } from '../../../integration/test-runner/index.js'; -import { browserstackLauncher } from '../src/index.js'; +import { describe } from 'node:test'; +import { runIntegrationTests } from '../../../integration/test-runner/index.ts'; +import { browserstackLauncher } from '../dist/index.js'; if (!process.env.BROWSER_STACK_USERNAME) { throw new Error('Missing env var BROWSER_STACK_USERNAME'); @@ -20,9 +21,7 @@ const sharedCapabilities = { }`, }; -describe('test-runner-browserstack', function () { - this.timeout(200000); - +describe('test-runner-browserstack', { timeout: 200000 }, () => { function createConfig() { return { browserStartTimeout: 1000 * 60 * 2, diff --git a/packages/test-runner-saucelabs/package.json b/packages/test-runner-saucelabs/package.json index c92b74b78..edfefaaf3 100644 --- a/packages/test-runner-saucelabs/package.json +++ b/packages/test-runner-saucelabs/package.json @@ -26,8 +26,8 @@ }, "scripts": { "build": "tsc", - "test": "mocha test-remote/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test-remote/**/*.test.ts --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit \"test-remote/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test-remote/**/*.test.ts\"" }, "files": [ "*.d.ts", diff --git a/packages/test-runner-saucelabs/test-remote/saucelabsLauncher.test.ts b/packages/test-runner-saucelabs/test-remote/saucelabsLauncher.test.ts index a67b8fe99..3ccd4c2c4 100644 --- a/packages/test-runner-saucelabs/test-remote/saucelabsLauncher.test.ts +++ b/packages/test-runner-saucelabs/test-remote/saucelabsLauncher.test.ts @@ -1,5 +1,6 @@ -import { runIntegrationTests } from '../../../integration/test-runner/index.js'; -import { createSauceLabsLauncher } from '../src/index.js'; +import { describe } from 'node:test'; +import { runIntegrationTests } from '../../../integration/test-runner/index.ts'; +import { createSauceLabsLauncher } from '../dist/index.js'; if (!process.env.SAUCE_USERNAME) { throw new Error('Missing env var SAUCE_USERNAME'); @@ -24,9 +25,7 @@ const sauceLabsLauncher = createSauceLabsLauncher( sauceLabsCapabilities, ); -describe('test-runner-saucelabs', function () { - this.timeout(400000); - +describe('test-runner-saucelabs', { timeout: 400000 }, () => { function createConfig() { return { browserStartTimeout: 1000 * 60 * 2, diff --git a/packages/test-runner-selenium/package.json b/packages/test-runner-selenium/package.json index 8c4f346c3..66908846a 100644 --- a/packages/test-runner-selenium/package.json +++ b/packages/test-runner-selenium/package.json @@ -26,8 +26,8 @@ }, "scripts": { "build": "tsc", - "test": "mocha test/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test/**/*.test.ts --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\"" }, "files": [ "*.d.ts", diff --git a/packages/test-runner-selenium/test/seleniumLauncher.test.ts b/packages/test-runner-selenium/test/seleniumLauncher.test.ts index 23ed8b27f..12b4f893b 100644 --- a/packages/test-runner-selenium/test/seleniumLauncher.test.ts +++ b/packages/test-runner-selenium/test/seleniumLauncher.test.ts @@ -1,9 +1,10 @@ +import { describe, before, after } from 'node:test'; import selenium from 'selenium-standalone'; import { Builder } from 'selenium-webdriver'; -import { Options as ChromeOptions } from 'selenium-webdriver/chrome'; -import { Options as FirefoxOptions } from 'selenium-webdriver/firefox'; -import { runIntegrationTests } from '../../../integration/test-runner'; -import { seleniumLauncher } from '../src/seleniumLauncher'; +import { Options as ChromeOptions } from 'selenium-webdriver/chrome.js'; +import { Options as FirefoxOptions } from 'selenium-webdriver/firefox.js'; +import { runIntegrationTests } from '../../../integration/test-runner/index.ts'; +import { seleniumLauncher } from '../dist/index.js'; async function startSeleniumServer() { let server: selenium.ChildProcess; @@ -39,9 +40,7 @@ async function startSeleniumServer() { let seleniumServer: selenium.ChildProcess; -describe('test-runner-selenium', function testRunnerSelenium() { - this.timeout(50000); - +describe('test-runner-selenium', { timeout: 50000 }, () => { before(async function () { seleniumServer = await startSeleniumServer(); }); diff --git a/packages/test-runner-webdriver/package.json b/packages/test-runner-webdriver/package.json index e305139bc..9f46ac946 100644 --- a/packages/test-runner-webdriver/package.json +++ b/packages/test-runner-webdriver/package.json @@ -26,8 +26,8 @@ }, "scripts": { "build": "tsc", - "test": "mocha test/**/*.test.ts --require ts-node/register --reporter dot", - "test:watch": "mocha test/**/*.test.ts --require ts-node/register --watch --watch-files src,test" + "test:node": "node --experimental-strip-types --test --test-force-exit \"test/**/*.test.ts\"", + "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test/**/*.test.ts\"" }, "files": [ "*.d.ts", diff --git a/packages/test-runner-webdriver/test/webdriverLauncher.test.ts b/packages/test-runner-webdriver/test/webdriverLauncher.test.ts index ac0e125a0..0f501751a 100644 --- a/packages/test-runner-webdriver/test/webdriverLauncher.test.ts +++ b/packages/test-runner-webdriver/test/webdriverLauncher.test.ts @@ -1,6 +1,7 @@ +import { describe, before, after } from 'node:test'; import selenium from 'selenium-standalone'; -import { runIntegrationTests } from '../../../integration/test-runner'; -import { webdriverLauncher } from '../src/webdriverLauncher'; +import { runIntegrationTests } from '../../../integration/test-runner/index.ts'; +import { webdriverLauncher } from '../dist/index.js'; async function startSeleniumServer() { let server; @@ -34,9 +35,7 @@ async function startSeleniumServer() { let seleniumServer: selenium.ChildProcess; -describe('test-runner-webdriver', function testRunnerWebdriver() { - this.timeout(50000); - +describe('test-runner-webdriver', { timeout: 50000 }, () => { before(async function () { seleniumServer = await startSeleniumServer(); }); From f2a68f0cb37cf733ef276560b887024e14c384b3 Mon Sep 17 00:00:00 2001 From: Mikhail Bashkirov Date: Wed, 17 Jun 2026 16:21:03 +0200 Subject: [PATCH 8/9] test: disable again tests for browserstack and saucelabs --- packages/test-runner-browserstack/package.json | 2 +- packages/test-runner-saucelabs/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/test-runner-browserstack/package.json b/packages/test-runner-browserstack/package.json index d5d126601..1341f9cb9 100644 --- a/packages/test-runner-browserstack/package.json +++ b/packages/test-runner-browserstack/package.json @@ -26,7 +26,7 @@ }, "scripts": { "build": "tsc", - "test:node": "node --experimental-strip-types --test --test-force-exit \"test-remote/**/*.test.ts\"", + "test": "node --experimental-strip-types --test --test-force-exit \"test-remote/**/*.test.ts\"", "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test-remote/**/*.test.ts\"" }, "files": [ diff --git a/packages/test-runner-saucelabs/package.json b/packages/test-runner-saucelabs/package.json index edfefaaf3..411f0269b 100644 --- a/packages/test-runner-saucelabs/package.json +++ b/packages/test-runner-saucelabs/package.json @@ -26,7 +26,7 @@ }, "scripts": { "build": "tsc", - "test:node": "node --experimental-strip-types --test --test-force-exit \"test-remote/**/*.test.ts\"", + "test": "node --experimental-strip-types --test --test-force-exit \"test-remote/**/*.test.ts\"", "test:watch": "node --experimental-strip-types --test --test-force-exit --watch \"test-remote/**/*.test.ts\"" }, "files": [ From 48d4ef98ba16760f5ad7794a51b3d9e19149b3f7 Mon Sep 17 00:00:00 2001 From: Mikhail Bashkirov Date: Wed, 17 Jun 2026 16:42:35 +0200 Subject: [PATCH 9/9] test: install Selenium dependencies --- .github/workflows/verify-node.yml | 6 + package-lock.json | 809 ++++++++++++++++---- packages/test-runner-selenium/package.json | 4 +- packages/test-runner-webdriver/package.json | 4 +- 4 files changed, 688 insertions(+), 135 deletions(-) diff --git a/.github/workflows/verify-node.yml b/.github/workflows/verify-node.yml index 8be272e5d..a767d5b0e 100644 --- a/.github/workflows/verify-node.yml +++ b/.github/workflows/verify-node.yml @@ -54,6 +54,9 @@ jobs: - name: Install Playwright dependencies run: npx playwright install --with-deps + - name: Install Selenium dependencies + run: npx selenium-standalone install + - name: Test run: npm run test:node env: @@ -96,6 +99,9 @@ jobs: - name: Install Playwright dependencies run: npx playwright install --with-deps + - name: Install Selenium dependencies + run: npx selenium-standalone install + - name: Test run: npm run test:node env: diff --git a/package-lock.json b/package-lock.json index be4e6c73b..fe62b2b9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6096,9 +6096,9 @@ } }, "node_modules/@types/selenium-standalone": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@types/selenium-standalone/-/selenium-standalone-7.0.1.tgz", - "integrity": "sha512-zbKenL0fAXzPyiOaaFMrvFdMNhj5BgNJQq8bxiZfwQD9ID2J8bUG5xbcS3tQtlzIX/62z9nG5Vo45oaHWTbvbw==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/selenium-standalone/-/selenium-standalone-7.0.4.tgz", + "integrity": "sha512-FDBK9ZiFHWL6AI2E+cXa/UsEnN2PjcGOV0KGONChf3OVyJVtfIwzZUgaBVGHbOmaAX6KZ/96OgcaALrah8ATTg==", "dev": true, "license": "MIT", "dependencies": { @@ -7094,6 +7094,20 @@ "node": ">= 14" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.15.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", @@ -9865,6 +9879,16 @@ "dev": true, "license": "MIT" }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -10302,6 +10326,16 @@ "node": ">=0.10.0" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/cli-boxes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", @@ -11326,6 +11360,16 @@ "node": ">= 8" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, "node_modules/crypto-random-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", @@ -14138,6 +14182,107 @@ "node": ">= 0.6" } }, + "node_modules/find-process": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.7.tgz", + "integrity": "sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "debug": "^4.1.1" + }, + "bin": { + "find-process": "bin/find-process.js" + } + }, + "node_modules/find-process/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/find-process/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/find-process/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/find-process/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/find-process/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/find-process/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/find-process/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-replace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", @@ -14164,6 +14309,121 @@ "node": ">=8" } }, + "node_modules/fkill": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/fkill/-/fkill-7.2.1.tgz", + "integrity": "sha512-eN9cmsIlRdq06wu3m01OOEgQf5Xh/M7REm0jfZ4eL3V3XisjXzfRq3iyqtKS+FhO6wB36FvWRiRGdeSx5KpLAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.1.0", + "arrify": "^2.0.1", + "execa": "^5.0.0", + "pid-port": "^0.1.0", + "process-exists": "^4.0.0", + "ps-list": "^7.2.0", + "taskkill": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fkill/node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/fkill/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fkill/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/fkill/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fkill/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fkill/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fkill/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -19882,6 +20142,25 @@ "node": ">=0.10.0" } }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/md5/node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true, + "license": "MIT" + }, "node_modules/mdast-comment-marker": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/mdast-comment-marker/-/mdast-comment-marker-2.1.2.tgz", @@ -23375,30 +23654,129 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pidtree": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "node_modules/pid-port": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pid-port/-/pid-port-0.1.1.tgz", + "integrity": "sha512-boqPJtSgZC6KOgXKNPC+/XR3xwVtpOtaLa7JLcdf8jfVe0ZM2TwllBXxxLUO8GQbOLJ4/hEtf2+L1QCKbaoHUg==", "dev": true, "license": "MIT", - "bin": { - "pidtree": "bin/pidtree.js" + "dependencies": { + "execa": "^5.0.0" }, "engines": { - "node": ">=0.10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "node_modules/pid-port/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pixelmatch": { + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/pid-port/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/pid-port/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pid-port/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pid-port/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pid-port/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pixelmatch": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz", "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==", @@ -24330,6 +24708,32 @@ "node": ">= 0.6.0" } }, + "node_modules/process-exists": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/process-exists/-/process-exists-4.1.0.tgz", + "integrity": "sha512-BBJoiorUKoP2AuM5q/yKwIfT1YWRHsaxjW+Ayu9erLhqKOfnXzzVVML0XTYoQZuI1YvcWKmc1dh06DEy4+KzfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ps-list": "^6.3.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process-exists/node_modules/ps-list": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ps-list/-/ps-list-6.3.0.tgz", + "integrity": "sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -24446,6 +24850,19 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "license": "MIT" }, + "node_modules/ps-list": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ps-list/-/ps-list-7.2.0.tgz", + "integrity": "sha512-v4Bl6I3f2kJfr5o80ShABNHAokIgY+wFDTQfE+X3zWYgSGQOCBeYptLZUpoOALBqO5EawmDN/tjTldJesd0ujQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ps-tree": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", @@ -28645,33 +29062,37 @@ } }, "node_modules/selenium-standalone": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/selenium-standalone/-/selenium-standalone-8.3.0.tgz", - "integrity": "sha512-cQVWQGxumvPnyzFNtzFtBfDCbqBsdEnwiOwRyrAzeUqf5ltAp3Z3+2f6asSFbLUQJs2sFuF6PsEyNA+eOzXKxg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/selenium-standalone/-/selenium-standalone-10.0.2.tgz", + "integrity": "sha512-JoFFVbCijsSHtAD9kJa4el0uT5hszL/2Z72PcXnXQLhfUUQdMTe25V3O6Dk13RPA3s0CKQN9GZoMk+rPg0+5+A==", "dev": true, "license": "MIT", "dependencies": { - "commander": "^10.0.0", + "commander": "^8.3.0", "cross-spawn": "^7.0.3", "debug": "^4.3.1", - "fs-extra": "^10.0.0", - "got": "^11.8.2", + "execa": "^5.1.1", + "find-process": "1.4.7", + "fkill": "^7.2.1", + "got": "^11.8.6", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", "is-port-reachable": "^3.0.0", "lodash.mapvalues": "^4.6.0", "lodash.merge": "^4.6.2", + "md5": "^2.3.0", "minimist": "^1.2.5", "mkdirp": "^2.1.3", "progress": "2.0.3", - "tar-stream": "3.0.0", + "tar-stream": "3.1.7", "which": "^2.0.2", - "yauzl": "^2.10.0" + "yauzl": "^3.1.2" }, "bin": { "selenium-standalone": "bin/selenium-standalone" }, "engines": { - "node": ">=12.0.0", - "npm": ">=6.0.0" + "node": ">=14" } }, "node_modules/selenium-standalone/node_modules/@sindresorhus/is": { @@ -28700,43 +29121,6 @@ "node": ">=10" } }, - "node_modules/selenium-standalone/node_modules/bl": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.3.tgz", - "integrity": "sha512-ZmReEQkPP4zOjCHVzGpXYLvf95/HnvwsNZ1sh2dhoy6OxqX9Sl3JF7UmoKXlXE40AjldnWlsSxvqDiDrgSCJDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^4.2.0" - } - }, - "node_modules/selenium-standalone/node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/selenium-standalone/node_modules/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -28767,13 +29151,13 @@ } }, "node_modules/selenium-standalone/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, "license": "MIT", "engines": { - "node": ">=14" + "node": ">= 12" } }, "node_modules/selenium-standalone/node_modules/decompress-response": { @@ -28802,19 +29186,41 @@ "node": ">=10" } }, - "node_modules/selenium-standalone/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "node_modules/selenium-standalone/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/selenium-standalone/node_modules/execa/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/selenium-standalone/node_modules/get-stream": { @@ -28873,6 +29279,16 @@ "node": ">=10.19.0" } }, + "node_modules/selenium-standalone/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, "node_modules/selenium-standalone/node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -28880,19 +29296,6 @@ "dev": true, "license": "MIT" }, - "node_modules/selenium-standalone/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/selenium-standalone/node_modules/keyv": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", @@ -28913,6 +29316,16 @@ "node": ">=8" } }, + "node_modules/selenium-standalone/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/selenium-standalone/node_modules/mimic-response": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", @@ -28955,31 +29368,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/selenium-standalone/node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "node_modules/selenium-standalone/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/selenium-standalone/node_modules/readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "node_modules/selenium-standalone/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/selenium-standalone/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/selenium-standalone/node_modules/responselike": { @@ -28995,36 +29420,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/selenium-standalone/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/selenium-standalone/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" + "engines": { + "node": ">=6" } }, - "node_modules/selenium-standalone/node_modules/tar-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.0.0.tgz", - "integrity": "sha512-O6OfUKBbQOqAhh6owTWmA730J/yZCYcpmZ1DBj2YX51ZQrt7d7NgzrR+CnO9wP6nt/viWZW2XeXLavX3/ZEbEg==", + "node_modules/selenium-standalone/node_modules/yauzl": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.4.0.tgz", + "integrity": "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw==", "dev": true, "license": "MIT", "dependencies": { - "b4a": "^1.6.1", - "bl": "^6.0.0", - "streamx": "^2.12.5" - } - }, - "node_modules/selenium-standalone/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "license": "MIT", + "pend": "~1.2.0" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=12" } }, "node_modules/selenium-webdriver": { @@ -30851,6 +31267,137 @@ "streamx": "^2.15.0" } }, + "node_modules/taskkill": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/taskkill/-/taskkill-3.1.0.tgz", + "integrity": "sha512-5KcOFzPvd1nGFVrmB7H4+QAWVjYOf//+QTbOj0GpXbqtqbKGWVczG+rq6VhXAtdtlKLTs16NAmHRyF5vbggQ2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^2.0.1", + "execa": "^3.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/taskkill/node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/taskkill/node_modules/execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": "^8.12.0 || >=9.7.0" + } + }, + "node_modules/taskkill/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/taskkill/node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/taskkill/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/taskkill/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/taskkill/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/taskkill/node_modules/p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/taskkill/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/temp-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", @@ -38601,9 +39148,9 @@ "selenium-webdriver": "^4.0.0" }, "devDependencies": { - "@types/selenium-standalone": "^7.0.1", + "@types/selenium-standalone": "^7.0.4", "@types/selenium-webdriver": "^4.0.11", - "selenium-standalone": "^8.0.4" + "selenium-standalone": "^10.0.2" }, "engines": { "node": ">=18.0.0" @@ -38654,8 +39201,8 @@ "webdriverio": "^9.0.0" }, "devDependencies": { - "@types/selenium-standalone": "^7.0.1", - "selenium-standalone": "^8.0.4" + "@types/selenium-standalone": "^7.0.4", + "selenium-standalone": "^10.0.2" }, "engines": { "node": ">=18.0.0" diff --git a/packages/test-runner-selenium/package.json b/packages/test-runner-selenium/package.json index 66908846a..b47f3d764 100644 --- a/packages/test-runner-selenium/package.json +++ b/packages/test-runner-selenium/package.json @@ -51,8 +51,8 @@ "selenium-webdriver": "^4.0.0" }, "devDependencies": { - "@types/selenium-standalone": "^7.0.1", + "@types/selenium-standalone": "^7.0.4", "@types/selenium-webdriver": "^4.0.11", - "selenium-standalone": "^8.0.4" + "selenium-standalone": "^10.0.2" } } diff --git a/packages/test-runner-webdriver/package.json b/packages/test-runner-webdriver/package.json index 9f46ac946..29f7d72b0 100644 --- a/packages/test-runner-webdriver/package.json +++ b/packages/test-runner-webdriver/package.json @@ -52,7 +52,7 @@ "webdriverio": "^9.0.0" }, "devDependencies": { - "@types/selenium-standalone": "^7.0.1", - "selenium-standalone": "^8.0.4" + "@types/selenium-standalone": "^7.0.4", + "selenium-standalone": "^10.0.2" } }