@dxos/test-utils 0.10.0 → 0.11.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/test-utils",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Test utilities",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -13,14 +13,14 @@
13
13
  "type": "module",
14
14
  "exports": {
15
15
  ".": {
16
+ "source": "./src/index.ts",
16
17
  "types": "./dist/types/src/index.d.ts",
17
- "browser": "./dist/lib/browser/index.mjs",
18
- "node": "./dist/lib/node-esm/index.mjs"
18
+ "import": "./dist/lib/index.mjs"
19
19
  },
20
20
  "./playwright": {
21
+ "source": "./src/playwright.ts",
21
22
  "types": "./dist/types/src/playwright.d.ts",
22
- "browser": "./dist/lib/browser/playwright.mjs",
23
- "node": "./dist/lib/node-esm/playwright.mjs"
23
+ "import": "./dist/lib/playwright.mjs"
24
24
  }
25
25
  },
26
26
  "types": "dist/types/src/index.d.ts",
@@ -31,11 +31,11 @@
31
31
  "dependencies": {
32
32
  "@playwright/test": "1.57.0",
33
33
  "pkg-up": "^3.1.0",
34
- "@dxos/async": "0.10.0",
35
- "@dxos/node-std": "0.10.0"
34
+ "@dxos/async": "0.11.0",
35
+ "@dxos/node-std": "0.11.0"
36
36
  },
37
37
  "peerDependencies": {
38
- "vitest": "4.1.8"
38
+ "vitest": "4.1.10"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"
package/src/playwright.ts CHANGED
@@ -71,6 +71,10 @@ export const e2ePreset = (testDir: string): PlaywrightTestConfig => {
71
71
  return {
72
72
  testDir,
73
73
  outputDir: testResultOuputDir,
74
+ // Playwright's default is 30s, which equals the action bound below — leaving a test no budget beyond
75
+ // a single slow action. Storybook-backed suites also pay an on-demand story compile in the first
76
+ // test's `beforeEach`, which alone exceeded 30s. Individual configs may still raise this.
77
+ timeout: 60_000,
74
78
  // Run tests in files in parallel.
75
79
  fullyParallel: true,
76
80
  // Fail the build on CI if you accidentally left test.only in the source code.
@@ -96,6 +100,9 @@ export const e2ePreset = (testDir: string): PlaywrightTestConfig => {
96
100
  : [['list']],
97
101
  use: {
98
102
  trace: 'retain-on-failure',
103
+ // Playwright's default is no limit, so a stuck locator would absorb the whole per-test budget and
104
+ // report a bare `Test timeout` naming nothing.
105
+ actionTimeout: 30_000,
99
106
  },
100
107
  projects,
101
108
  };
@@ -1,12 +0,0 @@
1
- // src/resource.ts
2
- import { onTestFinished } from "vitest";
3
- var openAndClose = async (...resources) => {
4
- for (const resourceLike of resources) {
5
- await resourceLike.open();
6
- onTestFinished(() => resourceLike.close());
7
- }
8
- };
9
- export {
10
- openAndClose
11
- };
12
- //# sourceMappingURL=index.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/resource.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { onTestFinished } from 'vitest';\n\ninterface ResourceLike {\n open(): Promise<any>;\n close(): Promise<any>;\n}\n\n// TODO(burdon): Replace with abstraction relating to Context object?\nexport const openAndClose = async (...resources: ResourceLike[]) => {\n for (const resourceLike of resources) {\n await resourceLike.open();\n onTestFinished(() => resourceLike.close());\n }\n};\n"],
5
- "mappings": ";AAIA,SAASA,sBAAsB;AAQxB,IAAMC,eAAe,UAAUC,cAAAA;AACpC,aAAWC,gBAAgBD,WAAW;AACpC,UAAMC,aAAaC,KAAI;AACvBJ,mBAAe,MAAMG,aAAaE,MAAK,CAAA;EACzC;AACF;",
6
- "names": ["onTestFinished", "openAndClose", "resources", "resourceLike", "open", "close"]
7
- }
@@ -1 +0,0 @@
1
- {"inputs":{"src/resource.ts":{"bytes":1452,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":376,"imports":[{"path":"src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"src/lock.ts":{"bytes":1942,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":16371,"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"@dxos/node-std/fs","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":780},"dist/lib/browser/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"src/index.ts","inputs":{"src/resource.ts":{"bytesInOutput":214},"src/index.ts":{"bytesInOutput":0}},"bytes":295},"dist/lib/browser/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9280},"dist/lib/browser/playwright.mjs":{"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"@dxos/node-std/fs","kind":"import-statement","external":true},{"path":"@dxos/node-std/path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true}],"exports":["e2ePreset","setupPage","storybookUrl"],"entryPoint":"src/playwright.ts","inputs":{"src/playwright.ts":{"bytesInOutput":3991},"src/lock.ts":{"bytesInOutput":389}},"bytes":4532}}}
@@ -1,169 +0,0 @@
1
- // src/playwright.ts
2
- import { devices } from "@playwright/test";
3
- import { existsSync, readFileSync } from "@dxos/node-std/fs";
4
- import { dirname, join, resolve } from "@dxos/node-std/path";
5
- import pkgUp from "pkg-up";
6
-
7
- // src/lock.ts
8
- import { trigger } from "@dxos/async";
9
- var Lock = class {
10
- _lastPromise = Promise.resolve();
11
- async executeSynchronized(fun) {
12
- const prevPromise = this._lastPromise;
13
- const [getPromise, resolve2] = trigger();
14
- this._lastPromise = getPromise();
15
- await prevPromise;
16
- try {
17
- const value = await fun();
18
- return value;
19
- } finally {
20
- resolve2();
21
- }
22
- }
23
- };
24
-
25
- // src/playwright.ts
26
- var findWorkspaceRoot = (startDir) => {
27
- let dir = resolve(startDir);
28
- while (dir !== "/") {
29
- try {
30
- const workspaceYamlPath = join(dir, "pnpm-workspace.yaml");
31
- if (existsSync(workspaceYamlPath)) {
32
- return dir;
33
- }
34
- const pkgPath = join(dir, "package.json");
35
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
36
- if (pkg.workspaces) {
37
- return dir;
38
- }
39
- } catch {
40
- }
41
- const parent = dirname(dir);
42
- if (parent === dir) {
43
- break;
44
- }
45
- dir = parent;
46
- }
47
- throw new Error("Could not find pnpm workspace root");
48
- };
49
- var e2ePreset = (testDir) => {
50
- const packageJson = pkgUp.sync({
51
- cwd: testDir
52
- });
53
- const packageDir = packageJson.split("/").slice(0, -1).join("/");
54
- const packageDirName = packageDir.split("/").pop();
55
- if (!packageDirName) {
56
- throw new Error("packageDirName not found");
57
- }
58
- const workspaceRoot = findWorkspaceRoot(packageDir);
59
- const testResultOuputDir = join(workspaceRoot, "test-results/playwright/output", packageDirName);
60
- const reporterOutputFile = join(workspaceRoot, "test-results/playwright/report", `${packageDirName}.json`);
61
- const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? "all" : "chromium");
62
- const projects = [
63
- {
64
- name: "chromium",
65
- use: {
66
- ...devices["Desktop Chrome"]
67
- }
68
- },
69
- {
70
- name: "firefox",
71
- use: {
72
- ...devices["Desktop Firefox"]
73
- }
74
- },
75
- {
76
- name: "webkit",
77
- use: {
78
- ...devices["Desktop Safari"]
79
- }
80
- }
81
- ].filter((project) => {
82
- return browser === "all" || project.name === browser;
83
- });
84
- return {
85
- testDir,
86
- outputDir: testResultOuputDir,
87
- // Run tests in files in parallel.
88
- fullyParallel: true,
89
- // Fail the build on CI if you accidentally left test.only in the source code.
90
- forbidOnly: !!process.env.CI,
91
- // Retry on CI to ride out the residual d&d / startup flakes while the
92
- // underlying causes are still being chased. Local runs stay strict so
93
- // flakes are visible while iterating.
94
- retries: process.env.CI ? 2 : 0,
95
- // Opt out of parallel tests on CI.
96
- workers: process.env.CI ? 1 : 4,
97
- // Reporter to use. See https://playwright.dev/docs/test-reporters.
98
- reporter: process.env.CI ? [
99
- [
100
- "list"
101
- ],
102
- [
103
- "json",
104
- {
105
- outputFile: reporterOutputFile
106
- }
107
- ],
108
- [
109
- "junit",
110
- {
111
- outputFile: reporterOutputFile.replace(/\.json$/, ".xml")
112
- }
113
- ]
114
- ] : [
115
- [
116
- "list"
117
- ]
118
- ],
119
- use: {
120
- trace: "retain-on-failure"
121
- },
122
- projects
123
- };
124
- };
125
- var setupPage = async (browser, options = {}) => {
126
- const { url, bridgeLogs, viewportSize } = options;
127
- const context = "newContext" in browser ? await browser.newContext() : browser;
128
- const page = await context.newPage();
129
- if (viewportSize) {
130
- await page.setViewportSize(viewportSize);
131
- }
132
- if (bridgeLogs) {
133
- const lock = new Lock();
134
- page.on("pageerror", async (error) => {
135
- await lock.executeSynchronized(async () => {
136
- console.log(error);
137
- });
138
- });
139
- page.on("console", async (msg) => {
140
- try {
141
- const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));
142
- await lock.executeSynchronized(async () => {
143
- const args = await argsPromise;
144
- if (args.length > 0) {
145
- console.log(...args);
146
- } else {
147
- console.log(msg);
148
- }
149
- });
150
- } catch (err) {
151
- console.error("Failed to parse message", err);
152
- }
153
- });
154
- }
155
- if (url) {
156
- await page.goto(url);
157
- }
158
- return {
159
- context,
160
- page
161
- };
162
- };
163
- var storybookUrl = (storyId, port = 9009) => `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;
164
- export {
165
- e2ePreset,
166
- setupPage,
167
- storybookUrl
168
- };
169
- //# sourceMappingURL=playwright.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/playwright.ts", "../../../src/lock.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\n/* eslint-disable no-console */\n\nimport { type Browser, type BrowserContext, type Page, type PlaywrightTestConfig, devices } from '@playwright/test';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nconst findWorkspaceRoot = (startDir: string): string => {\n let dir = resolve(startDir);\n while (dir !== '/') {\n try {\n // Check for pnpm-workspace.yaml first (modern pnpm approach)\n const workspaceYamlPath = join(dir, 'pnpm-workspace.yaml');\n if (existsSync(workspaceYamlPath)) {\n return dir;\n }\n\n // Check for package.json with workspaces field (legacy approach)\n const pkgPath = join(dir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n if (pkg.workspaces) {\n return dir;\n }\n } catch {}\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error('Could not find pnpm workspace root');\n};\n\nexport const e2ePreset = (testDir: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd: testDir });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirName = packageDir.split('/').pop();\n if (!packageDirName) {\n throw new Error('packageDirName not found');\n }\n\n const workspaceRoot = findWorkspaceRoot(packageDir);\n const testResultOuputDir = join(workspaceRoot, 'test-results/playwright/output', packageDirName);\n const reporterOutputFile = join(workspaceRoot, 'test-results/playwright/report', `${packageDirName}.json`);\n\n const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? 'all' : 'chromium');\n const projects = [\n {\n name: 'chromium',\n use: { ...devices['Desktop Chrome'] },\n },\n {\n name: 'firefox',\n use: { ...devices['Desktop Firefox'] },\n },\n {\n name: 'webkit',\n use: { ...devices['Desktop Safari'] },\n },\n ].filter((project) => {\n return browser === 'all' || project.name === browser;\n });\n\n return {\n testDir,\n outputDir: testResultOuputDir,\n // Run tests in files in parallel.\n fullyParallel: true,\n // Fail the build on CI if you accidentally left test.only in the source code.\n forbidOnly: !!process.env.CI,\n // Retry on CI to ride out the residual d&d / startup flakes while the\n // underlying causes are still being chased. Local runs stay strict so\n // flakes are visible while iterating.\n retries: process.env.CI ? 2 : 0,\n // Opt out of parallel tests on CI.\n workers: process.env.CI ? 1 : 4,\n // Reporter to use. See https://playwright.dev/docs/test-reporters.\n reporter: process.env.CI\n ? [\n ['list'],\n [\n 'json',\n {\n outputFile: reporterOutputFile,\n },\n ],\n ['junit', { outputFile: reporterOutputFile.replace(/\\.json$/, '.xml') }],\n ]\n : [['list']],\n use: {\n trace: 'retain-on-failure',\n },\n projects,\n };\n};\n\nexport type SetupOptions = {\n url?: string;\n bridgeLogs?: boolean;\n viewportSize?: Parameters<Page['setViewportSize']>[0];\n};\n\nexport const setupPage = async (browser: Browser | BrowserContext, options: SetupOptions = {}) => {\n const { url, bridgeLogs, viewportSize } = options;\n\n const context = 'newContext' in browser ? await browser.newContext() : browser;\n const page = await context.newPage();\n\n if (viewportSize) {\n await page.setViewportSize(viewportSize);\n }\n\n // TODO(wittjosiah): Remove?\n if (bridgeLogs) {\n const lock = new Lock();\n\n page.on('pageerror', async (error) => {\n await lock.executeSynchronized(async () => {\n // eslint-disable-next-line no-console\n console.log(error);\n });\n });\n\n page.on('console', async (msg) => {\n try {\n const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));\n await lock.executeSynchronized(async () => {\n const args = await argsPromise;\n\n if (args.length > 0) {\n console.log(...args);\n } else {\n console.log(msg);\n }\n });\n } catch (err) {\n console.error('Failed to parse message', err);\n }\n });\n }\n\n if (url) {\n await page.goto(url);\n }\n\n return { context, page };\n};\n\nexport const storybookUrl = (storyId: string, port = 9009) =>\n `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { trigger } from '@dxos/async';\n\n// Copied from @dxos/async.\nexport class Lock {\n private _lastPromise = Promise.resolve();\n\n async executeSynchronized<T>(fun: () => Promise<T>): Promise<T> {\n const prevPromise = this._lastPromise;\n const [getPromise, resolve] = trigger();\n this._lastPromise = getPromise();\n\n await prevPromise;\n try {\n const value = await fun();\n return value;\n } finally {\n resolve();\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["devices", "existsSync", "readFileSync", "dirname", "join", "resolve", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "value", "findWorkspaceRoot", "startDir", "dir", "resolve", "workspaceYamlPath", "join", "existsSync", "pkgPath", "pkg", "JSON", "parse", "readFileSync", "workspaces", "parent", "dirname", "Error", "e2ePreset", "testDir", "packageJson", "pkgUp", "sync", "cwd", "packageDir", "split", "slice", "packageDirName", "pop", "workspaceRoot", "testResultOuputDir", "reporterOutputFile", "browser", "process", "env", "PLAYWRIGHT_BROWSER", "CI", "projects", "name", "use", "devices", "filter", "project", "outputDir", "fullyParallel", "forbidOnly", "retries", "workers", "reporter", "outputFile", "replace", "trace", "setupPage", "options", "url", "bridgeLogs", "viewportSize", "context", "newContext", "page", "newPage", "setViewportSize", "lock", "Lock", "on", "error", "executeSynchronized", "console", "log", "msg", "argsPromise", "Promise", "all", "args", "map", "x", "jsonValue", "length", "err", "goto", "storybookUrl", "storyId", "port"]
7
- }
@@ -1,14 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
-
3
- // src/resource.ts
4
- import { onTestFinished } from "vitest";
5
- var openAndClose = async (...resources) => {
6
- for (const resourceLike of resources) {
7
- await resourceLike.open();
8
- onTestFinished(() => resourceLike.close());
9
- }
10
- };
11
- export {
12
- openAndClose
13
- };
14
- //# sourceMappingURL=index.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/resource.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { onTestFinished } from 'vitest';\n\ninterface ResourceLike {\n open(): Promise<any>;\n close(): Promise<any>;\n}\n\n// TODO(burdon): Replace with abstraction relating to Context object?\nexport const openAndClose = async (...resources: ResourceLike[]) => {\n for (const resourceLike of resources) {\n await resourceLike.open();\n onTestFinished(() => resourceLike.close());\n }\n};\n"],
5
- "mappings": ";;;AAIA,SAASA,sBAAsB;AAQxB,IAAMC,eAAe,UAAUC,cAAAA;AACpC,aAAWC,gBAAgBD,WAAW;AACpC,UAAMC,aAAaC,KAAI;AACvBJ,mBAAe,MAAMG,aAAaE,MAAK,CAAA;EACzC;AACF;",
6
- "names": ["onTestFinished", "openAndClose", "resources", "resourceLike", "open", "close"]
7
- }
@@ -1 +0,0 @@
1
- {"inputs":{"src/resource.ts":{"bytes":1452,"imports":[{"path":"vitest","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":376,"imports":[{"path":"src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"},"src/lock.ts":{"bytes":1942,"imports":[{"path":"@dxos/async","kind":"import-statement","external":true}],"format":"esm"},"src/playwright.ts":{"bytes":16371,"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"src/lock.ts","kind":"import-statement","original":"./lock"}],"format":"esm"}},"outputs":{"dist/lib/node-esm/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":782},"dist/lib/node-esm/index.mjs":{"imports":[{"path":"vitest","kind":"import-statement","external":true}],"exports":["openAndClose"],"entryPoint":"src/index.ts","inputs":{"src/resource.ts":{"bytesInOutput":214},"src/index.ts":{"bytesInOutput":0}},"bytes":388},"dist/lib/node-esm/playwright.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9282},"dist/lib/node-esm/playwright.mjs":{"imports":[{"path":"@playwright/test","kind":"import-statement","external":true},{"path":"node:fs","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"pkg-up","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true}],"exports":["e2ePreset","setupPage","storybookUrl"],"entryPoint":"src/playwright.ts","inputs":{"src/playwright.ts":{"bytesInOutput":3971},"src/lock.ts":{"bytesInOutput":389}},"bytes":4605}}}
@@ -1,171 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
-
3
- // src/playwright.ts
4
- import { devices } from "@playwright/test";
5
- import { existsSync, readFileSync } from "node:fs";
6
- import { dirname, join, resolve } from "node:path";
7
- import pkgUp from "pkg-up";
8
-
9
- // src/lock.ts
10
- import { trigger } from "@dxos/async";
11
- var Lock = class {
12
- _lastPromise = Promise.resolve();
13
- async executeSynchronized(fun) {
14
- const prevPromise = this._lastPromise;
15
- const [getPromise, resolve2] = trigger();
16
- this._lastPromise = getPromise();
17
- await prevPromise;
18
- try {
19
- const value = await fun();
20
- return value;
21
- } finally {
22
- resolve2();
23
- }
24
- }
25
- };
26
-
27
- // src/playwright.ts
28
- var findWorkspaceRoot = (startDir) => {
29
- let dir = resolve(startDir);
30
- while (dir !== "/") {
31
- try {
32
- const workspaceYamlPath = join(dir, "pnpm-workspace.yaml");
33
- if (existsSync(workspaceYamlPath)) {
34
- return dir;
35
- }
36
- const pkgPath = join(dir, "package.json");
37
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
38
- if (pkg.workspaces) {
39
- return dir;
40
- }
41
- } catch {
42
- }
43
- const parent = dirname(dir);
44
- if (parent === dir) {
45
- break;
46
- }
47
- dir = parent;
48
- }
49
- throw new Error("Could not find pnpm workspace root");
50
- };
51
- var e2ePreset = (testDir) => {
52
- const packageJson = pkgUp.sync({
53
- cwd: testDir
54
- });
55
- const packageDir = packageJson.split("/").slice(0, -1).join("/");
56
- const packageDirName = packageDir.split("/").pop();
57
- if (!packageDirName) {
58
- throw new Error("packageDirName not found");
59
- }
60
- const workspaceRoot = findWorkspaceRoot(packageDir);
61
- const testResultOuputDir = join(workspaceRoot, "test-results/playwright/output", packageDirName);
62
- const reporterOutputFile = join(workspaceRoot, "test-results/playwright/report", `${packageDirName}.json`);
63
- const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? "all" : "chromium");
64
- const projects = [
65
- {
66
- name: "chromium",
67
- use: {
68
- ...devices["Desktop Chrome"]
69
- }
70
- },
71
- {
72
- name: "firefox",
73
- use: {
74
- ...devices["Desktop Firefox"]
75
- }
76
- },
77
- {
78
- name: "webkit",
79
- use: {
80
- ...devices["Desktop Safari"]
81
- }
82
- }
83
- ].filter((project) => {
84
- return browser === "all" || project.name === browser;
85
- });
86
- return {
87
- testDir,
88
- outputDir: testResultOuputDir,
89
- // Run tests in files in parallel.
90
- fullyParallel: true,
91
- // Fail the build on CI if you accidentally left test.only in the source code.
92
- forbidOnly: !!process.env.CI,
93
- // Retry on CI to ride out the residual d&d / startup flakes while the
94
- // underlying causes are still being chased. Local runs stay strict so
95
- // flakes are visible while iterating.
96
- retries: process.env.CI ? 2 : 0,
97
- // Opt out of parallel tests on CI.
98
- workers: process.env.CI ? 1 : 4,
99
- // Reporter to use. See https://playwright.dev/docs/test-reporters.
100
- reporter: process.env.CI ? [
101
- [
102
- "list"
103
- ],
104
- [
105
- "json",
106
- {
107
- outputFile: reporterOutputFile
108
- }
109
- ],
110
- [
111
- "junit",
112
- {
113
- outputFile: reporterOutputFile.replace(/\.json$/, ".xml")
114
- }
115
- ]
116
- ] : [
117
- [
118
- "list"
119
- ]
120
- ],
121
- use: {
122
- trace: "retain-on-failure"
123
- },
124
- projects
125
- };
126
- };
127
- var setupPage = async (browser, options = {}) => {
128
- const { url, bridgeLogs, viewportSize } = options;
129
- const context = "newContext" in browser ? await browser.newContext() : browser;
130
- const page = await context.newPage();
131
- if (viewportSize) {
132
- await page.setViewportSize(viewportSize);
133
- }
134
- if (bridgeLogs) {
135
- const lock = new Lock();
136
- page.on("pageerror", async (error) => {
137
- await lock.executeSynchronized(async () => {
138
- console.log(error);
139
- });
140
- });
141
- page.on("console", async (msg) => {
142
- try {
143
- const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));
144
- await lock.executeSynchronized(async () => {
145
- const args = await argsPromise;
146
- if (args.length > 0) {
147
- console.log(...args);
148
- } else {
149
- console.log(msg);
150
- }
151
- });
152
- } catch (err) {
153
- console.error("Failed to parse message", err);
154
- }
155
- });
156
- }
157
- if (url) {
158
- await page.goto(url);
159
- }
160
- return {
161
- context,
162
- page
163
- };
164
- };
165
- var storybookUrl = (storyId, port = 9009) => `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;
166
- export {
167
- e2ePreset,
168
- setupPage,
169
- storybookUrl
170
- };
171
- //# sourceMappingURL=playwright.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/playwright.ts", "../../../src/lock.ts"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\n/* eslint-disable no-console */\n\nimport { type Browser, type BrowserContext, type Page, type PlaywrightTestConfig, devices } from '@playwright/test';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport pkgUp from 'pkg-up';\n\nimport { Lock } from './lock';\n\nconst findWorkspaceRoot = (startDir: string): string => {\n let dir = resolve(startDir);\n while (dir !== '/') {\n try {\n // Check for pnpm-workspace.yaml first (modern pnpm approach)\n const workspaceYamlPath = join(dir, 'pnpm-workspace.yaml');\n if (existsSync(workspaceYamlPath)) {\n return dir;\n }\n\n // Check for package.json with workspaces field (legacy approach)\n const pkgPath = join(dir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n if (pkg.workspaces) {\n return dir;\n }\n } catch {}\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error('Could not find pnpm workspace root');\n};\n\nexport const e2ePreset = (testDir: string): PlaywrightTestConfig => {\n const packageJson = pkgUp.sync({ cwd: testDir });\n const packageDir = packageJson!.split('/').slice(0, -1).join('/');\n const packageDirName = packageDir.split('/').pop();\n if (!packageDirName) {\n throw new Error('packageDirName not found');\n }\n\n const workspaceRoot = findWorkspaceRoot(packageDir);\n const testResultOuputDir = join(workspaceRoot, 'test-results/playwright/output', packageDirName);\n const reporterOutputFile = join(workspaceRoot, 'test-results/playwright/report', `${packageDirName}.json`);\n\n const browser = process.env.PLAYWRIGHT_BROWSER || (process.env.CI ? 'all' : 'chromium');\n const projects = [\n {\n name: 'chromium',\n use: { ...devices['Desktop Chrome'] },\n },\n {\n name: 'firefox',\n use: { ...devices['Desktop Firefox'] },\n },\n {\n name: 'webkit',\n use: { ...devices['Desktop Safari'] },\n },\n ].filter((project) => {\n return browser === 'all' || project.name === browser;\n });\n\n return {\n testDir,\n outputDir: testResultOuputDir,\n // Run tests in files in parallel.\n fullyParallel: true,\n // Fail the build on CI if you accidentally left test.only in the source code.\n forbidOnly: !!process.env.CI,\n // Retry on CI to ride out the residual d&d / startup flakes while the\n // underlying causes are still being chased. Local runs stay strict so\n // flakes are visible while iterating.\n retries: process.env.CI ? 2 : 0,\n // Opt out of parallel tests on CI.\n workers: process.env.CI ? 1 : 4,\n // Reporter to use. See https://playwright.dev/docs/test-reporters.\n reporter: process.env.CI\n ? [\n ['list'],\n [\n 'json',\n {\n outputFile: reporterOutputFile,\n },\n ],\n ['junit', { outputFile: reporterOutputFile.replace(/\\.json$/, '.xml') }],\n ]\n : [['list']],\n use: {\n trace: 'retain-on-failure',\n },\n projects,\n };\n};\n\nexport type SetupOptions = {\n url?: string;\n bridgeLogs?: boolean;\n viewportSize?: Parameters<Page['setViewportSize']>[0];\n};\n\nexport const setupPage = async (browser: Browser | BrowserContext, options: SetupOptions = {}) => {\n const { url, bridgeLogs, viewportSize } = options;\n\n const context = 'newContext' in browser ? await browser.newContext() : browser;\n const page = await context.newPage();\n\n if (viewportSize) {\n await page.setViewportSize(viewportSize);\n }\n\n // TODO(wittjosiah): Remove?\n if (bridgeLogs) {\n const lock = new Lock();\n\n page.on('pageerror', async (error) => {\n await lock.executeSynchronized(async () => {\n // eslint-disable-next-line no-console\n console.log(error);\n });\n });\n\n page.on('console', async (msg) => {\n try {\n const argsPromise = Promise.all(msg.args().map((x) => x.jsonValue()));\n await lock.executeSynchronized(async () => {\n const args = await argsPromise;\n\n if (args.length > 0) {\n console.log(...args);\n } else {\n console.log(msg);\n }\n });\n } catch (err) {\n console.error('Failed to parse message', err);\n }\n });\n }\n\n if (url) {\n await page.goto(url);\n }\n\n return { context, page };\n};\n\nexport const storybookUrl = (storyId: string, port = 9009) =>\n `http://localhost:${port}/iframe.html?id=${storyId}&viewMode=story`;\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { trigger } from '@dxos/async';\n\n// Copied from @dxos/async.\nexport class Lock {\n private _lastPromise = Promise.resolve();\n\n async executeSynchronized<T>(fun: () => Promise<T>): Promise<T> {\n const prevPromise = this._lastPromise;\n const [getPromise, resolve] = trigger();\n this._lastPromise = getPromise();\n\n await prevPromise;\n try {\n const value = await fun();\n return value;\n } finally {\n resolve();\n }\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["devices", "existsSync", "readFileSync", "dirname", "join", "resolve", "pkgUp", "trigger", "Lock", "_lastPromise", "Promise", "resolve", "executeSynchronized", "fun", "prevPromise", "getPromise", "value", "findWorkspaceRoot", "startDir", "dir", "resolve", "workspaceYamlPath", "join", "existsSync", "pkgPath", "pkg", "JSON", "parse", "readFileSync", "workspaces", "parent", "dirname", "Error", "e2ePreset", "testDir", "packageJson", "pkgUp", "sync", "cwd", "packageDir", "split", "slice", "packageDirName", "pop", "workspaceRoot", "testResultOuputDir", "reporterOutputFile", "browser", "process", "env", "PLAYWRIGHT_BROWSER", "CI", "projects", "name", "use", "devices", "filter", "project", "outputDir", "fullyParallel", "forbidOnly", "retries", "workers", "reporter", "outputFile", "replace", "trace", "setupPage", "options", "url", "bridgeLogs", "viewportSize", "context", "newContext", "page", "newPage", "setViewportSize", "lock", "Lock", "on", "error", "executeSynchronized", "console", "log", "msg", "argsPromise", "Promise", "all", "args", "map", "x", "jsonValue", "length", "err", "goto", "storybookUrl", "storyId", "port"]
7
- }