diff --git a/packages/test-runner-junit-reporter/package.json b/packages/test-runner-junit-reporter/package.json
index 266337955e..b0a49e66a9 100644
--- a/packages/test-runner-junit-reporter/package.json
+++ b/packages/test-runner-junit-reporter/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 --reporter dot"
+    "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-junit-reporter/test/fixtures/multiple/expected.xml b/packages/test-runner-junit-reporter/test/fixtures/multiple/expected.xml
index 13af3840be..560e5fc9df 100644
--- a/packages/test-runner-junit-reporter/test/fixtures/multiple/expected.xml
+++ b/packages/test-runner-junit-reporter/test/fixtures/multiple/expected.xml
@@ -1,28 +1,28 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuites>
-  <testsuite name="Chrome_puppeteer_/packages/test-runner-junit-reporter/test/fixtures/multiple/nested-test.js" id="0" tests="1" skipped="0" errors="0" failures="0" time="<<computed>>">
+  <testsuite name="Chrome_puppeteer_/test/fixtures/multiple/nested-test.js" id="0" tests="1" skipped="0" errors="0" failures="0" time="<<computed>>">
     <properties>
-      <property name="test.fileName" value="packages/test-runner-junit-reporter/test/fixtures/multiple/nested-test.js"/>
+      <property name="test.fileName" value="test/fixtures/multiple/nested-test.js"/>
       <property name="browser.name" value="Chrome"/>
       <property name="browser.launcher" value="puppeteer"/>
     </properties>
-    <testcase name="is equivalent to map (f.g) f a" time="<<computed>>" classname="given a functor f and a function a -&gt; b map f map g f a" file="packages/test-runner-junit-reporter/test/fixtures/multiple/nested-test.js"/>
+    <testcase name="is equivalent to map (f.g) f a" time="<<computed>>" classname="given a functor f and a function a -&gt; b map f map g f a" file="test/fixtures/multiple/nested-test.js"/>
   </testsuite>
-  <testsuite name="Chrome_puppeteer_/packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js" id="0" tests="5" skipped="1" errors="1" failures="1" time="<<computed>>">
+  <testsuite name="Chrome_puppeteer_/test/fixtures/multiple/simple-test.js" id="0" tests="5" skipped="1" errors="1" failures="1" time="<<computed>>">
     <properties>
-      <property name="test.fileName" value="packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js"/>
+      <property name="test.fileName" value="test/fixtures/multiple/simple-test.js"/>
       <property name="browser.name" value="Chrome"/>
       <property name="browser.launcher" value="puppeteer"/>
     </properties>
-    <testcase name="under addition" time="<<computed>>" classname="real numbers forming a monoid" file="packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js"/>
-    <testcase name="null hypothesis" time="<<computed>>" classname="off-by-one boolean logic errors" file="packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js"/>
-    <testcase name="asserts error" time="<<computed>>" classname="off-by-one boolean logic errors" file="packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js" line="15">
+    <testcase name="under addition" time="<<computed>>" classname="real numbers forming a monoid" file="test/fixtures/multiple/simple-test.js"/>
+    <testcase name="null hypothesis" time="<<computed>>" classname="off-by-one boolean logic errors" file="test/fixtures/multiple/simple-test.js"/>
+    <testcase name="asserts error" time="<<computed>>" classname="off-by-one boolean logic errors" file="test/fixtures/multiple/simple-test.js" line="15">
       <failure message="expected false to be true" type="AssertionError"><![CDATA[AssertionError: expected false to be true
-  at <<anonymous>> (packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js:15:29)]]></failure>
+  at <<anonymous>> (test/fixtures/multiple/simple-test.js:15:29)]]></failure>
     </testcase>
-    <testcase name="tbd: confirm true positive" time="<<computed>>" classname="off-by-one boolean logic errors" file="packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js">
+    <testcase name="tbd: confirm true positive" time="<<computed>>" classname="off-by-one boolean logic errors" file="test/fixtures/multiple/simple-test.js">
       <skipped/>
     </testcase>
-    <testcase name="reports logs to JUnit" time="<<computed>>" classname="logging during a test" file="packages/test-runner-junit-reporter/test/fixtures/multiple/simple-test.js"/>
+    <testcase name="reports logs to JUnit" time="<<computed>>" classname="logging during a test" file="test/fixtures/multiple/simple-test.js"/>
   </testsuite>
 </testsuites>
\ No newline at end of file
diff --git a/packages/test-runner-junit-reporter/test/fixtures/nested/expected.xml b/packages/test-runner-junit-reporter/test/fixtures/nested/expected.xml
index d1383961ef..fe103402e3 100644
--- a/packages/test-runner-junit-reporter/test/fixtures/nested/expected.xml
+++ b/packages/test-runner-junit-reporter/test/fixtures/nested/expected.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuites>
-  <testsuite name="Chrome_puppeteer_/packages/test-runner-junit-reporter/test/fixtures/nested/nested-test.js" id="0" tests="1" skipped="0" errors="0" failures="0" time="<<computed>>">
+  <testsuite name="Chrome_puppeteer_/test/fixtures/nested/nested-test.js" id="0" tests="1" skipped="0" errors="0" failures="0" time="<<computed>>">
     <properties>
-      <property name="test.fileName" value="packages/test-runner-junit-reporter/test/fixtures/nested/nested-test.js"/>
+      <property name="test.fileName" value="test/fixtures/nested/nested-test.js"/>
       <property name="browser.name" value="Chrome"/>
       <property name="browser.launcher" value="puppeteer"/>
     </properties>
-    <testcase name="is equivalent to map (f.g) f a" time="<<computed>>" classname="given a functor f and a function a -&gt; b map f map g f a" file="packages/test-runner-junit-reporter/test/fixtures/nested/nested-test.js"/>
+    <testcase name="is equivalent to map (f.g) f a" time="<<computed>>" classname="given a functor f and a function a -&gt; b map f map g f a" file="test/fixtures/nested/nested-test.js"/>
   </testsuite>
 </testsuites>
\ No newline at end of file
diff --git a/packages/test-runner-junit-reporter/test/fixtures/simple/expected.xml b/packages/test-runner-junit-reporter/test/fixtures/simple/expected.xml
index 93eb434893..4386a40677 100644
--- a/packages/test-runner-junit-reporter/test/fixtures/simple/expected.xml
+++ b/packages/test-runner-junit-reporter/test/fixtures/simple/expected.xml
@@ -1,25 +1,25 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <testsuites>
-  <testsuite name="Chrome_puppeteer_/packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js" id="0" tests="6" skipped="1" errors="2" failures="2" time="<<computed>>">
+  <testsuite name="Chrome_puppeteer_/test/fixtures/simple/simple-test.js" id="0" tests="6" skipped="1" errors="2" failures="2" time="<<computed>>">
     <properties>
-      <property name="test.fileName" value="packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js"/>
+      <property name="test.fileName" value="test/fixtures/simple/simple-test.js"/>
       <property name="browser.name" value="Chrome"/>
       <property name="browser.launcher" value="puppeteer"/>
     </properties>
-    <testcase name="under addition" time="<<computed>>" classname="real numbers forming a monoid" file="packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js"/>
-    <testcase name="null hypothesis" time="<<computed>>" classname="off-by-one boolean logic errors" file="packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js"/>
-    <testcase name="asserts error" time="<<computed>>" classname="off-by-one boolean logic errors" file="packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js" line="17">
+    <testcase name="under addition" time="<<computed>>" classname="real numbers forming a monoid" file="test/fixtures/simple/simple-test.js"/>
+    <testcase name="null hypothesis" time="<<computed>>" classname="off-by-one boolean logic errors" file="test/fixtures/simple/simple-test.js"/>
+    <testcase name="asserts error" time="<<computed>>" classname="off-by-one boolean logic errors" file="test/fixtures/simple/simple-test.js" line="17">
       <failure message="expected false to be true" type="AssertionError"><![CDATA[AssertionError: expected false to be true
-  at <<anonymous>> (packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js:17:29)]]></failure>
+  at <<anonymous>> (test/fixtures/simple/simple-test.js:17:29)]]></failure>
     </testcase>
-    <testcase name="tbd: confirm true positive" time="<<computed>>" classname="off-by-one boolean logic errors" file="packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js">
+    <testcase name="tbd: confirm true positive" time="<<computed>>" classname="off-by-one boolean logic errors" file="test/fixtures/simple/simple-test.js">
       <skipped/>
     </testcase>
-    <testcase name="reports logs to JUnit" time="<<computed>>" classname="logging during a test" file="packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js"/>
-    <testcase name="fails with source trace" time="<<computed>>" classname="logging during a test" file="packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js" line="2">
+    <testcase name="reports logs to JUnit" time="<<computed>>" classname="logging during a test" file="test/fixtures/simple/simple-test.js"/>
+    <testcase name="fails with source trace" time="<<computed>>" classname="logging during a test" file="test/fixtures/simple/simple-test.js" line="2">
       <failure message="failed" type="Error"><![CDATA[Error: failed
-  at fail (packages/test-runner-junit-reporter/test/fixtures/simple/simple-source.js:2:9)
-  at <<anonymous>> (packages/test-runner-junit-reporter/test/fixtures/simple/simple-test.js:33:17)]]></failure>
+  at fail (test/fixtures/simple/simple-source.js:2:9)
+  at <<anonymous>> (test/fixtures/simple/simple-test.js:33:17)]]></failure>
     </testcase>
   </testsuite>
 </testsuites>
\ No newline at end of file
diff --git a/packages/test-runner-junit-reporter/test/junitReporter.test.ts b/packages/test-runner-junit-reporter/test/junitReporter.test.ts
index 79e63fed3e..7c04c05f4f 100644
--- a/packages/test-runner-junit-reporter/test/junitReporter.test.ts
+++ b/packages/test-runner-junit-reporter/test/junitReporter.test.ts
@@ -1,18 +1,19 @@
-import { expect } from 'chai';
+import { describe, it, after } from 'node:test';
+import assert from 'node:assert/strict';
 import { promises as fs } from 'fs';
 import path from 'path';
 import globby from 'globby';
 
 import { chromeLauncher } from '@web/test-runner-chrome';
-import { TestRunnerCoreConfig } from '@web/test-runner-core';
+import type { TestRunnerCoreConfig } from '@web/test-runner-core';
 import { runTests } from '@web/test-runner-core/test-helpers';
-import { junitReporter } from '../src/junitReporter.js';
+import { junitReporter } from '../dist/junitReporter.js';
 
 const NON_ZERO_TIME_VALUE_REGEX = /time="((\d\.\d+)|(\d))"/g;
 
 const USER_AGENT_STRING_REGEX = /"Mozilla\/5\.0 (.*)"/g;
 
-const rootDir = path.join(__dirname, '..', '..', '..');
+const rootDir = path.resolve(import.meta.dirname, '..', '..', '..');
 
 const normalizeOutput = (cwd: string, output: string) =>
   output
@@ -64,35 +65,35 @@ async function run(cwd: string): Promise<{ actual: string; expected: string }> {
 async function cleanupFixtures() {
   for (const file of await globby('fixtures/**/test-results.xml', {
     absolute: true,
-    cwd: __dirname,
+    cwd: import.meta.dirname,
   }))
     await fs.unlink(file);
 }
 
-describe('junitReporter', function () {
+describe('junitReporter', () => {
   after(cleanupFixtures);
 
-  describe('for a simple case', function () {
-    const fixtureDir = path.join(__dirname, 'fixtures/simple');
-    it('produces expected results', async function () {
+  describe('for a simple case', () => {
+    const fixtureDir = path.join(import.meta.dirname, 'fixtures/simple');
+    it('produces expected results', async () => {
       const { actual, expected } = await run(fixtureDir);
-      expect(actual).to.equal(expected);
+      assert.equal(actual, expected);
     });
   });
 
-  describe('for a nested suite', function () {
-    const fixtureDir = path.join(__dirname, 'fixtures/nested');
-    it('produces expected results', async function () {
+  describe('for a nested suite', () => {
+    const fixtureDir = path.join(import.meta.dirname, 'fixtures/nested');
+    it('produces expected results', async () => {
       const { actual, expected } = await run(fixtureDir);
-      expect(actual).to.equal(expected);
+      assert.equal(actual, expected);
     });
   });
 
-  describe('for multiple test files', function () {
-    const fixtureDir = path.join(__dirname, 'fixtures/multiple');
-    it('produces expected results', async function () {
+  describe('for multiple test files', () => {
+    const fixtureDir = path.join(import.meta.dirname, 'fixtures/multiple');
+    it('produces expected results', async () => {
       const { actual, expected } = await run(fixtureDir);
-      expect(actual).to.equal(expected);
+      assert.equal(actual, expected);
     });
   });
 });
