@ohos-ports/web-test-runner 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +65 -0
  2. package/dist/TestRunnerStartError.d.ts +3 -0
  3. package/dist/TestRunnerStartError.d.ts.map +1 -0
  4. package/dist/TestRunnerStartError.js +7 -0
  5. package/dist/TestRunnerStartError.js.map +1 -0
  6. package/dist/bin.d.ts +3 -0
  7. package/dist/bin.d.ts.map +1 -0
  8. package/dist/bin.js +6 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/config/TestRunnerConfig.d.ts +10 -0
  11. package/dist/config/TestRunnerConfig.d.ts.map +1 -0
  12. package/dist/config/TestRunnerConfig.js +3 -0
  13. package/dist/config/TestRunnerConfig.js.map +1 -0
  14. package/dist/config/collectGroupConfigs.d.ts +3 -0
  15. package/dist/config/collectGroupConfigs.d.ts.map +1 -0
  16. package/dist/config/collectGroupConfigs.js +43 -0
  17. package/dist/config/collectGroupConfigs.js.map +1 -0
  18. package/dist/config/loadLauncher.d.ts +3 -0
  19. package/dist/config/loadLauncher.d.ts.map +1 -0
  20. package/dist/config/loadLauncher.js +43 -0
  21. package/dist/config/loadLauncher.js.map +1 -0
  22. package/dist/config/mergeConfigs.d.ts +3 -0
  23. package/dist/config/mergeConfigs.d.ts.map +1 -0
  24. package/dist/config/mergeConfigs.js +26 -0
  25. package/dist/config/mergeConfigs.js.map +1 -0
  26. package/dist/config/parseConfig.d.ts +9 -0
  27. package/dist/config/parseConfig.d.ts.map +1 -0
  28. package/dist/config/parseConfig.js +216 -0
  29. package/dist/config/parseConfig.js.map +1 -0
  30. package/dist/config/readCliArgs.d.ts +15 -0
  31. package/dist/config/readCliArgs.d.ts.map +1 -0
  32. package/dist/config/readCliArgs.js +148 -0
  33. package/dist/config/readCliArgs.js.map +1 -0
  34. package/dist/config/readFileConfig.d.ts +18 -0
  35. package/dist/config/readFileConfig.d.ts.map +1 -0
  36. package/dist/config/readFileConfig.js +22 -0
  37. package/dist/config/readFileConfig.js.map +1 -0
  38. package/dist/index.d.ts +10 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +31 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/logger/TestRunnerLogger.d.ts +15 -0
  43. package/dist/logger/TestRunnerLogger.d.ts.map +1 -0
  44. package/dist/logger/TestRunnerLogger.js +48 -0
  45. package/dist/logger/TestRunnerLogger.js.map +1 -0
  46. package/dist/reporter/defaultReporter.d.ts +7 -0
  47. package/dist/reporter/defaultReporter.d.ts.map +1 -0
  48. package/dist/reporter/defaultReporter.js +51 -0
  49. package/dist/reporter/defaultReporter.js.map +1 -0
  50. package/dist/reporter/dotReporter.d.ts +4 -0
  51. package/dist/reporter/dotReporter.d.ts.map +1 -0
  52. package/dist/reporter/dotReporter.js +53 -0
  53. package/dist/reporter/dotReporter.js.map +1 -0
  54. package/dist/reporter/getCodeCoverage.d.ts +3 -0
  55. package/dist/reporter/getCodeCoverage.d.ts.map +1 -0
  56. package/dist/reporter/getCodeCoverage.js +36 -0
  57. package/dist/reporter/getCodeCoverage.js.map +1 -0
  58. package/dist/reporter/getTestProgress.d.ts +16 -0
  59. package/dist/reporter/getTestProgress.d.ts.map +1 -0
  60. package/dist/reporter/getTestProgress.js +105 -0
  61. package/dist/reporter/getTestProgress.js.map +1 -0
  62. package/dist/reporter/renderProgressBar.d.ts +2 -0
  63. package/dist/reporter/renderProgressBar.d.ts.map +1 -0
  64. package/dist/reporter/renderProgressBar.js +23 -0
  65. package/dist/reporter/renderProgressBar.js.map +1 -0
  66. package/dist/reporter/reportBrowserLogs.d.ts +3 -0
  67. package/dist/reporter/reportBrowserLogs.d.ts.map +1 -0
  68. package/dist/reporter/reportBrowserLogs.js +61 -0
  69. package/dist/reporter/reportBrowserLogs.js.map +1 -0
  70. package/dist/reporter/reportRequest404s.d.ts +3 -0
  71. package/dist/reporter/reportRequest404s.d.ts.map +1 -0
  72. package/dist/reporter/reportRequest404s.js +54 -0
  73. package/dist/reporter/reportRequest404s.js.map +1 -0
  74. package/dist/reporter/reportTestFileErrors.d.ts +3 -0
  75. package/dist/reporter/reportTestFileErrors.d.ts.map +1 -0
  76. package/dist/reporter/reportTestFileErrors.js +52 -0
  77. package/dist/reporter/reportTestFileErrors.js.map +1 -0
  78. package/dist/reporter/reportTestFileResults.d.ts +3 -0
  79. package/dist/reporter/reportTestFileResults.d.ts.map +1 -0
  80. package/dist/reporter/reportTestFileResults.js +25 -0
  81. package/dist/reporter/reportTestFileResults.js.map +1 -0
  82. package/dist/reporter/reportTestsErrors.d.ts +4 -0
  83. package/dist/reporter/reportTestsErrors.d.ts.map +1 -0
  84. package/dist/reporter/reportTestsErrors.js +129 -0
  85. package/dist/reporter/reportTestsErrors.js.map +1 -0
  86. package/dist/reporter/summaryReporter.d.ts +10 -0
  87. package/dist/reporter/summaryReporter.d.ts.map +1 -0
  88. package/dist/reporter/summaryReporter.js +73 -0
  89. package/dist/reporter/summaryReporter.js.map +1 -0
  90. package/dist/reporter/utils/getFailedOnBrowsers.d.ts +2 -0
  91. package/dist/reporter/utils/getFailedOnBrowsers.d.ts.map +1 -0
  92. package/dist/reporter/utils/getFailedOnBrowsers.js +13 -0
  93. package/dist/reporter/utils/getFailedOnBrowsers.js.map +1 -0
  94. package/dist/reporter/utils/getFlattenedTestResults.d.ts +3 -0
  95. package/dist/reporter/utils/getFlattenedTestResults.d.ts.map +1 -0
  96. package/dist/reporter/utils/getFlattenedTestResults.js +21 -0
  97. package/dist/reporter/utils/getFlattenedTestResults.js.map +1 -0
  98. package/dist/reporter/utils/getPassedFailedSkippedCount.d.ts +7 -0
  99. package/dist/reporter/utils/getPassedFailedSkippedCount.d.ts.map +1 -0
  100. package/dist/reporter/utils/getPassedFailedSkippedCount.js +30 -0
  101. package/dist/reporter/utils/getPassedFailedSkippedCount.js.map +1 -0
  102. package/dist/reporter/utils/toBrowserPath.d.ts +2 -0
  103. package/dist/reporter/utils/toBrowserPath.d.ts.map +1 -0
  104. package/dist/reporter/utils/toBrowserPath.js +11 -0
  105. package/dist/reporter/utils/toBrowserPath.js.map +1 -0
  106. package/dist/reporter/utils/toFilePath.d.ts +6 -0
  107. package/dist/reporter/utils/toFilePath.d.ts.map +1 -0
  108. package/dist/reporter/utils/toFilePath.js +15 -0
  109. package/dist/reporter/utils/toFilePath.js.map +1 -0
  110. package/dist/startTestRunner.d.ts +33 -0
  111. package/dist/startTestRunner.d.ts.map +1 -0
  112. package/dist/startTestRunner.js +61 -0
  113. package/dist/startTestRunner.js.map +1 -0
  114. package/index.d.ts +2 -0
  115. package/index.mjs +38 -0
  116. package/package.json +107 -0
  117. package/scripts/ohos-postinstall-sign.js +117 -0
  118. package/src/TestRunnerStartError.ts +1 -0
  119. package/src/bin.ts +4 -0
  120. package/src/config/TestRunnerConfig.ts +14 -0
  121. package/src/config/collectGroupConfigs.ts +50 -0
  122. package/src/config/loadLauncher.ts +48 -0
  123. package/src/config/mergeConfigs.ts +26 -0
  124. package/src/config/parseConfig.ts +286 -0
  125. package/src/config/readCliArgs.ts +187 -0
  126. package/src/config/readFileConfig.ts +35 -0
  127. package/src/index.ts +11 -0
  128. package/src/logger/TestRunnerLogger.ts +54 -0
  129. package/src/reporter/defaultReporter.ts +78 -0
  130. package/src/reporter/dotReporter.ts +65 -0
  131. package/src/reporter/getCodeCoverage.ts +54 -0
  132. package/src/reporter/getTestProgress.ts +181 -0
  133. package/src/reporter/renderProgressBar.ts +27 -0
  134. package/src/reporter/reportBrowserLogs.ts +64 -0
  135. package/src/reporter/reportRequest404s.ts +55 -0
  136. package/src/reporter/reportTestFileErrors.ts +70 -0
  137. package/src/reporter/reportTestFileResults.ts +33 -0
  138. package/src/reporter/reportTestsErrors.ts +110 -0
  139. package/src/reporter/summaryReporter.ts +123 -0
  140. package/src/reporter/utils/getFailedOnBrowsers.ts +10 -0
  141. package/src/reporter/utils/getFlattenedTestResults.ts +24 -0
  142. package/src/reporter/utils/getPassedFailedSkippedCount.ts +31 -0
  143. package/src/reporter/utils/toBrowserPath.ts +5 -0
  144. package/src/reporter/utils/toFilePath.ts +9 -0
  145. package/src/startTestRunner.ts +101 -0
  146. package/web-test-runner.config.mjs +8 -0
@@ -0,0 +1,110 @@
1
+ import { type Logger, type TestResultError, type TestSession } from '@web/test-runner-core';
2
+ import * as diff from 'diff';
3
+ import { gray, green, red } from 'nanocolors';
4
+
5
+ import { getFailedOnBrowsers } from './utils/getFailedOnBrowsers.js';
6
+ import { getFlattenedTestResults } from './utils/getFlattenedTestResults.js';
7
+
8
+ function renderDiff(actual: string, expected: string) {
9
+ function cleanUp(line: string) {
10
+ if (line[0] === '+') {
11
+ return green(line);
12
+ }
13
+ if (line[0] === '-') {
14
+ return red(line);
15
+ }
16
+ if (line.match(/@@/)) {
17
+ return null;
18
+ }
19
+ if (line.match(/\\ No newline/)) {
20
+ return null;
21
+ }
22
+ return line;
23
+ }
24
+
25
+ const diffMsg = diff
26
+ .createPatch('string', actual, expected)
27
+ .split('\n')
28
+ .splice(4)
29
+ .map(cleanUp)
30
+ .filter(l => !!l)
31
+ .join('\n');
32
+
33
+ return `${green('+ expected')} ${red('- actual')}\n\n${diffMsg}`;
34
+ }
35
+
36
+ export function formatError(error: TestResultError) {
37
+ const strings: string[] = [];
38
+ const { name, message = 'Unknown error' } = error;
39
+ const errorMsg = name ? `${name}: ${message}` : message;
40
+ const showDiff = typeof error.expected === 'string' && typeof error.actual === 'string';
41
+ strings.push(red(errorMsg));
42
+
43
+ if (showDiff) {
44
+ strings.push(`${renderDiff(error.actual!, error.expected!)}\n`);
45
+ }
46
+
47
+ if (error.stack) {
48
+ if (showDiff) {
49
+ const dedented = error.stack
50
+ .split('\n')
51
+ .map(s => s.trim())
52
+ .join('\n');
53
+ strings.push(gray(dedented));
54
+ } else {
55
+ strings.push(gray(error.stack));
56
+ }
57
+ }
58
+
59
+ if (!error.expected && !error.stack) {
60
+ strings.push(red(error.message || 'Unknown error'));
61
+ }
62
+
63
+ return strings.join('\n');
64
+ }
65
+
66
+ export function reportTestsErrors(
67
+ logger: Logger,
68
+ allBrowserNames: string[],
69
+ favoriteBrowser: string,
70
+ failedSessions: TestSession[],
71
+ ) {
72
+ const testErrorsPerBrowser = new Map<string, Map<string, TestResultError>>();
73
+
74
+ for (const session of failedSessions) {
75
+ if (session.testResults) {
76
+ const flattenedTests = getFlattenedTestResults(session.testResults);
77
+ for (const test of flattenedTests) {
78
+ if (test.error) {
79
+ let testErrorsForBrowser = testErrorsPerBrowser.get(test.name);
80
+ if (!testErrorsForBrowser) {
81
+ testErrorsForBrowser = new Map<string, TestResultError>();
82
+ testErrorsPerBrowser.set(test.name, testErrorsForBrowser);
83
+ }
84
+ if (test.error) {
85
+ testErrorsForBrowser.set(session.browser.name, test.error);
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+
92
+ if (testErrorsPerBrowser.size > 0) {
93
+ for (const [name, errorsForBrowser] of testErrorsPerBrowser) {
94
+ const failedBrowsers = Array.from(errorsForBrowser.keys());
95
+ const error =
96
+ errorsForBrowser.get(favoriteBrowser) ?? errorsForBrowser.get(failedBrowsers[0])!;
97
+ const failedOn = getFailedOnBrowsers(allBrowserNames, failedBrowsers);
98
+
99
+ logger.log(` ❌ ${name}${failedOn}`);
100
+ logger.group();
101
+ logger.group();
102
+ logger.group();
103
+ logger.log(formatError(error));
104
+ logger.groupEnd();
105
+ logger.groupEnd();
106
+ logger.groupEnd();
107
+ logger.log('');
108
+ }
109
+ }
110
+ }
@@ -0,0 +1,123 @@
1
+ import type {
2
+ BrowserLauncher,
3
+ Logger,
4
+ Reporter,
5
+ ReporterArgs,
6
+ TestSuiteResult,
7
+ } from '@web/test-runner-core';
8
+
9
+ import { reportTestFileErrors } from './reportTestFileErrors.js';
10
+ import { reportTestsErrors } from './reportTestsErrors.js';
11
+
12
+ import { TestRunnerLogger } from '../logger/TestRunnerLogger.js';
13
+ import { reportBrowserLogs } from './reportBrowserLogs.js';
14
+
15
+ interface Options {
16
+ flatten?: boolean;
17
+ reportTestLogs?: boolean;
18
+ reportTestErrors?: boolean;
19
+ }
20
+
21
+ const color =
22
+ ([x, y]: [number, number]) =>
23
+ (z: string) =>
24
+ `\x1b[${x}m${z}\x1b[${y}m${reset}`;
25
+ const reset = `\x1b[0m\x1b[0m`;
26
+ const green = color([32, 89]);
27
+ const red = color([31, 89]);
28
+ const dim = color([2, 0]);
29
+
30
+ /** Test reporter that summarizes all test for a given run */
31
+ export function summaryReporter(opts: Options): Reporter {
32
+ const { flatten = false, reportTestLogs = true, reportTestErrors = true } = opts ?? {};
33
+ let args: ReporterArgs;
34
+ let favoriteBrowser: string;
35
+
36
+ const testLogger = new TestRunnerLogger();
37
+
38
+ function log(
39
+ logger: Logger,
40
+ name: string,
41
+ passed: boolean,
42
+ skipped: boolean,
43
+ prefix = ' ',
44
+ postfix = '',
45
+ ) {
46
+ const sign = skipped ? dim('-') : passed ? green('✓') : red('𐄂');
47
+ if (flatten) logger.log(`${sign} ${name}${postfix}`);
48
+ else logger.log(`${prefix} ${sign} ${name}`);
49
+ }
50
+
51
+ function logResults(
52
+ logger: Logger,
53
+ results?: TestSuiteResult,
54
+ prefix?: string,
55
+ browser?: BrowserLauncher,
56
+ ) {
57
+ const browserName = browser?.name ? ` ${dim(`[${browser.name}]`)}` : '';
58
+ for (const result of results?.tests ?? []) {
59
+ log(
60
+ logger,
61
+ flatten ? `${prefix ?? ''} ${result.name}` : result.name,
62
+ result.passed,
63
+ result.skipped,
64
+ prefix,
65
+ browserName,
66
+ );
67
+ }
68
+
69
+ for (const suite of results?.suites ?? []) {
70
+ logSuite(logger, suite, prefix, browser);
71
+ }
72
+ }
73
+
74
+ function logSuite(
75
+ logger: Logger,
76
+ suite: TestSuiteResult,
77
+ parent?: string,
78
+ browser?: BrowserLauncher,
79
+ ) {
80
+ const browserName = browser?.name ? ` ${dim(`[${browser.name}]`)}` : '';
81
+ let pref = parent ? `${parent} ` : ' ';
82
+ if (flatten) pref += `${suite.name}`;
83
+ else logger.log(`${pref}${suite.name}${browserName}`);
84
+
85
+ logResults(logger, suite, pref, browser);
86
+ }
87
+
88
+ return {
89
+ start(_args) {
90
+ args = _args;
91
+ favoriteBrowser =
92
+ args.browserNames.find(name => {
93
+ const n = name.toLowerCase();
94
+ return n.includes('chrome') || n.includes('chromium') || n.includes('firefox');
95
+ }) ?? args.browserNames[0];
96
+ },
97
+
98
+ reportTestFileResults({ logger, sessionsForTestFile }) {
99
+ for (const session of sessionsForTestFile) {
100
+ logResults(logger, session.testResults, '', session.browser);
101
+ logger.log('');
102
+ }
103
+ if (reportTestLogs) reportBrowserLogs(logger, sessionsForTestFile);
104
+ },
105
+
106
+ onTestRunFinished({ sessions }) {
107
+ if (reportTestErrors) {
108
+ const failedSessions = sessions.filter(s => !s.passed);
109
+ if (failedSessions.length > 0) {
110
+ testLogger.log('\n\nErrors Reported in Tests:\n\n');
111
+ reportTestsErrors(testLogger, args.browserNames, favoriteBrowser, failedSessions);
112
+ reportTestFileErrors(
113
+ testLogger,
114
+ args.browserNames,
115
+ favoriteBrowser,
116
+ failedSessions,
117
+ true,
118
+ );
119
+ }
120
+ }
121
+ },
122
+ };
123
+ }
@@ -0,0 +1,10 @@
1
+ export function getFailedOnBrowsers(allBrowserNames: string[], failedBrowsers: string[]) {
2
+ if (allBrowserNames.length === 1 || failedBrowsers.length === allBrowserNames.length) {
3
+ return '';
4
+ }
5
+ const browserString =
6
+ failedBrowsers.length === 1
7
+ ? failedBrowsers[0]
8
+ : failedBrowsers.slice(0, -1).join(', ') + ' and ' + failedBrowsers.slice(-1);
9
+ return ` (failed on ${browserString})`;
10
+ }
@@ -0,0 +1,24 @@
1
+ import { type TestResult, type TestSuiteResult } from '@web/test-runner-core';
2
+
3
+ export function getFlattenedTestResults(testResults: TestSuiteResult) {
4
+ const flattened: TestResult[] = [];
5
+
6
+ function collectTests(prefix: string, tests: TestResult[]) {
7
+ for (const test of tests) {
8
+ flattened.push({ ...test, name: `${prefix}${test.name}` });
9
+ }
10
+ }
11
+
12
+ function collectSuite(prefix: string, suite: TestSuiteResult) {
13
+ collectTests(prefix, suite.tests);
14
+
15
+ for (const childSuite of suite.suites) {
16
+ const newPrefix = `${prefix}${childSuite.name} > `;
17
+ collectSuite(newPrefix, childSuite);
18
+ }
19
+ }
20
+
21
+ collectSuite('', testResults);
22
+
23
+ return flattened;
24
+ }
@@ -0,0 +1,31 @@
1
+ import { type TestResult, type TestSuiteResult } from '@web/test-runner-core';
2
+
3
+ export function getPassedFailedSkippedCount(testResults: TestSuiteResult) {
4
+ let passed = 0;
5
+ let failed = 0;
6
+ let skipped = 0;
7
+
8
+ function collectTests(tests: TestResult[]) {
9
+ for (const test of tests) {
10
+ if (test.skipped) {
11
+ skipped += 1;
12
+ } else if (test.passed) {
13
+ passed += 1;
14
+ } else {
15
+ failed += 1;
16
+ }
17
+ }
18
+ }
19
+
20
+ function collectSuite(suite: TestSuiteResult) {
21
+ collectTests(suite.tests);
22
+
23
+ for (const childSuite of suite.suites) {
24
+ collectSuite(childSuite);
25
+ }
26
+ }
27
+
28
+ collectSuite(testResults);
29
+
30
+ return { passed, failed, skipped };
31
+ }
@@ -0,0 +1,5 @@
1
+ import path from 'path';
2
+
3
+ export function toBrowserPath(filePath: string) {
4
+ return filePath.split(path.sep).join('/');
5
+ }
@@ -0,0 +1,9 @@
1
+ import path from 'path';
2
+
3
+ /**
4
+ * Transforms a file system path to a browser URL. For example windows uses `\` on the file system,
5
+ * but it should use `/` in the browser.
6
+ */
7
+ export function toFilePath(browserPath: string) {
8
+ return browserPath.split('/').join(path.sep);
9
+ }
@@ -0,0 +1,101 @@
1
+ import { TestRunner, TestRunnerCli } from '@web/test-runner-core';
2
+ import { red } from 'nanocolors';
3
+
4
+ import { TestRunnerStartError } from './TestRunnerStartError.js';
5
+ import { TestRunnerConfig } from './config/TestRunnerConfig.js';
6
+ import { mergeConfigs } from './config/mergeConfigs.js';
7
+ import { parseConfig } from './config/parseConfig.js';
8
+ import { readCliArgs } from './config/readCliArgs.js';
9
+ import { readFileConfig } from './config/readFileConfig.js';
10
+
11
+ export interface StartTestRunnerParams {
12
+ /**
13
+ * Optional config to merge with the user-defined config.
14
+ */
15
+ config?: Partial<TestRunnerConfig>;
16
+ /**
17
+ * Whether to read CLI args. Default true.
18
+ */
19
+ readCliArgs?: boolean;
20
+ /**
21
+ * Whether to read a user config from the file system. Default true.
22
+ */
23
+ readFileConfig?: boolean;
24
+ /**
25
+ * Name of the configuration to read. Defaults to web-dev-server.config.{mjs,cjs,js}
26
+ */
27
+ configName?: string;
28
+ /**
29
+ * Whether to automatically exit the process when the server is stopped, killed or an error is thrown.
30
+ */
31
+ autoExitProcess?: boolean;
32
+ /**
33
+ * Array to read the CLI args from. Defaults to process.argv.
34
+ */
35
+ argv?: string[];
36
+ }
37
+
38
+ /**
39
+ * Starts the test runner.
40
+ */
41
+ export async function startTestRunner(options: StartTestRunnerParams = {}) {
42
+ const {
43
+ config: extraConfig,
44
+ readCliArgs: readCliArgsFlag = true,
45
+ readFileConfig: readFileConfigFlag = true,
46
+ configName,
47
+ autoExitProcess = true,
48
+ argv = process.argv,
49
+ } = options;
50
+
51
+ try {
52
+ const cliArgs = readCliArgsFlag ? readCliArgs({ argv }) : {};
53
+ const rawConfig = readFileConfigFlag
54
+ ? await readFileConfig({ configName, configPath: cliArgs.config })
55
+ : {};
56
+ const mergedConfig = mergeConfigs(extraConfig, rawConfig);
57
+ const { config, groupConfigs } = await parseConfig(mergedConfig, cliArgs);
58
+
59
+ const runner = new TestRunner(config, groupConfigs);
60
+ const cli = new TestRunnerCli(config, runner);
61
+
62
+ function stop() {
63
+ runner.stop();
64
+ }
65
+
66
+ if (autoExitProcess) {
67
+ (['exit', 'SIGINT'] as NodeJS.Signals[]).forEach(event => {
68
+ process.on(event, stop);
69
+ });
70
+ }
71
+
72
+ if (autoExitProcess) {
73
+ process.on('uncaughtException', error => {
74
+ console.error(`Uncaught exception, stopping test runner..\n`, error);
75
+ stop();
76
+ });
77
+ }
78
+
79
+ runner.on('stopped', passed => {
80
+ if (autoExitProcess) {
81
+ process.exit(passed ? 0 : 1);
82
+ }
83
+ });
84
+
85
+ await runner.start();
86
+ cli.start();
87
+
88
+ return runner;
89
+ } catch (error) {
90
+ if (error instanceof TestRunnerStartError) {
91
+ console.error(`\n${red('Error:')} ${error.message}\n`);
92
+ } else {
93
+ console.error(error);
94
+ }
95
+
96
+ setTimeout(() => {
97
+ // exit after a timeout to allow CLI to flush console output
98
+ process.exit(1);
99
+ }, 0);
100
+ }
101
+ }
@@ -0,0 +1,8 @@
1
+ import { legacyPlugin } from '@web/dev-server-legacy';
2
+
3
+ export default {
4
+ rootDir: '../../',
5
+ preserveSymlinks: true,
6
+ nodeResolve: true,
7
+ plugins: [legacyPlugin()],
8
+ };