@untestutils/playwright 0.5.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/LICENSE +21 -0
- package/dist/harness.d.ts +19 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.mjs +41 -0
- package/dist/index.d.mts +56 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +119 -0
- package/dist/pw-global-setup.d.mts +1 -0
- package/dist/pw-global-setup.d.ts +2 -0
- package/dist/pw-global-setup.d.ts.map +1 -0
- package/dist/pw-global-setup.mjs +1 -0
- package/dist/pw-global-teardown.d.mts +1 -0
- package/dist/pw-global-teardown.d.ts +2 -0
- package/dist/pw-global-teardown.d.ts.map +1 -0
- package/dist/pw-global-teardown.mjs +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 s00d
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Recipe } from '@untestutils/core';
|
|
2
|
+
/**
|
|
3
|
+
* Prepare (or reuse) the harness and ensure `UNTESTUTILS_HOST_*` is set in
|
|
4
|
+
* *this* worker process. Cross-process reuse only writes `targets.json`;
|
|
5
|
+
* workers must apply env locally before reading `baseURL`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolvePlaywrightHarnessId(harness: string | Recipe): Promise<string>;
|
|
8
|
+
export declare function resolvePlaywrightBaseURL(harnessId: string): string;
|
|
9
|
+
export declare function usePlaywrightHarnessId(harness: string | Recipe, use: (id: string) => Promise<void>): Promise<void>;
|
|
10
|
+
type TestFixtures = {
|
|
11
|
+
baseURL: string;
|
|
12
|
+
};
|
|
13
|
+
type WorkerFixtures = {
|
|
14
|
+
harness: string | Recipe;
|
|
15
|
+
harnessId: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & TestFixtures, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions & WorkerFixtures>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,MAAM,EACZ,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB1F;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKlE;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,KAAK,YAAY,GAAG;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,IAAI,6QAWf,CAAC"}
|
package/dist/harness.mjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { test as base } from "@playwright/test";
|
|
2
|
+
import { ensurePrepared, getRegisteredRecipe, normalizeBaseUrl, resolveArtifactsRoot, envKey, TargetRegistry } from "@untestutils/core";
|
|
3
|
+
|
|
4
|
+
export async function resolvePlaywrightHarnessId(harness) {
|
|
5
|
+
const id = typeof harness === "string" ? harness : harness.id;
|
|
6
|
+
if (!id) throw new Error("[untestutils/playwright] test.use({ harness }) required");
|
|
7
|
+
const recipe = typeof harness === "string" ? getRegisteredRecipe(harness) : harness;
|
|
8
|
+
if (!recipe) throw new Error(`[untestutils/playwright] unknown harness "${id}"`);
|
|
9
|
+
const artifactsRoot = resolveArtifactsRoot();
|
|
10
|
+
const prepared = await ensurePrepared(recipe, { artifactsRoot });
|
|
11
|
+
const runningUrl = "url" in prepared.running ? prepared.running.url : undefined;
|
|
12
|
+
if (runningUrl) {
|
|
13
|
+
process.env[envKey(id)] = normalizeBaseUrl(runningUrl);
|
|
14
|
+
} else {
|
|
15
|
+
const registry = new TargetRegistry(artifactsRoot);
|
|
16
|
+
const entry = await registry.get(id);
|
|
17
|
+
if (entry) registry.applyEnv(entry);
|
|
18
|
+
}
|
|
19
|
+
return id;
|
|
20
|
+
}
|
|
21
|
+
export function resolvePlaywrightBaseURL(harnessId) {
|
|
22
|
+
const key = envKey(harnessId);
|
|
23
|
+
const url = process.env[key];
|
|
24
|
+
if (!url) throw new Error(`[untestutils/playwright] missing ${key}`);
|
|
25
|
+
return normalizeBaseUrl(url);
|
|
26
|
+
}
|
|
27
|
+
export async function usePlaywrightHarnessId(harness, use) {
|
|
28
|
+
await use(await resolvePlaywrightHarnessId(harness));
|
|
29
|
+
}
|
|
30
|
+
export const test = base.extend({
|
|
31
|
+
harness: ["", {
|
|
32
|
+
option: true,
|
|
33
|
+
scope: "worker"
|
|
34
|
+
}],
|
|
35
|
+
harnessId: [async ({ harness }, use) => {
|
|
36
|
+
await usePlaywrightHarnessId(harness, use);
|
|
37
|
+
}, { scope: "worker" }],
|
|
38
|
+
baseURL: async ({ harnessId }, use) => {
|
|
39
|
+
await use(resolvePlaywrightBaseURL(harnessId));
|
|
40
|
+
}
|
|
41
|
+
});
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type RecipeRegistry } from "@untestutils/core";
|
|
2
|
+
export interface PlaywrightHarnessOptions {
|
|
3
|
+
/** Recipe map from `defineRecipes(...)` — import and pass it. */
|
|
4
|
+
recipes?: RecipeRegistry;
|
|
5
|
+
/** Override recipes module path; usually inferred from `defineRecipes`. */
|
|
6
|
+
recipesModule?: string;
|
|
7
|
+
prewarm?: string[];
|
|
8
|
+
/**
|
|
9
|
+
* Absolute or cwd-relative artifacts root. When set, takes precedence over
|
|
10
|
+
* `session` namespacing.
|
|
11
|
+
*/
|
|
12
|
+
artifactsRoot?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Isolate TargetRegistry / locks / builds under
|
|
15
|
+
* `.untestutils/sessions/<session>/` so parallel Playwright runs (or PW +
|
|
16
|
+
* Vitest) do not tear down each other's servers.
|
|
17
|
+
*/
|
|
18
|
+
session?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Expand into Playwright `projects` (one per engine) when `projects` is not
|
|
21
|
+
* already set. Default `['chromium']`.
|
|
22
|
+
*/
|
|
23
|
+
browsers?: Array<"chromium" | "firefox" | "webkit">;
|
|
24
|
+
}
|
|
25
|
+
type PWConfig = Record<string, unknown> & {
|
|
26
|
+
use?: Record<string, unknown>;
|
|
27
|
+
globalSetup?: string;
|
|
28
|
+
globalTeardown?: string;
|
|
29
|
+
workers?: number;
|
|
30
|
+
fullyParallel?: boolean;
|
|
31
|
+
};
|
|
32
|
+
/** Sanitize session segment for filesystem / env use. */
|
|
33
|
+
export declare function sanitizePlaywrightSession(session: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Resolve the artifacts root for a Playwright run.
|
|
36
|
+
* Explicit `artifactsRoot` wins; otherwise `session` / `UNTESTUTILS_SESSION`
|
|
37
|
+
* nests under the default `.untestutils` root.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolvePlaywrightArtifactsRoot(opts?: {
|
|
40
|
+
artifactsRoot?: string;
|
|
41
|
+
session?: string;
|
|
42
|
+
cwd?: string;
|
|
43
|
+
}): string;
|
|
44
|
+
/**
|
|
45
|
+
* Build a Playwright Test config that shares the same recipes.ts as Vitest.
|
|
46
|
+
*
|
|
47
|
+
* Defaults (overridable via rest fields):
|
|
48
|
+
* - `fullyParallel: true`
|
|
49
|
+
* - `workers: 2` when `CI` is set (local runs keep Playwright's CPU default)
|
|
50
|
+
*/
|
|
51
|
+
export declare function createPlaywrightConfig(opts: PlaywrightHarnessOptions & PWConfig): PWConfig;
|
|
52
|
+
export declare function playwrightGlobalSetup(): Promise<void>;
|
|
53
|
+
export declare function playwrightGlobalTeardown(): Promise<void>;
|
|
54
|
+
export { resolvePlaywrightHarnessId, resolvePlaywrightBaseURL, usePlaywrightHarnessId, test } from "./harness.mjs";
|
|
55
|
+
export { expect } from "@playwright/test";
|
|
56
|
+
export { defineRecipes, useHarness } from "@untestutils/core";
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type RecipeRegistry } from '@untestutils/core';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
export interface PlaywrightHarnessOptions {
|
|
6
|
+
/** Recipe map from `defineRecipes(...)` — import and pass it. */
|
|
7
|
+
recipes?: RecipeRegistry;
|
|
8
|
+
/** Override recipes module path; usually inferred from `defineRecipes`. */
|
|
9
|
+
recipesModule?: string;
|
|
10
|
+
prewarm?: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Absolute or cwd-relative artifacts root. When set, takes precedence over
|
|
13
|
+
* `session` namespacing.
|
|
14
|
+
*/
|
|
15
|
+
artifactsRoot?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Isolate TargetRegistry / locks / builds under
|
|
18
|
+
* `.untestutils/sessions/<session>/` so parallel Playwright runs (or PW +
|
|
19
|
+
* Vitest) do not tear down each other's servers.
|
|
20
|
+
*/
|
|
21
|
+
session?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Expand into Playwright `projects` (one per engine) when `projects` is not
|
|
24
|
+
* already set. Default `['chromium']`.
|
|
25
|
+
*/
|
|
26
|
+
browsers?: Array<'chromium' | 'firefox' | 'webkit'>;
|
|
27
|
+
}
|
|
28
|
+
type PWConfig = Record<string, unknown> & {
|
|
29
|
+
use?: Record<string, unknown>;
|
|
30
|
+
globalSetup?: string;
|
|
31
|
+
globalTeardown?: string;
|
|
32
|
+
workers?: number;
|
|
33
|
+
fullyParallel?: boolean;
|
|
34
|
+
};
|
|
35
|
+
/** Sanitize session segment for filesystem / env use. */
|
|
36
|
+
export declare function sanitizePlaywrightSession(session: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the artifacts root for a Playwright run.
|
|
39
|
+
* Explicit `artifactsRoot` wins; otherwise `session` / `UNTESTUTILS_SESSION`
|
|
40
|
+
* nests under the default `.untestutils` root.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolvePlaywrightArtifactsRoot(opts?: {
|
|
43
|
+
artifactsRoot?: string;
|
|
44
|
+
session?: string;
|
|
45
|
+
cwd?: string;
|
|
46
|
+
}): string;
|
|
47
|
+
/**
|
|
48
|
+
* Build a Playwright Test config that shares the same recipes.ts as Vitest.
|
|
49
|
+
*
|
|
50
|
+
* Defaults (overridable via rest fields):
|
|
51
|
+
* - `fullyParallel: true`
|
|
52
|
+
* - `workers: 2` when `CI` is set (local runs keep Playwright's CPU default)
|
|
53
|
+
*/
|
|
54
|
+
export declare function createPlaywrightConfig(opts: PlaywrightHarnessOptions & PWConfig): PWConfig;
|
|
55
|
+
/** @internal */
|
|
56
|
+
export declare const playwrightCompanionIo: {
|
|
57
|
+
createRequire: typeof createRequire;
|
|
58
|
+
existsSync: typeof existsSync;
|
|
59
|
+
fileURLToPath: typeof fileURLToPath;
|
|
60
|
+
};
|
|
61
|
+
/** @internal */
|
|
62
|
+
export declare function resolvePlaywrightCompanion(name: 'pw-global-setup' | 'pw-global-teardown'): string;
|
|
63
|
+
export declare function playwrightGlobalSetup(): Promise<void>;
|
|
64
|
+
export declare function playwrightGlobalTeardown(): Promise<void>;
|
|
65
|
+
export { resolvePlaywrightHarnessId, resolvePlaywrightBaseURL, usePlaywrightHarnessId, test, } from './harness';
|
|
66
|
+
export { expect } from '@playwright/test';
|
|
67
|
+
export { defineRecipes, useHarness } from '@untestutils/core';
|
|
68
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,WAAW,wBAAwB;IACvC,iEAAiE;IACjE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC,CAAC;CACrD;AAED,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,yDAAyD;AACzD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMjE;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,GAAE;IACJ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACT,GACL,MAAM,CAOR;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,wBAAwB,GAAG,QAAQ,GAAG,QAAQ,CA8C1F;AAMD,gBAAgB;AAChB,eAAO,MAAM,qBAAqB;;;;CAIjC,CAAC;AAEF,gBAAgB;AAChB,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,iBAAiB,GAAG,oBAAoB,GAAG,MAAM,CAsBjG;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CA8B3D;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9D;AAED,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,IAAI,GACL,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { ensureRecipes, getRegisteredRecipe, getRecipesModulePath, ensurePrepared, stopAllTargets, resolveArtifactsRoot, progress, TargetRegistry } from "@untestutils/core";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { dirname, join, resolve } from "pathe";
|
|
6
|
+
|
|
7
|
+
export function sanitizePlaywrightSession(session) {
|
|
8
|
+
const s = session.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
9
|
+
if (!s) {
|
|
10
|
+
throw new Error("[untestutils/playwright] session must be a non-empty identifier");
|
|
11
|
+
}
|
|
12
|
+
return s;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolvePlaywrightArtifactsRoot(opts = {}) {
|
|
16
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
17
|
+
if (opts.artifactsRoot) return resolve(cwd, opts.artifactsRoot);
|
|
18
|
+
const base = resolveArtifactsRoot(cwd);
|
|
19
|
+
const session = opts.session ?? process.env.UNTESTUTILS_SESSION;
|
|
20
|
+
if (session) return join(base, "sessions", sanitizePlaywrightSession(session));
|
|
21
|
+
return base;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createPlaywrightConfig(opts) {
|
|
25
|
+
const { recipes, recipesModule, prewarm = [], artifactsRoot, session, browsers: browsersOpt, ...rest } = opts;
|
|
26
|
+
if (recipes) ensureRecipes(recipes);
|
|
27
|
+
const resolvedRoot = resolvePlaywrightArtifactsRoot({
|
|
28
|
+
artifactsRoot,
|
|
29
|
+
session
|
|
30
|
+
});
|
|
31
|
+
process.env.UNTESTUTILS_ARTIFACTS_DIR = resolvedRoot;
|
|
32
|
+
if (session) process.env.UNTESTUTILS_SESSION = sanitizePlaywrightSession(session);
|
|
33
|
+
else if (!artifactsRoot) delete process.env.UNTESTUTILS_SESSION;
|
|
34
|
+
process.env.UNTESTUTILS_PREWARM = JSON.stringify(prewarm);
|
|
35
|
+
const mod = recipesModule ?? getRecipesModulePath();
|
|
36
|
+
if (mod) process.env.UNTESTUTILS_RECIPES_MODULE = mod;
|
|
37
|
+
const browsers = browsersOpt?.length ? browsersOpt : undefined;
|
|
38
|
+
const defaults = { fullyParallel: true };
|
|
39
|
+
if (process.env.CI && rest.workers === undefined) {
|
|
40
|
+
defaults.workers = 2;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (browsers?.length && rest.projects === undefined) {
|
|
44
|
+
defaults.projects = browsers.map((browserName) => ({
|
|
45
|
+
name: browserName,
|
|
46
|
+
use: { browserName }
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
...defaults,
|
|
51
|
+
...rest,
|
|
52
|
+
use: { ...rest.use ?? {} },
|
|
53
|
+
globalSetup: companion("pw-global-setup"),
|
|
54
|
+
globalTeardown: companion("pw-global-teardown")
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function companion(name) {
|
|
58
|
+
return resolvePlaywrightCompanion(name);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const playwrightCompanionIo = {
|
|
62
|
+
createRequire,
|
|
63
|
+
existsSync,
|
|
64
|
+
fileURLToPath
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export function resolvePlaywrightCompanion(name) {
|
|
68
|
+
const req = playwrightCompanionIo.createRequire(join(process.cwd(), "package.json"));
|
|
69
|
+
for (const id of [`untestutils/playwright/${name}`, `@untestutils/playwright/${name}`]) {
|
|
70
|
+
try {
|
|
71
|
+
return req.resolve(id);
|
|
72
|
+
} catch {}
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const pkgRoot = dirname(req.resolve("@untestutils/playwright/package.json"));
|
|
76
|
+
const mjs = join(pkgRoot, "dist", `${name}.mjs`);
|
|
77
|
+
if (playwrightCompanionIo.existsSync(mjs)) return mjs;
|
|
78
|
+
const ts = join(pkgRoot, "src", `${name}.ts`);
|
|
79
|
+
if (playwrightCompanionIo.existsSync(ts)) return ts;
|
|
80
|
+
} catch {}
|
|
81
|
+
const here = dirname(playwrightCompanionIo.fileURLToPath(import.meta.url));
|
|
82
|
+
const localTs = join(here, `${name}.ts`);
|
|
83
|
+
if (playwrightCompanionIo.existsSync(localTs)) return localTs;
|
|
84
|
+
throw new Error(`[untestutils/playwright] missing ${name}`);
|
|
85
|
+
}
|
|
86
|
+
export async function playwrightGlobalSetup() {
|
|
87
|
+
const modPath = process.env.UNTESTUTILS_RECIPES_MODULE;
|
|
88
|
+
let recipesFromModule;
|
|
89
|
+
if (modPath) {
|
|
90
|
+
const { pathToFileURL } = await import("node:url");
|
|
91
|
+
const loaded = await import(pathToFileURL(modPath).href);
|
|
92
|
+
recipesFromModule = loaded.recipes;
|
|
93
|
+
}
|
|
94
|
+
const artifactsRoot = resolveArtifactsRoot();
|
|
95
|
+
await stopAllTargets(artifactsRoot);
|
|
96
|
+
const registry = new TargetRegistry(artifactsRoot);
|
|
97
|
+
const prewarm = JSON.parse(process.env.UNTESTUTILS_PREWARM || "[]");
|
|
98
|
+
if (prewarm.length) {
|
|
99
|
+
progress.waveStart(prewarm);
|
|
100
|
+
for (const id of prewarm) {
|
|
101
|
+
const recipe = recipesFromModule?.[id] ?? getRegisteredRecipe(id);
|
|
102
|
+
if (!recipe) {
|
|
103
|
+
throw new Error(`[untestutils/playwright] prewarm "${id}" missing — import recipes via defineRecipes(..., import.meta.url)`);
|
|
104
|
+
}
|
|
105
|
+
await ensurePrepared(recipe, { artifactsRoot });
|
|
106
|
+
}
|
|
107
|
+
progress.waveReady();
|
|
108
|
+
progress.massRun();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
registry.applyAllToEnv(await registry.read());
|
|
112
|
+
}
|
|
113
|
+
export async function playwrightGlobalTeardown() {
|
|
114
|
+
progress.teardown();
|
|
115
|
+
await stopAllTargets(resolveArtifactsRoot());
|
|
116
|
+
}
|
|
117
|
+
export { resolvePlaywrightHarnessId, resolvePlaywrightBaseURL, usePlaywrightHarnessId, test } from "./harness.mjs";
|
|
118
|
+
export { expect } from "@playwright/test";
|
|
119
|
+
export { defineRecipes, useHarness } from "@untestutils/core";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { playwrightGlobalSetup as default } from "./index.mjs";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pw-global-setup.d.ts","sourceRoot":"","sources":["../src/pw-global-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { playwrightGlobalSetup as default } from "./index.mjs";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { playwrightGlobalTeardown as default } from "./index.mjs";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pw-global-teardown.d.ts","sourceRoot":"","sources":["../src/pw-global-teardown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { playwrightGlobalTeardown as default } from "./index.mjs";
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@untestutils/playwright",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"files": [
|
|
5
|
+
"dist"
|
|
6
|
+
],
|
|
7
|
+
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./pw-global-setup": {
|
|
16
|
+
"types": "./dist/pw-global-setup.d.ts",
|
|
17
|
+
"import": "./dist/pw-global-setup.mjs",
|
|
18
|
+
"default": "./dist/pw-global-setup.mjs"
|
|
19
|
+
},
|
|
20
|
+
"./pw-global-teardown": {
|
|
21
|
+
"types": "./dist/pw-global-teardown.d.ts",
|
|
22
|
+
"import": "./dist/pw-global-teardown.mjs",
|
|
23
|
+
"default": "./dist/pw-global-teardown.mjs"
|
|
24
|
+
},
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"pathe": "^2.0.3",
|
|
29
|
+
"@untestutils/core": "0.5.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@playwright/test": "^1.63.0",
|
|
33
|
+
"@types/node": "^26.6.1",
|
|
34
|
+
"publint": "^0.3.24",
|
|
35
|
+
"typescript": "^6.0.3",
|
|
36
|
+
"obuild": "^0.4.40"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@playwright/test": "^1.63.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
},
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"homepage": "https://s00d.github.io/untestutils/",
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/s00d/untestutils.git",
|
|
49
|
+
"directory": "packages/playwright"
|
|
50
|
+
},
|
|
51
|
+
"main": "./dist/index.mjs",
|
|
52
|
+
"types": "./dist/index.d.ts",
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "obuild && tsc -p tsconfig.build.json",
|
|
58
|
+
"publint": "publint --strict"
|
|
59
|
+
}
|
|
60
|
+
}
|