diff --git a/examples/todomvc/tests/integration.spec.ts b/examples/todomvc/tests/integration.spec.ts index 61988a642d..75484aca51 100644 --- a/examples/todomvc/tests/integration.spec.ts +++ b/examples/todomvc/tests/integration.spec.ts @@ -143,6 +143,7 @@ test.describe('Item', () => { // Assert completed class. await expect(firstTodo).toHaveClass('completed'); await expect(secondTodo).toHaveClass('completed'); + }); test('should allow me to un-mark items as complete', async ({ page }) => { diff --git a/packages/playwright-test/src/cli.ts b/packages/playwright-test/src/cli.ts index f89b00dfb6..4196d4be28 100644 --- a/packages/playwright-test/src/cli.ts +++ b/packages/playwright-test/src/cli.ts @@ -195,7 +195,7 @@ async function listTestFiles(opts: { [key: string]: any }) { const runner = new Runner(); await runner.loadConfigFromResolvedFile(resolvedConfigFile); - const report = await runner.listTestFiles(resolvedConfigFile, opts.project); + const report = await runner.listTestFiles(opts.project); write(JSON.stringify(report), () => { process.exit(0); }); diff --git a/packages/playwright-test/src/runner.ts b/packages/playwright-test/src/runner.ts index 46f202423d..f376e71352 100644 --- a/packages/playwright-test/src/runner.ts +++ b/packages/playwright-test/src/runner.ts @@ -194,7 +194,7 @@ export class Runner { return fullResult; } - async listTestFiles(configFile: string, projectNames: string[] | undefined): Promise { + async listTestFiles(projectNames: string[] | undefined): Promise { const projects = this._collectProjects(projectNames); const { filesByProject } = await this._collectFiles(projects, () => true); const report: any = { @@ -202,10 +202,8 @@ export class Runner { }; for (const [project, files] of filesByProject) { report.projects.push({ - docker: process.env.PLAYWRIGHT_DOCKER, - name: project.name, - testDir: path.resolve(configFile, project.testDir), - files: files + ...sanitizeConfigForJSON(project, new Set()), + files: files, }); } return report; @@ -953,5 +951,34 @@ function createStacklessError(message: string): TestError { return { message, __isNotAFatalError: true } as any; } +function sanitizeConfigForJSON(object: any, visited: Set): any { + const type = typeof object; + if (type === 'function' || type === 'symbol') + return undefined; + if (!object || type !== 'object') + return object; + + if (object instanceof RegExp) + return String(object); + if (object instanceof Date) + return object.toISOString(); + + if (visited.has(object)) + return undefined; + visited.add(object); + + if (Array.isArray(object)) + return object.map(a => sanitizeConfigForJSON(a, visited)); + + const result: any = {}; + const keys = Object.keys(object).slice(0, 100); + for (const key of keys) { + if (key.startsWith('_')) + continue; + result[key] = sanitizeConfigForJSON(object[key], visited); + } + return result; +} + export const builtInReporters = ['list', 'line', 'dot', 'json', 'junit', 'null', 'github', 'html'] as const; export type BuiltInReporter = typeof builtInReporters[number];