@emesoft_company/playwright-core 2.1.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 (92) hide show
  1. package/README.md +62 -0
  2. package/dist/api/index.cjs +248 -0
  3. package/dist/api/index.cjs.map +1 -0
  4. package/dist/api/index.d.cts +12 -0
  5. package/dist/api/index.d.ts +12 -0
  6. package/dist/api/index.js +245 -0
  7. package/dist/api/index.js.map +1 -0
  8. package/dist/api-client-C_StjpPX.d.ts +58 -0
  9. package/dist/api-client-CpXo_NOU.d.cts +58 -0
  10. package/dist/auth/index.cjs +310 -0
  11. package/dist/auth/index.cjs.map +1 -0
  12. package/dist/auth/index.d.cts +98 -0
  13. package/dist/auth/index.d.ts +98 -0
  14. package/dist/auth/index.js +304 -0
  15. package/dist/auth/index.js.map +1 -0
  16. package/dist/config/index.cjs +268 -0
  17. package/dist/config/index.cjs.map +1 -0
  18. package/dist/config/index.d.cts +105 -0
  19. package/dist/config/index.d.ts +105 -0
  20. package/dist/config/index.js +254 -0
  21. package/dist/config/index.js.map +1 -0
  22. package/dist/data/index.cjs +59 -0
  23. package/dist/data/index.cjs.map +1 -0
  24. package/dist/data/index.d.cts +25 -0
  25. package/dist/data/index.d.ts +25 -0
  26. package/dist/data/index.js +50 -0
  27. package/dist/data/index.js.map +1 -0
  28. package/dist/di/index.cjs +47 -0
  29. package/dist/di/index.cjs.map +1 -0
  30. package/dist/di/index.d.cts +19 -0
  31. package/dist/di/index.d.ts +19 -0
  32. package/dist/di/index.js +45 -0
  33. package/dist/di/index.js.map +1 -0
  34. package/dist/errors/index.cjs +90 -0
  35. package/dist/errors/index.cjs.map +1 -0
  36. package/dist/errors/index.d.cts +38 -0
  37. package/dist/errors/index.d.ts +38 -0
  38. package/dist/errors/index.js +83 -0
  39. package/dist/errors/index.js.map +1 -0
  40. package/dist/expect/index.cjs +36 -0
  41. package/dist/expect/index.cjs.map +1 -0
  42. package/dist/expect/index.d.cts +30 -0
  43. package/dist/expect/index.d.ts +30 -0
  44. package/dist/expect/index.js +34 -0
  45. package/dist/expect/index.js.map +1 -0
  46. package/dist/fixtures/index.cjs +660 -0
  47. package/dist/fixtures/index.cjs.map +1 -0
  48. package/dist/fixtures/index.d.cts +68 -0
  49. package/dist/fixtures/index.d.ts +68 -0
  50. package/dist/fixtures/index.js +651 -0
  51. package/dist/fixtures/index.js.map +1 -0
  52. package/dist/index.cjs +1322 -0
  53. package/dist/index.cjs.map +1 -0
  54. package/dist/index.d.cts +21 -0
  55. package/dist/index.d.ts +21 -0
  56. package/dist/index.js +1248 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/logging/index.cjs +32 -0
  59. package/dist/logging/index.cjs.map +1 -0
  60. package/dist/logging/index.d.cts +18 -0
  61. package/dist/logging/index.d.ts +18 -0
  62. package/dist/logging/index.js +25 -0
  63. package/dist/logging/index.js.map +1 -0
  64. package/dist/reporting/index.cjs +59 -0
  65. package/dist/reporting/index.cjs.map +1 -0
  66. package/dist/reporting/index.d.cts +63 -0
  67. package/dist/reporting/index.d.ts +63 -0
  68. package/dist/reporting/index.js +52 -0
  69. package/dist/reporting/index.js.map +1 -0
  70. package/dist/retry-XqnSC8YL.d.cts +27 -0
  71. package/dist/retry-XqnSC8YL.d.ts +27 -0
  72. package/dist/schema-y5w2hbT-.d.cts +292 -0
  73. package/dist/schema-y5w2hbT-.d.ts +292 -0
  74. package/dist/types-CbWnSYEK.d.cts +5 -0
  75. package/dist/types-CbWnSYEK.d.ts +5 -0
  76. package/dist/types-CopwwpSW.d.cts +8 -0
  77. package/dist/types-CopwwpSW.d.ts +8 -0
  78. package/dist/types-hInbkPXf.d.cts +59 -0
  79. package/dist/types-hInbkPXf.d.ts +59 -0
  80. package/dist/ui/index.cjs +366 -0
  81. package/dist/ui/index.cjs.map +1 -0
  82. package/dist/ui/index.d.cts +190 -0
  83. package/dist/ui/index.d.ts +190 -0
  84. package/dist/ui/index.js +348 -0
  85. package/dist/ui/index.js.map +1 -0
  86. package/dist/utils/index.cjs +72 -0
  87. package/dist/utils/index.cjs.map +1 -0
  88. package/dist/utils/index.d.cts +27 -0
  89. package/dist/utils/index.d.ts +27 -0
  90. package/dist/utils/index.js +66 -0
  91. package/dist/utils/index.js.map +1 -0
  92. package/package.json +133 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/app-error.ts","../src/utils/deep-merge.ts","../src/config/schema.ts","../src/config/loader.ts","../src/config/env.ts","../src/reporting/allure-setup.ts","../src/config/define-config.ts","../src/auth/token-provider.ts","../src/utils/sleep.ts","../src/errors/retry.ts","../src/api/interceptors.ts","../src/api/api-client.ts","../src/logging/logger.ts","../src/reporting/meta.ts","../src/fixtures/auth.fixture.ts","../src/reporting/attachments.ts","../src/fixtures/diagnostics.fixture.ts","../src/expect/matchers.ts","../src/fixtures/base-test.ts","../src/auth/global-setup.ts","../src/ui/actions.ts","../src/ui/components/base-page.ts","../src/ui/components/base-component.ts","../src/ui/components/table.component.ts","../src/di/container.ts","../src/utils/wait.ts","../src/data/generators.ts"],"names":["base","logger","baseExpect"],"mappings":"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","file":"index.js","sourcesContent":["export interface AppErrorOptions {\n code: string;\n cause?: unknown;\n context?: Record<string, unknown>;\n}\n\n/**\n * Base error class for the framework. Every error thrown by core carries a\n * machine-readable `code` and optional `context`, so callers can branch on\n * `error.code` instead of parsing messages.\n */\nexport class AppError extends Error {\n readonly code: string;\n readonly context?: Record<string, unknown>;\n\n constructor(message: string, options: AppErrorOptions) {\n super(message, { cause: options.cause });\n this.name = new.target.name;\n this.code = options.code;\n this.context = options.context;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class ConfigValidationError extends AppError {\n constructor(message: string, issues: unknown, context?: Record<string, unknown>) {\n super(message, { code: \"CONFIG_VALIDATION_ERROR\", context: { issues, ...context } });\n }\n}\n\nexport class ApiError extends AppError {\n readonly status?: number;\n readonly method?: string;\n readonly url?: string;\n\n constructor(\n message: string,\n options: AppErrorOptions & { status?: number; method?: string; url?: string },\n ) {\n super(message, options);\n this.status = options.status;\n this.method = options.method;\n this.url = options.url;\n }\n}\n\nexport class AuthError extends AppError {\n constructor(message: string, options: Omit<AppErrorOptions, \"code\"> = {}) {\n super(message, { code: \"AUTH_ERROR\", ...options });\n }\n}\n\nexport class ConfigMissingError extends AppError {\n constructor(name: string) {\n super(`Required environment variable \"${name}\" is not set`, {\n code: \"ENV_VAR_MISSING\",\n context: { name },\n });\n }\n}\n","export function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Recursively merges `override` onto `base`. Arrays and primitives replace wholesale;\n * only plain objects are merged key by key. `undefined` values in `override` are ignored,\n * so a partial object never accidentally erases a configured value.\n */\nexport function deepMerge<T>(base: T, override: unknown): T {\n if (override === undefined) return base;\n if (!isPlainObject(base) || !isPlainObject(override)) {\n return override as T;\n }\n const result: Record<string, unknown> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const baseValue = (base as Record<string, unknown>)[key];\n result[key] = isPlainObject(baseValue) && isPlainObject(value) ? deepMerge(baseValue, value) : value;\n }\n return result as T;\n}\n\n/** Strips `undefined` values and empty nested objects, so zod defaults apply instead. */\nexport function pruneUndefined(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(pruneUndefined);\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n if (val === undefined) continue;\n const pruned = pruneUndefined(val);\n if (isPlainObject(pruned) && Object.keys(pruned).length === 0) continue;\n result[key] = pruned;\n }\n return result;\n }\n return value;\n}\n","import { z } from \"zod\";\n\n/** Environments seen most often across projects — autocompleted, but any string is accepted. */\nexport const KNOWN_ENVIRONMENTS = [\"local\", \"dev\", \"qa\", \"uat\", \"staging\", \"prod\"] as const;\n\n/**\n * Free-form on purpose: teams run `uat`, `qa`, `sit`, per-tenant envs and so on. The union\n * below keeps editor autocomplete for the common ones without rejecting anything else\n * (`(string & {})` is the TS idiom that preserves suggestions on an open string type).\n */\nexport type Environment = (typeof KNOWN_ENVIRONMENTS)[number] | (string & {});\n\nexport const EnvironmentSchema = z.string().min(1);\n\nexport const TimeoutsSchema = z.object({\n actionMs: z.number().int().positive().default(15_000),\n navigationMs: z.number().int().positive().default(30_000),\n testMs: z.number().int().positive().default(60_000),\n /** Default budget for `waitForCondition` and other non-locator polling. */\n waitMs: z.number().int().positive().default(30_000),\n});\n\nexport const AuthConfigSchema = z\n .object({\n tokenUrl: z.string().url().optional(),\n clientId: z.string().optional(),\n clientSecret: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n /** Single-session storage state file (see `buildGlobalSetup`). */\n storageStatePath: z.string().optional(),\n /** Directory used for per-role storage state files in multi-role setups. */\n storageStateDir: z.string().default(\".auth\"),\n })\n .default({});\n\nexport const ReportingConfigSchema = z\n .object({\n allureEnabled: z.boolean().default(false),\n resultsDir: z.string().default(\"allure-results\"),\n /** `{id}` is replaced with a test-case id — see `meta()` in `@emesoft_company/playwright-core/reporting`. */\n testCaseUrlTemplate: z.string().optional(),\n })\n .default({});\n\nexport const RetryConfigSchema = z\n .object({\n retries: z.number().int().min(0).default(2),\n minDelayMs: z.number().int().positive().default(200),\n maxDelayMs: z.number().int().positive().default(5_000),\n })\n .default({});\n\nexport const DiagnosticsConfigSchema = z\n .object({\n /** Collect browser console errors + failed requests and attach them to the report. */\n enabled: z.boolean().default(true),\n /** Fail the test if the page logged a console error. Off by default — many apps are noisy. */\n failOnConsoleError: z.boolean().default(false),\n /** Fail the test on an uncaught page exception. */\n failOnPageError: z.boolean().default(false),\n /** Console messages matching any of these substrings are ignored entirely. */\n ignoreConsolePatterns: z.array(z.string()).default([]),\n })\n .default({});\n\n/**\n * Base config schema shared by every project. Projects extend this via\n * `AppConfigSchema.extend({ ... })` or by nesting project-specific fields\n * under `custom` — core never hardcodes project business fields here.\n */\nexport const AppConfigSchema = z.object({\n environment: EnvironmentSchema,\n baseUrl: z.string().url(),\n apiBaseUrl: z.string().url().optional(),\n tenant: z.string().optional(),\n timeouts: TimeoutsSchema.default({}),\n auth: AuthConfigSchema,\n reporting: ReportingConfigSchema,\n retry: RetryConfigSchema,\n diagnostics: DiagnosticsConfigSchema,\n logLevel: z.enum([\"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\", \"silent\"]).default(\"info\"),\n custom: z.record(z.string(), z.unknown()).default({}),\n});\n\nexport type AppConfig = Omit<z.infer<typeof AppConfigSchema>, \"environment\"> & {\n environment: Environment;\n};\nexport type TimeoutsConfig = z.infer<typeof TimeoutsSchema>;\nexport type AuthConfig = z.infer<typeof AuthConfigSchema>;\nexport type ReportingConfig = z.infer<typeof ReportingConfigSchema>;\nexport type RetryConfig = z.infer<typeof RetryConfigSchema>;\nexport type DiagnosticsConfig = z.infer<typeof DiagnosticsConfigSchema>;\n","import { ConfigMissingError, ConfigValidationError } from \"../errors/app-error.js\";\nimport { deepMerge, pruneUndefined } from \"../utils/deep-merge.js\";\nimport { AppConfigSchema, type AppConfig } from \"./schema.js\";\nimport type { DeepPartial } from \"./types.js\";\n\nfunction readEnvConfig(env: NodeJS.ProcessEnv): Record<string, unknown> {\n return {\n environment: env.TEST_ENV ?? \"dev\",\n baseUrl: env.BASE_URL,\n apiBaseUrl: env.API_BASE_URL,\n tenant: env.TENANT,\n logLevel: env.LOG_LEVEL,\n timeouts: {\n actionMs: env.ACTION_TIMEOUT_MS ? Number(env.ACTION_TIMEOUT_MS) : undefined,\n navigationMs: env.NAVIGATION_TIMEOUT_MS ? Number(env.NAVIGATION_TIMEOUT_MS) : undefined,\n testMs: env.TEST_TIMEOUT_MS ? Number(env.TEST_TIMEOUT_MS) : undefined,\n waitMs: env.WAIT_TIMEOUT_MS ? Number(env.WAIT_TIMEOUT_MS) : undefined,\n },\n auth: {\n tokenUrl: env.AUTH_TOKEN_URL,\n clientId: env.AUTH_CLIENT_ID,\n clientSecret: env.AUTH_CLIENT_SECRET,\n username: env.AUTH_USERNAME,\n password: env.AUTH_PASSWORD,\n storageStatePath: env.AUTH_STORAGE_STATE_PATH,\n storageStateDir: env.AUTH_STORAGE_STATE_DIR,\n },\n reporting: {\n allureEnabled: env.REPORT_ALLURE === \"true\",\n resultsDir: env.ALLURE_RESULTS_DIR,\n testCaseUrlTemplate: env.TEST_CASE_URL_TEMPLATE,\n },\n retry: {\n retries: env.RETRY_COUNT ? Number(env.RETRY_COUNT) : undefined,\n minDelayMs: env.RETRY_MIN_DELAY_MS ? Number(env.RETRY_MIN_DELAY_MS) : undefined,\n maxDelayMs: env.RETRY_MAX_DELAY_MS ? Number(env.RETRY_MAX_DELAY_MS) : undefined,\n },\n diagnostics: {\n enabled: env.DIAGNOSTICS === undefined ? undefined : env.DIAGNOSTICS !== \"false\",\n failOnConsoleError: env.FAIL_ON_CONSOLE_ERROR === undefined ? undefined : env.FAIL_ON_CONSOLE_ERROR === \"true\",\n failOnPageError: env.FAIL_ON_PAGE_ERROR === undefined ? undefined : env.FAIL_ON_PAGE_ERROR === \"true\",\n },\n };\n}\n\n/**\n * Reads a required environment variable, failing immediately with a clear message instead of\n * letting an `undefined` surface as a confusing failure deep inside a test.\n */\nexport function requireEnv(name: string, env: NodeJS.ProcessEnv = process.env): string {\n const value = env[name];\n if (value === undefined || value === \"\") {\n throw new ConfigMissingError(name);\n }\n return value;\n}\n\nexport interface LoadConfigOptions {\n /** Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv;\n /** Project-specific overrides (e.g. from a project's `config.override.ts`), merged on top of env-derived values. */\n overrides?: DeepPartial<AppConfig>;\n}\n\n/**\n * Loads and validates the application config for the current environment.\n * Resolution order: env-derived defaults -> project `overrides` -> zod validation.\n * Fails fast with `ConfigValidationError` when required fields (e.g. `baseUrl`) are missing/invalid,\n * instead of letting tests fail later with a confusing `undefined` somewhere downstream.\n */\nexport function loadConfig(options: LoadConfigOptions = {}): AppConfig {\n const { env = process.env, overrides } = options;\n\n const fromEnv = pruneUndefined(readEnvConfig(env)) as DeepPartial<AppConfig>;\n const merged = deepMerge(fromEnv as AppConfig, overrides);\n\n const result = AppConfigSchema.safeParse(merged);\n if (!result.success) {\n throw new ConfigValidationError(\n `Invalid application config: ${result.error.issues\n .map((issue) => `${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"; \")}`,\n result.error.issues,\n );\n }\n return result.data;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { parse } from \"dotenv\";\n\nexport interface LoadEnvFilesResult {\n /** Files that existed and were read, in the order they were applied. */\n loaded: string[];\n /** Variable names actually written to the environment. */\n applied: string[];\n}\n\n/**\n * Loads several env files with predictable precedence:\n *\n * 1. **Later files beat earlier ones** — so `.env.staging.local` overrides `.env.staging`.\n * 2. **Real environment variables beat every file** — a `BASE_URL` exported by CI or the shell\n * is never clobbered by a committed `.env`, which is what makes the same config work locally\n * and in a pipeline.\n *\n * Missing files are skipped silently: the `.local` files are gitignored and simply won't exist\n * on most machines.\n *\n * The two rules together are why this can't just be repeated `dotenv.config()` calls — dotenv\n * either never overrides (so later files lose) or always overrides (so the shell loses). Files\n * are merged first, then applied only where the environment has nothing already.\n */\nexport function loadEnvFiles(files: string[], env: NodeJS.ProcessEnv = process.env): LoadEnvFilesResult {\n const merged: Record<string, string> = {};\n const loaded: string[] = [];\n\n for (const file of files) {\n if (!existsSync(file)) continue;\n Object.assign(merged, parse(readFileSync(file)));\n loaded.push(file);\n }\n\n const applied: string[] = [];\n for (const [key, value] of Object.entries(merged)) {\n if (env[key] === undefined) {\n env[key] = value;\n applied.push(key);\n }\n }\n\n return { loaded, applied };\n}\n\n/**\n * The standard cascade for an environment, following the convention used by Vite/CRA/Next:\n * a committed base, a gitignored base override, then the same pair for the specific environment.\n * Keep secrets in the `.local` files — they are gitignored; `.env` / `.env.<environment>` are not.\n */\nexport function defaultEnvFiles(environment: string): string[] {\n return [\".env\", \".env.local\", `.env.${environment}`, `.env.${environment}.local`];\n}\n","import type { AppConfig } from \"../config/schema.js\";\n\nexport type PlaywrightReporterEntry = [string] | [string, Record<string, unknown>];\n\n/**\n * Builds the `reporter` array for a project's `playwright.config.ts`. Always includes\n * the built-in HTML reporter; adds Allure when `reporting.allureEnabled` is true.\n *\n * Allure is optional and NOT bundled transitively: because Playwright resolves reporter\n * packages relative to the project that runs the tests, a project enabling Allure must add\n * `allure-playwright` (and `allure-js-commons` if using manual annotations) to its own\n * `devDependencies`. See `docs/EXTENDING.md`.\n */\nexport function buildReporterConfig(config: Pick<AppConfig, \"reporting\">): PlaywrightReporterEntry[] {\n const reporters: PlaywrightReporterEntry[] = [[\"html\", { open: \"never\" }]];\n if (config.reporting.allureEnabled) {\n reporters.push([\"allure-playwright\", { resultsDir: config.reporting.resultsDir, detail: true }]);\n }\n return reporters;\n}\n","import { devices, type PlaywrightTestConfig } from \"@playwright/test\";\nimport { buildReporterConfig } from \"../reporting/allure-setup.js\";\nimport { deepMerge } from \"../utils/deep-merge.js\";\nimport { defaultEnvFiles, loadEnvFiles } from \"./env.js\";\nimport { loadConfig } from \"./loader.js\";\nimport type { AppConfig } from \"./schema.js\";\nimport type { DeepPartial } from \"./types.js\";\n\nexport type BrowserName = \"chromium\" | \"firefox\" | \"webkit\";\n\nexport interface DefineE2EConfigOptions {\n /**\n * Project-specific config overrides merged on top of the env-derived values.\n * Pass a FUNCTION if the overrides read `process.env` — it is called after the env files are\n * loaded, whereas an object literal in a `playwright.config.ts` import would be evaluated\n * before them.\n */\n configOverrides?: DeepPartial<AppConfig> | (() => DeepPartial<AppConfig>);\n /**\n * Environment to use when `TEST_ENV` isn't set. Defaults to `\"dev\"`. Set it for apps that\n * only have one environment (e.g. `\"staging\"`) so nobody has to export `TEST_ENV` by hand.\n */\n defaultEnvironment?: string;\n /**\n * Env files to load. Defaults to the standard cascade for the resolved environment:\n * `.env`, `.env.local`, `.env.<environment>`, `.env.<environment>.local` — later files win,\n * but real environment variables always win over files. Pass an explicit list to take full\n * control, or `false` to load none.\n */\n envFile?: string | string[] | false;\n /** Defaults to `./tests`. */\n testDir?: string;\n /** Browser projects to generate. Defaults to `[\"chromium\"]`. */\n browsers?: BrowserName[];\n /** Path to a global setup module (see `buildGlobalSetup`). */\n globalSetup?: string;\n globalTeardown?: string;\n /**\n * Deep-merged over everything generated here — the escape hatch for any Playwright option\n * core doesn't model. Anything set here wins.\n */\n playwright?: PlaywrightTestConfig;\n}\n\nfunction resolveEnvFiles(options: DefineE2EConfigOptions, environment: string): string[] {\n if (options.envFile === false) return [];\n if (typeof options.envFile === \"string\") return [options.envFile];\n if (Array.isArray(options.envFile)) return options.envFile;\n return defaultEnvFiles(environment);\n}\n\n/**\n * Builds a project's `playwright.config.ts` from its `AppConfig`, so each project doesn't\n * re-implement the same env-loading + config-plumbing boilerplate.\n *\n * Order matters and is handled here: env files are loaded FIRST, then `configOverrides` is\n * evaluated (hence the function form), then the config is validated, then the Playwright config\n * is assembled from it.\n *\n * ```ts\n * // playwright.config.ts\n * import { defineE2EConfig } from \"@emesoft_company/playwright-core/config\";\n * export default defineE2EConfig();\n * ```\n */\nexport function defineE2EConfig(options: DefineE2EConfigOptions = {}): PlaywrightTestConfig {\n const environment = process.env.TEST_ENV ?? options.defaultEnvironment ?? \"dev\";\n loadEnvFiles(resolveEnvFiles(options, environment));\n\n const overrides =\n typeof options.configOverrides === \"function\" ? options.configOverrides() : options.configOverrides;\n // The resolved environment is a base, not an override: an explicit `environment` in the\n // project's own overrides still wins.\n const appConfig = loadConfig({ overrides: deepMerge({ environment }, overrides) });\n\n const browsers = options.browsers ?? [\"chromium\"];\n const deviceByBrowser: Record<BrowserName, string> = {\n chromium: \"Desktop Chrome\",\n firefox: \"Desktop Firefox\",\n webkit: \"Desktop Safari\",\n };\n\n const generated: PlaywrightTestConfig = {\n testDir: options.testDir ?? \"./tests\",\n fullyParallel: true,\n retries: appConfig.retry.retries,\n timeout: appConfig.timeouts.testMs,\n reporter: buildReporterConfig(appConfig),\n // `globalSetup` is only wired when a path is given AND a storage state path is configured —\n // otherwise a project that hasn't set up login yet would fail on every run.\n ...(options.globalSetup && appConfig.auth.storageStatePath\n ? { globalSetup: options.globalSetup }\n : {}),\n ...(options.globalTeardown ? { globalTeardown: options.globalTeardown } : {}),\n use: {\n baseURL: appConfig.baseUrl,\n actionTimeout: appConfig.timeouts.actionMs,\n navigationTimeout: appConfig.timeouts.navigationMs,\n trace: \"on-first-retry\",\n screenshot: \"only-on-failure\",\n ...(options.globalSetup && appConfig.auth.storageStatePath\n ? { storageState: appConfig.auth.storageStatePath }\n : {}),\n },\n projects: browsers.map((browser) => ({\n name: browser,\n use: { ...devices[deviceByBrowser[browser]] },\n })),\n };\n\n return deepMerge(generated, options.playwright);\n}\n","import { AuthError } from \"../errors/app-error.js\";\nimport type { Logger } from \"../logging/logger.js\";\nimport type { TokenProvider } from \"./types.js\";\n\n/** Token provider that always returns a fixed token. Useful for tests/local dev with a pre-issued token. */\nexport class StaticTokenProvider implements TokenProvider {\n constructor(private readonly token: string) {}\n\n async getToken(): Promise<string> {\n return this.token;\n }\n\n invalidate(): void {\n // no-op: nothing to invalidate for a static token\n }\n}\n\n/** No-op provider for endpoints that don't require authentication. */\nexport class NullTokenProvider implements TokenProvider {\n async getToken(): Promise<string> {\n return \"\";\n }\n\n invalidate(): void {\n // no-op\n }\n}\n\nexport interface JwtTokenProviderOptions {\n tokenUrl: string;\n clientId?: string;\n clientSecret?: string;\n username?: string;\n password?: string;\n /** Seconds subtracted from the token's `expires_in` to refresh proactively. Default: 30. */\n refreshSkewSeconds?: number;\n logger?: Logger;\n fetchImpl?: typeof fetch;\n}\n\ninterface CachedToken {\n token: string;\n expiresAt: number;\n}\n\n/**\n * JWT/OAuth2 token provider supporting client-credentials or password grants.\n * Caches the token in-memory and transparently refreshes it before expiry.\n */\nexport class JwtTokenProvider implements TokenProvider {\n private cached?: CachedToken;\n private inFlight?: Promise<string>;\n\n constructor(private readonly options: JwtTokenProviderOptions) {}\n\n async getToken(): Promise<string> {\n if (this.cached && this.cached.expiresAt > Date.now()) {\n return this.cached.token;\n }\n if (!this.inFlight) {\n this.inFlight = this.fetchToken().finally(() => {\n this.inFlight = undefined;\n });\n }\n return this.inFlight;\n }\n\n invalidate(): void {\n this.cached = undefined;\n }\n\n private async fetchToken(): Promise<string> {\n const { tokenUrl, clientId, clientSecret, username, password, refreshSkewSeconds = 30, logger, fetchImpl = fetch } = this.options;\n\n const body = new URLSearchParams();\n if (username && password) {\n body.set(\"grant_type\", \"password\");\n body.set(\"username\", username);\n body.set(\"password\", password);\n } else {\n body.set(\"grant_type\", \"client_credentials\");\n }\n if (clientId) body.set(\"client_id\", clientId);\n if (clientSecret) body.set(\"client_secret\", clientSecret);\n\n logger?.debug({ tokenUrl }, \"fetching auth token\");\n\n let response: Response;\n try {\n response = await fetchImpl(tokenUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body,\n });\n } catch (cause) {\n throw new AuthError(`Failed to reach token endpoint ${tokenUrl}`, { cause });\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AuthError(`Token endpoint returned ${response.status}: ${text}`, {\n context: { status: response.status, tokenUrl },\n });\n }\n\n const data = (await response.json()) as { access_token?: string; expires_in?: number };\n if (!data.access_token) {\n throw new AuthError(\"Token endpoint response missing access_token\", { context: { tokenUrl } });\n }\n\n const expiresInSeconds = data.expires_in ?? 300;\n this.cached = {\n token: data.access_token,\n expiresAt: Date.now() + Math.max(expiresInSeconds - refreshSkewSeconds, 0) * 1000,\n };\n return this.cached.token;\n }\n}\n","export function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { sleep } from \"../utils/sleep.js\";\n\nexport interface RetryOptions {\n /** Number of retry attempts after the initial try. Default: 2. */\n retries?: number;\n minDelayMs?: number;\n maxDelayMs?: number;\n /** Exponential backoff factor. Default: 2. */\n factor?: number;\n /** Return true to retry this error, false to fail fast. Default: retry everything. */\n retryOn?: (error: unknown) => boolean;\n /** Called before each retry (not before the first attempt). */\n onRetry?: (error: unknown, attempt: number) => void;\n /** Called once when giving up, with the total number of attempts made. */\n onGiveUp?: (error: unknown, attempts: number) => void;\n}\n\nfunction backoffDelay(attempt: number, minDelayMs: number, maxDelayMs: number, factor: number): number {\n const exponential = minDelayMs * factor ** (attempt - 1);\n const jitter = Math.random() * minDelayMs;\n return Math.min(exponential + jitter, maxDelayMs);\n}\n\n/**\n * Runs `fn` with exponential-backoff retry. Used for both flaky API calls and\n * flaky UI actions so the retry policy stays consistent across the framework.\n *\n * Always rethrows the ORIGINAL error — whether it failed fast (`retryOn` returned\n * false) or exhausted its retries. That's what makes `catch (e) { e instanceof ApiError }`\n * and `expect(...).rejects.toThrow(ApiError)` work in tests; wrapping the error in a\n * retry-specific type would hide the only thing the caller actually wants to assert on.\n * Use `onGiveUp` if you need the attempt count.\n */\nexport async function withRetry<T>(fn: () => Promise<T>, options: RetryOptions = {}): Promise<T> {\n const {\n retries = 2,\n minDelayMs = 200,\n maxDelayMs = 5_000,\n factor = 2,\n retryOn = () => true,\n onRetry,\n onGiveUp,\n } = options;\n\n const maxAttempts = retries + 1;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n const isLastAttempt = attempt >= maxAttempts;\n if (isLastAttempt || !retryOn(error)) {\n onGiveUp?.(error, attempt);\n throw error;\n }\n onRetry?.(error, attempt);\n await sleep(backoffDelay(attempt, minDelayMs, maxDelayMs, factor));\n }\n }\n\n // Unreachable: the loop either returns or throws.\n throw new Error(\"withRetry: unreachable state\");\n}\n","/** 429 (rate-limited) and any 5xx are considered transient and safe to retry. */\nexport function isRetryableStatus(status: number): boolean {\n return status === 429 || (status >= 500 && status <= 599);\n}\n","import type { APIRequestContext, APIResponse } from \"@playwright/test\";\nimport { NullTokenProvider } from \"../auth/token-provider.js\";\nimport type { TokenProvider } from \"../auth/types.js\";\nimport { ApiError, AppError } from \"../errors/app-error.js\";\nimport { withRetry, type RetryOptions } from \"../errors/retry.js\";\nimport type { Logger } from \"../logging/logger.js\";\nimport { isRetryableStatus } from \"./interceptors.js\";\nimport type { ApiClientInterceptors, ApiRequestOptions, ApiResponse } from \"./types.js\";\n\nexport interface ApiClientOptions {\n /** Playwright's `APIRequestContext` (from `request` fixture or `context.request`). */\n request: APIRequestContext;\n baseUrl?: string;\n tokenProvider?: TokenProvider;\n logger?: Logger;\n retry?: Partial<RetryOptions>;\n defaultHeaders?: Record<string, string>;\n interceptors?: ApiClientInterceptors;\n}\n\n/** Internal signal used to drive retry backoff; never escapes `send()`. */\nclass TransientHttpError extends Error {\n constructor(readonly status: number) {\n super(`Transient HTTP status ${status}`);\n }\n}\n\n/**\n * Thin, project-agnostic abstraction over Playwright's `APIRequestContext`:\n * base URL resolution, bearer-token injection, structured error mapping, and\n * retry-on-5xx/429. Projects extend this for domain-specific API clients\n * instead of calling `request.fetch` directly in tests.\n *\n * Two levels of API, on purpose:\n * - `get`/`post`/... return the body and THROW `ApiError` on an unexpected status — the right\n * default for arranging test data, where a failed call should stop the test loudly.\n * - `send()` returns the full `ApiResponse` (status, headers, body) and never throws for an\n * HTTP status — for tests that assert on error responses themselves.\n */\nexport class ApiClient {\n private readonly request: APIRequestContext;\n private readonly baseUrl?: string;\n private readonly tokenProvider: TokenProvider;\n private readonly logger?: Logger;\n private readonly retryOptions: RetryOptions;\n private readonly defaultHeaders: Record<string, string>;\n private readonly interceptors: ApiClientInterceptors;\n\n constructor(options: ApiClientOptions) {\n this.request = options.request;\n this.baseUrl = options.baseUrl;\n this.tokenProvider = options.tokenProvider ?? new NullTokenProvider();\n this.logger = options.logger;\n this.defaultHeaders = options.defaultHeaders ?? {};\n this.interceptors = options.interceptors ?? {};\n this.retryOptions = { ...options.retry };\n }\n\n get<T = unknown>(path: string, options?: ApiRequestOptions<T>): Promise<T> {\n return this.requestBody<T>(\"GET\", path, options);\n }\n\n post<T = unknown>(path: string, options?: ApiRequestOptions<T>): Promise<T> {\n return this.requestBody<T>(\"POST\", path, options);\n }\n\n put<T = unknown>(path: string, options?: ApiRequestOptions<T>): Promise<T> {\n return this.requestBody<T>(\"PUT\", path, options);\n }\n\n patch<T = unknown>(path: string, options?: ApiRequestOptions<T>): Promise<T> {\n return this.requestBody<T>(\"PATCH\", path, options);\n }\n\n delete<T = unknown>(path: string, options?: ApiRequestOptions<T>): Promise<T> {\n return this.requestBody<T>(\"DELETE\", path, options);\n }\n\n /**\n * Full response including status and headers. Retries transient statuses, then returns\n * whatever came back — a 404 or 500 is a normal return value here, not an exception.\n * Network/timeout failures still throw.\n */\n async send<T = unknown>(\n method: string,\n path: string,\n options: ApiRequestOptions<T> = {},\n ): Promise<ApiResponse<T>> {\n const url = this.resolveUrl(path, options.params);\n let lastResponse: ApiResponse<T> | undefined;\n\n try {\n await withRetry(\n async () => {\n lastResponse = await this.fetchOnce<T>(method, url, options);\n if (isRetryableStatus(lastResponse.status) && !this.isExpectedStatus(lastResponse.status, options)) {\n throw new TransientHttpError(lastResponse.status);\n }\n },\n {\n ...this.retryOptions,\n retryOn: (error) => error instanceof TransientHttpError,\n onRetry: (error, attempt) =>\n this.logger?.warn({ method, url, attempt, err: error }, \"retrying API request\"),\n },\n );\n } catch (error) {\n // A transient status that never recovered is still a response the caller may want to\n // inspect; anything else (DNS, TLS, timeout) is a real failure and must propagate.\n if (!(error instanceof TransientHttpError)) throw error;\n }\n\n if (!lastResponse) {\n throw new AppError(`API request produced no response: ${method} ${url}`, {\n code: \"API_NO_RESPONSE\",\n context: { method, url },\n });\n }\n return lastResponse;\n }\n\n private async requestBody<T>(\n method: string,\n path: string,\n options: ApiRequestOptions<T> = {},\n ): Promise<T> {\n const response = await this.send<T>(method, path, options);\n\n if (!this.isExpectedStatus(response.status, options)) {\n if (response.status === 401) this.tokenProvider.invalidate();\n this.logger?.error(\n { status: response.status, method, url: response.url, body: response.data },\n \"API request failed\",\n );\n throw new ApiError(\n `API request failed: ${method} ${response.url} -> ${response.status}` +\n (options.expectStatus === undefined ? \"\" : ` (expected ${String(options.expectStatus)})`),\n {\n code: \"API_REQUEST_FAILED\",\n status: response.status,\n method,\n url: response.url,\n context: { body: response.data },\n },\n );\n }\n return response.data;\n }\n\n private isExpectedStatus(status: number, options: ApiRequestOptions<unknown>): boolean {\n if (options.expectStatus === undefined) return status >= 200 && status < 300;\n const expected = Array.isArray(options.expectStatus) ? options.expectStatus : [options.expectStatus];\n return expected.includes(status);\n }\n\n private async fetchOnce<T>(\n method: string,\n url: string,\n options: ApiRequestOptions<T>,\n ): Promise<ApiResponse<T>> {\n const headers = await this.buildHeaders(method, url, options);\n const response = await this.request.fetch(url, {\n method,\n headers,\n data: options.data,\n form: options.form,\n multipart: options.multipart,\n timeout: options.timeoutMs,\n });\n await this.interceptors.onResponse?.({ method, url, status: response.status() });\n\n return {\n status: response.status(),\n ok: response.ok(),\n headers: response.headers(),\n data: await this.parseBody<T>(response, options),\n url,\n method,\n };\n }\n\n private resolveUrl(path: string, params?: ApiRequestOptions<unknown>[\"params\"]): string {\n const base = this.baseUrl ? new URL(path, this.baseUrl).toString() : path;\n if (!params) return base;\n const url = new URL(base);\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) url.searchParams.set(key, String(value));\n }\n return url.toString();\n }\n\n private async buildHeaders(\n method: string,\n url: string,\n options: ApiRequestOptions<unknown>,\n ): Promise<Record<string, string>> {\n let headers: Record<string, string> = { ...this.defaultHeaders, ...options.headers };\n if (!options.skipAuth) {\n const token = await this.tokenProvider.getToken();\n if (token) headers = { ...headers, Authorization: `Bearer ${token}` };\n }\n const overridden = await this.interceptors.onRequest?.({ method, url, headers });\n return overridden ?? headers;\n }\n\n private async parseBody<T>(response: APIResponse, options: ApiRequestOptions<T>): Promise<T> {\n const raw = await this.readBody(response);\n\n if (!options.schema) return raw as T;\n\n const result = options.schema.safeParse(raw);\n if (!result.success) {\n throw new ApiError(`API response did not match the expected schema: ${response.url()}`, {\n code: \"API_SCHEMA_MISMATCH\",\n status: response.status(),\n url: response.url(),\n context: { issues: result.error.issues, body: raw },\n });\n }\n return result.data;\n }\n\n private async readBody(response: APIResponse): Promise<unknown> {\n const contentType = response.headers()[\"content-type\"] ?? \"\";\n if (contentType.includes(\"application/json\")) {\n // A JSON content-type with an empty body (some 204s) would otherwise throw on parse.\n const text = await response.text();\n if (text.trim() === \"\") return undefined;\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n }\n return response.text();\n }\n}\n","import pino, { type Logger } from \"pino\";\n\nexport interface LoggerOptions {\n level?: string;\n name?: string;\n /**\n * Pretty-print logs for local/interactive runs. Requires the optional\n * `pino-pretty` dev dependency to be installed in the consuming project;\n * leave off (default) for CI where structured JSON logs are preferred.\n */\n pretty?: boolean;\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const {\n level = process.env.LOG_LEVEL ?? \"info\",\n name = \"playwright-core\",\n pretty = process.env.LOG_PRETTY === \"true\",\n } = options;\n\n return pino({\n name,\n level,\n ...(pretty\n ? {\n transport: {\n target: \"pino-pretty\",\n options: { colorize: true, translateTime: \"SYS:standard\" },\n },\n }\n : {}),\n });\n}\n\n/** Default shared logger instance. Prefer `createLogger()` when a project needs a distinct name/level. */\nexport const logger = createLogger();\n\nexport type { Logger };\n","import type { TestInfo } from \"@playwright/test\";\n\nexport interface TestMetaOptions {\n /** Test-case id(s) in your test management tool, e.g. `\"TC-1234\"` or `[\"TC-1\", \"TC-2\"]`. */\n testCase?: string | string[];\n /** Tag(s) for filtering with `--grep`, e.g. `\"@smoke\"`. The leading `@` is added if missing. */\n tag?: string | string[];\n /** Free-form annotations, e.g. `{ type: \"issue\", description: \"JIRA-42\" }`. */\n annotation?: { type: string; description?: string }[];\n}\n\nexport interface TestMeta {\n tag?: string[];\n annotation?: { type: string; description?: string }[];\n}\n\nfunction toArray(value: string | string[] | undefined): string[] {\n if (value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Builds the `details` argument of `test(title, details, body)` from test-case ids and tags,\n * so the mapping between an automated test and its test-case id lives in the test itself and\n * shows up in the report.\n *\n * ```ts\n * test(\"login success\", meta({ testCase: \"TC-1234\", tag: \"@smoke\" }), async ({ page }) => { ... });\n * ```\n *\n * Set `reporting.testCaseUrlTemplate` (env `TEST_CASE_URL_TEMPLATE`, with `{id}` as the\n * placeholder) to turn the ids into links — see `linkTestCases`.\n */\nexport function meta(options: TestMetaOptions): TestMeta {\n const tags = toArray(options.tag).map((tag) => (tag.startsWith(\"@\") ? tag : `@${tag}`));\n const testCaseAnnotations = toArray(options.testCase).map((id) => ({\n type: \"testCase\",\n description: id,\n }));\n\n const annotation = [...testCaseAnnotations, ...(options.annotation ?? [])];\n\n return {\n ...(tags.length > 0 ? { tag: tags } : {}),\n ...(annotation.length > 0 ? { annotation } : {}),\n };\n}\n\n/**\n * Rewrites `testCase` annotations into full URLs using a template containing `{id}`.\n * Call from a project's `beforeEach`/fixture when `reporting.testCaseUrlTemplate` is set.\n */\nexport function linkTestCases(testInfo: TestInfo, urlTemplate: string | undefined): void {\n if (!urlTemplate) return;\n for (const annotation of testInfo.annotations) {\n if (annotation.type === \"testCase\" && annotation.description) {\n annotation.description = urlTemplate.replace(\"{id}\", annotation.description);\n }\n }\n}\n","import { JwtTokenProvider, NullTokenProvider } from \"../auth/token-provider.js\";\nimport type { TokenProvider } from \"../auth/types.js\";\nimport type { AppConfig } from \"../config/schema.js\";\nimport type { Logger } from \"../logging/logger.js\";\n\n/**\n * Default token-provider resolution: uses JWT client-credentials/password grant when\n * `auth.tokenUrl` is configured, otherwise falls back to no-auth. Projects that need a\n * different strategy (SSO, pre-provisioned storageState, static token, ...) override the\n * `tokenProvider` fixture in their own `fixtures/index.ts` — see `docs/EXTENDING.md`.\n */\nexport function resolveTokenProvider(config: AppConfig, logger?: Logger): TokenProvider {\n const { auth } = config;\n if (auth.tokenUrl) {\n return new JwtTokenProvider({\n tokenUrl: auth.tokenUrl,\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n username: auth.username,\n password: auth.password,\n logger,\n });\n }\n return new NullTokenProvider();\n}\n","import type { TestInfo } from \"@playwright/test\";\n\n/**\n * Report attachment helpers. These show up in the HTML report (and Allure, when enabled)\n * next to the test, which is usually the difference between a failure you can diagnose from\n * CI and one you have to reproduce locally.\n */\n\nexport async function attachText(testInfo: TestInfo, name: string, body: string): Promise<void> {\n await testInfo.attach(name, { body, contentType: \"text/plain\" });\n}\n\nexport async function attachJson(testInfo: TestInfo, name: string, value: unknown): Promise<void> {\n await testInfo.attach(name, {\n body: JSON.stringify(value, null, 2),\n contentType: \"application/json\",\n });\n}\n\nexport async function attachScreenshot(testInfo: TestInfo, name: string, buffer: Buffer): Promise<void> {\n await testInfo.attach(name, { body: buffer, contentType: \"image/png\" });\n}\n","import type { Page, TestInfo } from \"@playwright/test\";\nimport type { DiagnosticsConfig } from \"../config/schema.js\";\nimport { attachText } from \"../reporting/attachments.js\";\n\nexport interface CollectedDiagnostics {\n consoleErrors: string[];\n pageErrors: string[];\n failedRequests: string[];\n}\n\n/**\n * Subscribes to a page's error signals. Returns the collected buffers plus a `report()` to\n * call after the test body, which attaches anything collected to the report and — if\n * configured — fails the test.\n *\n * Wired into the `page` fixture override in `base-test.ts` rather than an `auto` fixture on\n * purpose: an auto fixture that depends on `page` would force a browser launch for every\n * API-only test, whereas an override only runs for tests that actually use a page.\n */\nexport function collectDiagnostics(\n page: Page,\n config: DiagnosticsConfig,\n): { collected: CollectedDiagnostics; report: (testInfo: TestInfo) => Promise<void> } {\n const collected: CollectedDiagnostics = { consoleErrors: [], pageErrors: [], failedRequests: [] };\n\n const isIgnored = (text: string): boolean =>\n config.ignoreConsolePatterns.some((pattern) => text.includes(pattern));\n\n page.on(\"console\", (message) => {\n if (message.type() !== \"error\") return;\n const text = message.text();\n if (!isIgnored(text)) collected.consoleErrors.push(text);\n });\n\n page.on(\"pageerror\", (error) => {\n collected.pageErrors.push(error.message);\n });\n\n page.on(\"requestfailed\", (request) => {\n // Navigations and in-flight requests cancelled by the browser land here too, so this is\n // recorded for context but never fails a test on its own.\n collected.failedRequests.push(\n `${request.method()} ${request.url()} — ${request.failure()?.errorText ?? \"failed\"}`,\n );\n });\n\n const report = async (testInfo: TestInfo): Promise<void> => {\n if (collected.consoleErrors.length > 0) {\n await attachText(testInfo, \"console-errors\", collected.consoleErrors.join(\"\\n\"));\n }\n if (collected.pageErrors.length > 0) {\n await attachText(testInfo, \"page-errors\", collected.pageErrors.join(\"\\n\"));\n }\n if (collected.failedRequests.length > 0) {\n await attachText(testInfo, \"failed-requests\", collected.failedRequests.join(\"\\n\"));\n }\n\n // Only escalate when the test would otherwise pass — turning an unrelated console error\n // into the reported failure of an already-failing test hides the real cause.\n if (testInfo.status !== \"passed\") return;\n\n if (config.failOnPageError && collected.pageErrors.length > 0) {\n throw new Error(`Uncaught page error(s):\\n${collected.pageErrors.join(\"\\n\")}`);\n }\n if (config.failOnConsoleError && collected.consoleErrors.length > 0) {\n throw new Error(`Console error(s):\\n${collected.consoleErrors.join(\"\\n\")}`);\n }\n };\n\n return { collected, report };\n}\n","import { expect as baseExpect } from \"@playwright/test\";\nimport type { ZodType } from \"zod\";\nimport type { ApiResponse } from \"../api/types.js\";\n\n/**\n * `expect` with a few framework-specific matchers added. Projects get these automatically by\n * importing `expect` from `@emesoft_company/playwright-core/fixtures` (or their own `fixtures/index.ts`),\n * so there's nothing to register per project.\n */\nexport const expect = baseExpect.extend({\n /**\n * Asserts the status of an `ApiResponse` from `apiClient.send()`, printing the body on\n * failure — otherwise a wrong status tells you nothing about why.\n */\n toHaveStatus(received: ApiResponse<unknown>, expected: number) {\n const pass = received.status === expected;\n return {\n pass,\n name: \"toHaveStatus\",\n expected,\n actual: received.status,\n message: () =>\n pass\n ? `Expected status not to be ${expected}`\n : `Expected ${received.method} ${received.url} to return ${expected}, got ${received.status}\\n` +\n `Body: ${JSON.stringify(received.data, null, 2)}`,\n };\n },\n\n /** Asserts a value matches a zod schema, listing the exact field-level issues on failure. */\n toMatchSchema(received: unknown, schema: ZodType<unknown>) {\n const result = schema.safeParse(received);\n return {\n pass: result.success,\n name: \"toMatchSchema\",\n message: () =>\n result.success\n ? \"Expected value not to match the schema\"\n : `Value did not match the schema:\\n${result.error.issues\n .map((issue) => ` - ${issue.path.join(\".\") || \"(root)\"}: ${issue.message}`)\n .join(\"\\n\")}`,\n };\n },\n});\n","import { test as base } from \"@playwright/test\";\nimport { ApiClient } from \"../api/api-client.js\";\nimport type { TokenProvider } from \"../auth/types.js\";\nimport { loadConfig } from \"../config/loader.js\";\nimport type { AppConfig } from \"../config/schema.js\";\nimport { withRetry, type RetryOptions } from \"../errors/retry.js\";\nimport { createLogger, type Logger } from \"../logging/logger.js\";\nimport { linkTestCases } from \"../reporting/meta.js\";\nimport { resolveTokenProvider } from \"./auth.fixture.js\";\nimport { collectDiagnostics } from \"./diagnostics.fixture.js\";\n\n/** Registers a teardown callback; callbacks run in reverse order after the test. */\nexport type CleanupRegistrar = (task: () => unknown | Promise<unknown>) => void;\n\nexport interface CoreFixtures {\n appConfig: AppConfig;\n logger: Logger;\n tokenProvider: TokenProvider;\n apiClient: ApiClient;\n retry: <T>(fn: () => Promise<T>, options?: RetryOptions) => Promise<T>;\n /**\n * Registers teardown work (delete a record the test created, restore a toggled setting).\n * Runs in reverse registration order, and every task runs even if an earlier one throws —\n * a failed cleanup must not leave the rest of the data behind.\n */\n cleanup: CleanupRegistrar;\n /** Internal auto fixture: rewrites test-case annotations into links. Not meant to be used directly. */\n _testCaseLinks: void;\n}\n\nexport interface CoreWorkerFixtures {\n /** Config is loaded once per worker (env vars don't change mid-run) and shared by all tests in it. */\n workerConfig: AppConfig;\n}\n\n/**\n * Base test extended with the framework's core fixtures. Projects import this (not\n * `@playwright/test`'s `test` directly) and further `.extend()` it with their own\n * Page Objects/fixtures, or override any of these fixtures to change behavior\n * (see `docs/EXTENDING.md`).\n */\nexport const test = base.extend<CoreFixtures, CoreWorkerFixtures>({\n workerConfig: [\n async ({}, use) => {\n await use(loadConfig());\n },\n { scope: \"worker\" },\n ],\n\n appConfig: async ({ workerConfig }, use) => {\n await use(workerConfig);\n },\n\n logger: async ({ appConfig }, use, testInfo) => {\n await use(createLogger({ level: appConfig.logLevel, name: testInfo.title }));\n },\n\n tokenProvider: async ({ appConfig, logger }, use) => {\n await use(resolveTokenProvider(appConfig, logger));\n },\n\n apiClient: async ({ appConfig, tokenProvider, logger, request }, use) => {\n await use(\n new ApiClient({\n request,\n baseUrl: appConfig.apiBaseUrl ?? appConfig.baseUrl,\n tokenProvider,\n logger,\n retry: {\n retries: appConfig.retry.retries,\n minDelayMs: appConfig.retry.minDelayMs,\n maxDelayMs: appConfig.retry.maxDelayMs,\n },\n }),\n );\n },\n\n retry: async ({ logger }, use) => {\n const boundRetry = <T>(fn: () => Promise<T>, options?: RetryOptions) =>\n withRetry(fn, {\n onRetry: (error, attempt) => logger.warn({ err: error, attempt }, \"retrying operation\"),\n ...options,\n });\n await use(boundRetry);\n },\n\n cleanup: async ({ logger }, use) => {\n const tasks: Array<() => unknown | Promise<unknown>> = [];\n await use((task) => {\n tasks.push(task);\n });\n\n for (const task of tasks.reverse()) {\n try {\n await task();\n } catch (error) {\n // Swallowed deliberately: a failing cleanup should be visible but must not mask the\n // test result, nor stop the remaining cleanups from running.\n logger.error({ err: error }, \"cleanup task failed\");\n }\n }\n },\n\n // Overriding `page` (instead of an auto fixture) keeps API-only tests from launching a\n // browser: the override only runs for tests that actually request a page.\n page: async ({ page, appConfig }, use, testInfo) => {\n if (!appConfig.diagnostics.enabled) {\n await use(page);\n return;\n }\n const diagnostics = collectDiagnostics(page, appConfig.diagnostics);\n await use(page);\n await diagnostics.report(testInfo);\n },\n\n // testInfo-only, so this is safe to run automatically for every test.\n _testCaseLinks: [\n async ({ appConfig }, use, testInfo) => {\n linkTestCases(testInfo, appConfig.reporting.testCaseUrlTemplate);\n await use();\n },\n { auto: true },\n ],\n});\n\n// Re-exported from here (rather than straight from @playwright/test) so every project picks up\n// the framework's extra matchers without registering anything itself.\nexport { expect } from \"../expect/matchers.js\";\n","import { mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { chromium, type BrowserContextOptions, type Page } from \"@playwright/test\";\nimport { loadConfig } from \"../config/loader.js\";\nimport type { AppConfig } from \"../config/schema.js\";\nimport type { DeepPartial } from \"../config/types.js\";\nimport { AppError } from \"../errors/app-error.js\";\n\nexport type LoginFn = (page: Page, config: AppConfig) => Promise<void>;\n\nexport interface RoleSetup {\n /** Performs this role's login; storage state is captured right after it returns. */\n login: LoginFn;\n /** Defaults to `<auth.storageStateDir>/<role>.json`. */\n storageStatePath?: string;\n /** Per-role context options, falling back to the top-level `contextOptions`. */\n contextOptions?: BrowserContextOptions;\n}\n\nexport interface GlobalSetupOptions {\n /**\n * Single-session login. Storage state goes to `auth.storageStatePath`.\n * Mutually exclusive with `roles`.\n */\n login?: LoginFn;\n /**\n * Multi-role login — one storage state file per role, so tests can pick who they run as\n * with `test.use({ storageState: roleStorageState(\"admin\") })`.\n */\n roles?: Record<string, RoleSetup>;\n configOverrides?: DeepPartial<AppConfig>;\n /**\n * Context options (e.g. `devices[\"Desktop Chrome\"]`) to log in with. Pass the SAME options\n * your test projects run with — some apps tie a session to fingerprint details like\n * User-Agent, so logging in under different context options than the tests that reuse the\n * session can silently invalidate it server-side.\n */\n contextOptions?: BrowserContextOptions;\n /**\n * Options for `chromium.launch()` — e.g. `{ headless: false }`. Defaults to Playwright's own\n * default (headless). Some apps never finish loading/rendering in headless mode (confirmed\n * for real against a staging target in `bec.e2e`); pass `headless: false` here instead of\n * writing a custom `global-setup.ts` from scratch just to change this one thing.\n */\n launchOptions?: Parameters<typeof chromium.launch>[0];\n}\n\n/**\n * Path of a role's storage state file. Use the same role names here as in\n * `buildGlobalSetup({ roles })` so tests and setup agree:\n *\n * ```ts\n * test.use({ storageState: roleStorageState(\"admin\") });\n * ```\n */\nexport function roleStorageState(\n role: string,\n storageStateDir: string = process.env.AUTH_STORAGE_STATE_DIR ?? \".auth\",\n): string {\n return join(storageStateDir, `${role}.json`);\n}\n\n/**\n * Builds a Playwright `globalSetup` function that logs in once and persists the resulting\n * storage state, so per-test runs reuse an authenticated session instead of logging in for\n * every test. Wire the returned function into `playwright.config.ts`'s `globalSetup` option.\n * See `docs/EXTENDING.md`.\n */\nexport function buildGlobalSetup(options: GlobalSetupOptions) {\n if (!options.login && !options.roles) {\n throw new AppError(\"buildGlobalSetup requires either `login` or `roles`\", {\n code: \"GLOBAL_SETUP_NO_LOGIN\",\n });\n }\n\n return async function globalSetup(): Promise<void> {\n const config = loadConfig({ overrides: options.configOverrides });\n const sessions = resolveSessions(options, config);\n\n const browser = await chromium.launch(options.launchOptions);\n try {\n // Sequential on purpose: parallel logins to the same app can trip rate limits or\n // invalidate each other's sessions on single-session-per-user backends.\n for (const session of sessions) {\n mkdirSync(dirname(session.storageStatePath), { recursive: true });\n const context = await browser.newContext({\n baseURL: config.baseUrl,\n ...(session.contextOptions ?? options.contextOptions),\n });\n try {\n const page = await context.newPage();\n await session.login(page, config);\n await context.storageState({ path: session.storageStatePath });\n } finally {\n await context.close();\n }\n }\n } finally {\n await browser.close();\n }\n };\n}\n\ninterface ResolvedSession {\n login: LoginFn;\n storageStatePath: string;\n contextOptions?: BrowserContextOptions;\n}\n\nfunction resolveSessions(options: GlobalSetupOptions, config: AppConfig): ResolvedSession[] {\n if (options.roles) {\n return Object.entries(options.roles).map(([role, setup]) => ({\n login: setup.login,\n storageStatePath: setup.storageStatePath ?? roleStorageState(role, config.auth.storageStateDir),\n contextOptions: setup.contextOptions,\n }));\n }\n\n const storageStatePath = config.auth.storageStatePath;\n if (!storageStatePath) {\n throw new AppError(\n \"buildGlobalSetup requires `auth.storageStatePath` to be set (env AUTH_STORAGE_STATE_PATH or a config override) when using single-session `login`\",\n { code: \"MISSING_STORAGE_STATE_PATH\" },\n );\n }\n return [{ login: options.login as LoginFn, storageStatePath }];\n}\n","import type { Locator, Page } from \"@playwright/test\";\n\n/**\n * Locator-level helpers shared by `BasePage` and `BaseComponent` (and usable standalone on any\n * locator). Each one waits for the element to be actionable first, so callers don't sprinkle\n * `waitFor` everywhere — Playwright auto-waits for most of this already, but being explicit\n * gives far better failure messages than a bare `click()` timing out mid-action.\n */\n\nexport async function waitForVisible(locator: Locator, timeoutMs?: number): Promise<void> {\n await locator.waitFor({ state: \"visible\", timeout: timeoutMs });\n}\n\nexport async function safeClick(locator: Locator, timeoutMs?: number): Promise<void> {\n await waitForVisible(locator, timeoutMs);\n await locator.click();\n}\n\nexport async function safeDoubleClick(locator: Locator, timeoutMs?: number): Promise<void> {\n await waitForVisible(locator, timeoutMs);\n await locator.dblclick();\n}\n\nexport async function safeFill(locator: Locator, value: string, timeoutMs?: number): Promise<void> {\n await waitForVisible(locator, timeoutMs);\n await locator.fill(value);\n}\n\n/** Clears then types character by character — for inputs with keystroke-driven behavior (autocomplete, masks). */\nexport async function safeType(locator: Locator, value: string, delayMs = 0): Promise<void> {\n await waitForVisible(locator);\n await locator.fill(\"\");\n await locator.pressSequentially(value, { delay: delayMs });\n}\n\nexport async function safeSelect(locator: Locator, value: string | string[]): Promise<void> {\n await waitForVisible(locator);\n await locator.selectOption(value);\n}\n\nexport async function safeCheck(locator: Locator, checked = true): Promise<void> {\n await waitForVisible(locator);\n if (checked) await locator.check();\n else await locator.uncheck();\n}\n\nexport async function uploadFile(locator: Locator, files: string | string[]): Promise<void> {\n await locator.setInputFiles(files);\n}\n\nexport async function scrollIntoView(locator: Locator): Promise<void> {\n await locator.scrollIntoViewIfNeeded();\n}\n\n/** Trimmed visible text of an element (`\"\"` when it has none). */\nexport async function getText(locator: Locator): Promise<string> {\n return (await locator.textContent())?.trim() ?? \"\";\n}\n\n/** Trimmed text of every element the locator matches. */\nexport async function getAllTexts(locator: Locator): Promise<string[]> {\n const texts = await locator.allTextContents();\n return texts.map((text) => text.trim());\n}\n\nexport async function getInputValue(locator: Locator): Promise<string> {\n return locator.inputValue();\n}\n\n/** True when the element exists in the DOM at all (regardless of visibility). */\nexport async function exists(locator: Locator): Promise<boolean> {\n return (await locator.count()) > 0;\n}\n\nexport interface FillFieldsOptions {\n /** Resolve each key into a locator. Defaults to `page.locator(key)`. */\n resolve?: (selector: string) => Locator;\n}\n\n/**\n * Fills a whole form from a `{ selector: value }` map — the single most repeated block in UI\n * tests. Booleans check/uncheck, everything else is filled as text.\n */\nexport async function fillFields(\n page: Page,\n fields: Record<string, string | number | boolean>,\n options: FillFieldsOptions = {},\n): Promise<void> {\n const resolve = options.resolve ?? ((selector: string) => page.locator(selector));\n for (const [selector, value] of Object.entries(fields)) {\n const locator = resolve(selector);\n if (typeof value === \"boolean\") {\n await safeCheck(locator, value);\n } else {\n await safeFill(locator, String(value));\n }\n }\n}\n","import type { Locator, Page, Response } from \"@playwright/test\";\nimport type { Logger } from \"../../logging/logger.js\";\nimport {\n fillFields,\n getAllTexts,\n getText,\n safeCheck,\n safeClick,\n safeFill,\n safeSelect,\n safeType,\n scrollIntoView,\n uploadFile,\n waitForVisible,\n} from \"../actions.js\";\n\nexport interface BasePageOptions {\n page: Page;\n baseUrl?: string;\n logger?: Logger;\n}\n\nexport interface GotoOptions {\n /** Appended as query string, e.g. `{ tab: \"open\" }` -> `?tab=open`. */\n query?: Record<string, string | number | boolean | undefined>;\n /** Path to navigate to instead of the page's own `path` (e.g. a detail page by id). */\n path?: string;\n waitUntil?: \"load\" | \"domcontentloaded\" | \"networkidle\" | \"commit\";\n}\n\n/**\n * Generic Page Object base. Subclasses declare `path` and their own selectors/actions —\n * this base only provides framework-level plumbing (navigation, safe interactions, waits),\n * never project-specific selectors or business logic.\n */\nexport abstract class BasePage {\n protected readonly page: Page;\n protected readonly baseUrl?: string;\n protected readonly logger?: Logger;\n\n abstract readonly path: string;\n\n constructor(options: BasePageOptions) {\n this.page = options.page;\n this.baseUrl = options.baseUrl;\n this.logger = options.logger;\n }\n\n /** Absolute URL for this page, with optional path override and query string. */\n url(options: Pick<GotoOptions, \"path\" | \"query\"> = {}): string {\n const path = options.path ?? this.path;\n const url = this.baseUrl ? new URL(path, this.baseUrl) : new URL(path, \"http://localhost\");\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined) url.searchParams.set(key, String(value));\n }\n }\n return this.baseUrl ? url.toString() : `${url.pathname}${url.search}`;\n }\n\n async goto(options: GotoOptions = {}): Promise<Response | null> {\n const url = this.url(options);\n this.logger?.debug({ url }, \"navigating\");\n return this.page.goto(url, options.waitUntil ? { waitUntil: options.waitUntil } : undefined);\n }\n\n async reload(): Promise<void> {\n await this.page.reload();\n }\n\n currentUrl(): string {\n return this.page.url();\n }\n\n async waitForUrl(url: string | RegExp, timeoutMs?: number): Promise<void> {\n await this.page.waitForURL(url, timeoutMs ? { timeout: timeoutMs } : undefined);\n }\n\n async waitForLoadState(state: \"load\" | \"domcontentloaded\" | \"networkidle\" = \"load\"): Promise<void> {\n await this.page.waitForLoadState(state);\n }\n\n /**\n * Waits for network activity to settle. Prefer waiting on a specific element when you can —\n * `networkidle` is discouraged by Playwright for apps that poll or hold sockets open.\n */\n async waitForNetworkIdle(timeoutMs?: number): Promise<void> {\n await this.page.waitForLoadState(\"networkidle\", timeoutMs ? { timeout: timeoutMs } : undefined);\n }\n\n async pressKey(key: string): Promise<void> {\n await this.page.keyboard.press(key);\n }\n\n /**\n * Screenshot as a buffer. Pair with `attachScreenshot()` from\n * `@emesoft_company/playwright-core/reporting` to put it in the HTML/Allure report.\n */\n async screenshot(fullPage = false): Promise<Buffer> {\n return this.page.screenshot({ fullPage, caret: \"hide\" });\n }\n\n // --- locator helpers, delegated to the shared actions so components behave identically ---\n\n protected waitForVisible(locator: Locator, timeoutMs?: number): Promise<void> {\n return waitForVisible(locator, timeoutMs);\n }\n\n async safeClick(locator: Locator, timeoutMs?: number): Promise<void> {\n await safeClick(locator, timeoutMs);\n }\n\n async safeFill(locator: Locator, value: string): Promise<void> {\n await safeFill(locator, value);\n }\n\n async safeType(locator: Locator, value: string, delayMs?: number): Promise<void> {\n await safeType(locator, value, delayMs);\n }\n\n async safeSelect(locator: Locator, value: string | string[]): Promise<void> {\n await safeSelect(locator, value);\n }\n\n async safeCheck(locator: Locator, checked = true): Promise<void> {\n await safeCheck(locator, checked);\n }\n\n async uploadFile(locator: Locator, files: string | string[]): Promise<void> {\n await uploadFile(locator, files);\n }\n\n async scrollIntoView(locator: Locator): Promise<void> {\n await scrollIntoView(locator);\n }\n\n async getText(locator: Locator): Promise<string> {\n return getText(locator);\n }\n\n async getAllTexts(locator: Locator): Promise<string[]> {\n return getAllTexts(locator);\n }\n\n /** Fills a form from a `{ selector: value }` map. Booleans check/uncheck. */\n async fillFields(fields: Record<string, string | number | boolean>): Promise<void> {\n await fillFields(this.page, fields);\n }\n}\n","import type { Locator, Page } from \"@playwright/test\";\nimport {\n exists,\n fillFields,\n getAllTexts,\n getText,\n safeCheck,\n safeClick,\n safeFill,\n safeSelect,\n scrollIntoView,\n waitForVisible,\n} from \"../actions.js\";\n\nexport interface BaseComponentOptions {\n page: Page;\n /** Locator scoping this component to its root element (e.g. a modal, a nav bar). */\n root: Locator;\n}\n\n/**\n * Generic, reusable wrapper for a UI component scoped to a root locator.\n * Intentionally contains no selectors or business logic — projects extend\n * this for their own components (e.g. `class LoginFormComponent extends BaseComponent`).\n *\n * Every lookup here is scoped to `root`, which is what keeps two instances of the same\n * component on one page (two rows, two modals) from matching each other's elements.\n */\nexport class BaseComponent {\n protected readonly page: Page;\n readonly root: Locator;\n\n constructor(options: BaseComponentOptions) {\n this.page = options.page;\n this.root = options.root;\n }\n\n // --- scoped lookups ---\n\n byTestId(testId: string): Locator {\n return this.root.getByTestId(testId);\n }\n\n byRole(...args: Parameters<Locator[\"getByRole\"]>): Locator {\n return this.root.getByRole(...args);\n }\n\n byText(...args: Parameters<Locator[\"getByText\"]>): Locator {\n return this.root.getByText(...args);\n }\n\n byLabel(...args: Parameters<Locator[\"getByLabel\"]>): Locator {\n return this.root.getByLabel(...args);\n }\n\n locator(selector: string): Locator {\n return this.root.locator(selector);\n }\n\n // --- state ---\n\n async isVisible(): Promise<boolean> {\n return this.root.isVisible();\n }\n\n async exists(): Promise<boolean> {\n return exists(this.root);\n }\n\n async text(): Promise<string> {\n return getText(this.root);\n }\n\n async waitForStable(timeoutMs?: number): Promise<void> {\n await waitForVisible(this.root, timeoutMs);\n }\n\n async waitForHidden(timeoutMs?: number): Promise<void> {\n await this.root.waitFor({ state: \"hidden\", timeout: timeoutMs });\n }\n\n // --- actions, same implementations BasePage uses ---\n\n async safeClick(locator: Locator, timeoutMs?: number): Promise<void> {\n await safeClick(locator, timeoutMs);\n }\n\n async safeFill(locator: Locator, value: string): Promise<void> {\n await safeFill(locator, value);\n }\n\n async safeSelect(locator: Locator, value: string | string[]): Promise<void> {\n await safeSelect(locator, value);\n }\n\n async safeCheck(locator: Locator, checked = true): Promise<void> {\n await safeCheck(locator, checked);\n }\n\n async scrollIntoView(locator: Locator = this.root): Promise<void> {\n await scrollIntoView(locator);\n }\n\n async getText(locator: Locator): Promise<string> {\n return getText(locator);\n }\n\n async getAllTexts(locator: Locator): Promise<string[]> {\n return getAllTexts(locator);\n }\n\n /** Fills fields *within this component*, so selectors don't collide with the rest of the page. */\n async fillFields(fields: Record<string, string | number | boolean>): Promise<void> {\n await fillFields(this.page, fields, { resolve: (selector) => this.root.locator(selector) });\n }\n}\n","import type { Locator } from \"@playwright/test\";\nimport { AppError } from \"../../errors/app-error.js\";\nimport { getAllTexts, getText } from \"../actions.js\";\nimport { BaseComponent, type BaseComponentOptions } from \"./base-component.js\";\n\nexport interface TableComponentOptions extends BaseComponentOptions {\n /** Selector for header cells, relative to the table root. Default: `\"thead th\"`. */\n headerSelector?: string;\n /** Selector for data rows, relative to the table root. Default: `\"tbody tr\"`. */\n rowSelector?: string;\n /** Selector for cells, relative to a row. Default: `\"td\"`. */\n cellSelector?: string;\n}\n\n/**\n * Generic data-table/grid wrapper: row counts, cell lookup by column *name* rather than\n * brittle index, and whole-table extraction for assertions.\n *\n * Defaults target a standard `<table><thead><th>/<tbody><tr><td>` layout. For div-based grids\n * pass the three selectors, e.g.\n * `{ headerSelector: '[role=columnheader]', rowSelector: '[role=row]', cellSelector: '[role=gridcell]' }`.\n *\n * Contains no project selectors itself — a project subclasses it (or just constructs it with\n * its own root locator) per grid.\n */\nexport class TableComponent extends BaseComponent {\n private readonly headerSelector: string;\n private readonly rowSelector: string;\n private readonly cellSelector: string;\n\n constructor(options: TableComponentOptions) {\n super(options);\n this.headerSelector = options.headerSelector ?? \"thead th\";\n this.rowSelector = options.rowSelector ?? \"tbody tr\";\n this.cellSelector = options.cellSelector ?? \"td\";\n }\n\n /** All data rows. A live locator — safe to use with auto-retrying assertions. */\n get rows(): Locator {\n return this.root.locator(this.rowSelector);\n }\n\n get headerCells(): Locator {\n return this.root.locator(this.headerSelector);\n }\n\n row(index: number): Locator {\n return this.rows.nth(index);\n }\n\n cells(rowIndex: number): Locator {\n return this.row(rowIndex).locator(this.cellSelector);\n }\n\n async rowCount(): Promise<number> {\n return this.rows.count();\n }\n\n async isEmpty(): Promise<boolean> {\n return (await this.rowCount()) === 0;\n }\n\n /** Trimmed header labels, in order. */\n async headers(): Promise<string[]> {\n return getAllTexts(this.headerCells);\n }\n\n /**\n * Zero-based index of a column by its header label (exact match after trimming, falling back\n * to a case-insensitive contains match). Throws listing the available headers when not found —\n * a renamed column is otherwise a confusing \"cell is empty\" failure.\n */\n async columnIndex(header: string): Promise<number> {\n const headers = await this.headers();\n const exact = headers.indexOf(header.trim());\n if (exact !== -1) return exact;\n\n const needle = header.trim().toLowerCase();\n const loose = headers.findIndex((candidate) => candidate.toLowerCase().includes(needle));\n if (loose !== -1) return loose;\n\n throw new AppError(`Column \"${header}\" not found in table`, {\n code: \"TABLE_COLUMN_NOT_FOUND\",\n context: { requested: header, available: headers },\n });\n }\n\n /** A cell by row index and either a column index or a header label. */\n async cell(rowIndex: number, column: string | number): Promise<Locator> {\n const index = typeof column === \"number\" ? column : await this.columnIndex(column);\n return this.cells(rowIndex).nth(index);\n }\n\n async cellText(rowIndex: number, column: string | number): Promise<string> {\n return getText(await this.cell(rowIndex, column));\n }\n\n /** Every cell value of one row, in column order. */\n async rowValues(rowIndex: number): Promise<string[]> {\n return getAllTexts(this.cells(rowIndex));\n }\n\n /**\n * The whole table as `{ header: cellText }` objects — the most convenient shape for\n * assertions (`expect(await table.records()).toContainEqual({ Status: \"Approved\", ... })`).\n */\n async records(): Promise<Record<string, string>[]> {\n const headers = await this.headers();\n const count = await this.rowCount();\n const records: Record<string, string>[] = [];\n\n for (let rowIndex = 0; rowIndex < count; rowIndex++) {\n const values = await this.rowValues(rowIndex);\n const record: Record<string, string> = {};\n values.forEach((value, columnIndex) => {\n record[headers[columnIndex] ?? `column${columnIndex}`] = value;\n });\n records.push(record);\n }\n return records;\n }\n\n /** Rows containing `text` anywhere. Still a locator, so assertions on it auto-retry. */\n rowsContaining(text: string | RegExp): Locator {\n return this.rows.filter({ hasText: text });\n }\n\n /**\n * Rows whose cell in a given column matches `value`. Returns a locator (auto-retrying);\n * only the header lookup is awaited up front.\n */\n async rowsByColumn(column: string | number, value: string | RegExp): Promise<Locator> {\n const index = typeof column === \"number\" ? column : await this.columnIndex(column);\n return this.rows.filter({\n has: this.page.locator(`${this.cellSelector}:nth-child(${index + 1})`).filter({ hasText: value }),\n });\n }\n\n /** Waits until the table has at least `min` rows (default 1) — e.g. after a search or load. */\n async waitForRows(min = 1, timeoutMs = 15_000): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n if ((await this.rowCount()) >= min) return;\n if (Date.now() >= deadline) {\n throw new AppError(`Table did not reach ${min} row(s) within ${timeoutMs}ms`, {\n code: \"TABLE_ROWS_TIMEOUT\",\n context: { min, timeoutMs, actual: await this.rowCount() },\n });\n }\n await this.page.waitForTimeout(200);\n }\n }\n}\n","import { AppError } from \"../errors/app-error.js\";\n\nexport type Factory<T> = (container: ServiceContainer) => T;\n\n/**\n * Minimal typed service locator used internally by core (and available to projects)\n * for wiring services that aren't naturally expressed as Playwright fixtures — e.g.\n * a token provider shared by both the API client and UI auth setup. Playwright's own\n * `test.extend()` remains the primary DI mechanism for anything test-scoped; this\n * container is for singletons that outlive a single fixture chain.\n */\nexport class ServiceContainer {\n private readonly factories = new Map<string, Factory<unknown>>();\n private readonly singletons = new Map<string, unknown>();\n\n register<T>(key: string, factory: Factory<T>): void {\n this.factories.set(key, factory as Factory<unknown>);\n this.singletons.delete(key);\n }\n\n /** Replaces an existing registration — this is how a project overrides a core-provided service. */\n override<T>(key: string, factory: Factory<T>): void {\n this.register(key, factory);\n }\n\n resolve<T>(key: string): T {\n if (this.singletons.has(key)) {\n return this.singletons.get(key) as T;\n }\n const factory = this.factories.get(key);\n if (!factory) {\n throw new AppError(`No provider registered for service \"${key}\"`, { code: \"DI_UNRESOLVED\" });\n }\n const instance = factory(this);\n this.singletons.set(key, instance);\n return instance as T;\n }\n\n has(key: string): boolean {\n return this.factories.has(key);\n }\n}\n","import { AppError } from \"../errors/app-error.js\";\nimport { sleep } from \"./sleep.js\";\n\nexport interface WaitForConditionOptions {\n timeoutMs?: number;\n intervalMs?: number;\n /** Included in the thrown error when the timeout is reached. */\n message?: string;\n}\n\n/**\n * Polls `predicate` until it returns truthy, or throws `AppError` after `timeoutMs`.\n * For waiting on state that has no built-in Playwright wait — e.g. an async job's status\n * via `apiClient`, a queue draining, a background process finishing — as opposed to UI\n * state, which should use Playwright locator assertions/`waitFor` directly.\n */\nexport async function waitForCondition(\n predicate: () => Promise<boolean> | boolean,\n options: WaitForConditionOptions = {},\n): Promise<void> {\n const { timeoutMs = 30_000, intervalMs = 500, message = \"Condition was not met within timeout\" } = options;\n const deadline = Date.now() + timeoutMs;\n\n for (;;) {\n if (await predicate()) return;\n if (Date.now() >= deadline) {\n throw new AppError(message, { code: \"WAIT_TIMEOUT\", context: { timeoutMs, intervalMs } });\n }\n await sleep(intervalMs);\n }\n}\n","/**\n * Domain-neutral value generators. Core deliberately ships no test *data* (that belongs to\n * each project — see `docs/MULTI_TENANT.md`); these only produce unique/random primitives so\n * every project doesn't reinvent \"make me a name nothing else in the DB has\".\n */\n\nlet counter = 0;\n\nconst ALPHANUMERIC = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n\n/**\n * An identifier unique across parallel workers and repeated runs: timestamp + process id +\n * an in-process counter. Playwright shards tests across processes, so a bare counter or a\n * bare timestamp will collide.\n */\nexport function uniqueId(prefix?: string): string {\n counter += 1;\n const id = `${Date.now().toString(36)}${process.pid.toString(36)}${counter.toString(36)}`;\n return prefix ? `${prefix}-${id}` : id;\n}\n\n/** A unique, syntactically valid email — for signup/invite flows that reject duplicates. */\nexport function uniqueEmail(domain = \"example.test\", prefix = \"qa\"): string {\n return `${prefix}-${uniqueId()}@${domain}`;\n}\n\nexport function randomString(length = 8, charset: string = ALPHANUMERIC): string {\n let result = \"\";\n for (let i = 0; i < length; i++) {\n result += charset.charAt(Math.floor(Math.random() * charset.length));\n }\n return result;\n}\n\n/** Random integer in `[min, max]`, both inclusive. */\nexport function randomInt(min: number, max: number): number {\n if (min > max) throw new RangeError(`randomInt: min (${min}) must be <= max (${max})`);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\nexport function randomBool(): boolean {\n return Math.random() < 0.5;\n}\n\n/** One random element. Throws on an empty array rather than returning `undefined`. */\nexport function pickOne<T>(items: readonly T[]): T {\n if (items.length === 0) throw new RangeError(\"pickOne: cannot pick from an empty array\");\n return items[randomInt(0, items.length - 1)] as T;\n}\n\n/** `count` distinct random elements, in random order. */\nexport function pickSome<T>(items: readonly T[], count: number): T[] {\n if (count > items.length) {\n throw new RangeError(`pickSome: cannot pick ${count} items from an array of ${items.length}`);\n }\n const pool = [...items];\n const picked: T[] = [];\n for (let i = 0; i < count; i++) {\n const [item] = pool.splice(randomInt(0, pool.length - 1), 1);\n picked.push(item as T);\n }\n return picked;\n}\n\n/** ISO date (`YYYY-MM-DD`) offset from today — e.g. `isoDate(-30)` for a month ago. */\nexport function isoDate(dayOffset = 0, from: Date = new Date()): string {\n const date = new Date(from);\n date.setDate(date.getDate() + dayOffset);\n return date.toISOString().slice(0, 10);\n}\n"]}
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ var pino = require('pino');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var pino__default = /*#__PURE__*/_interopDefault(pino);
8
+
9
+ // src/logging/logger.ts
10
+ function createLogger(options = {}) {
11
+ const {
12
+ level = process.env.LOG_LEVEL ?? "info",
13
+ name = "playwright-core",
14
+ pretty = process.env.LOG_PRETTY === "true"
15
+ } = options;
16
+ return pino__default.default({
17
+ name,
18
+ level,
19
+ ...pretty ? {
20
+ transport: {
21
+ target: "pino-pretty",
22
+ options: { colorize: true, translateTime: "SYS:standard" }
23
+ }
24
+ } : {}
25
+ });
26
+ }
27
+ var logger = createLogger();
28
+
29
+ exports.createLogger = createLogger;
30
+ exports.logger = logger;
31
+ //# sourceMappingURL=index.cjs.map
32
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/logging/logger.ts"],"names":["pino"],"mappings":";;;;;;;;;AAaO,SAAS,YAAA,CAAa,OAAA,GAAyB,EAAC,EAAW;AAChE,EAAA,MAAM;AAAA,IACJ,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,SAAA,IAAa,MAAA;AAAA,IACjC,IAAA,GAAO,iBAAA;AAAA,IACP,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,UAAA,KAAe;AAAA,GACtC,GAAI,OAAA;AAEJ,EAAA,OAAOA,qBAAA,CAAK;AAAA,IACV,IAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAI,MAAA,GACA;AAAA,MACE,SAAA,EAAW;AAAA,QACT,MAAA,EAAQ,aAAA;AAAA,QACR,OAAA,EAAS,EAAE,QAAA,EAAU,IAAA,EAAM,eAAe,cAAA;AAAe;AAC3D,QAEF;AAAC,GACN,CAAA;AACH;AAGO,IAAM,SAAS,YAAA","file":"index.cjs","sourcesContent":["import pino, { type Logger } from \"pino\";\n\nexport interface LoggerOptions {\n level?: string;\n name?: string;\n /**\n * Pretty-print logs for local/interactive runs. Requires the optional\n * `pino-pretty` dev dependency to be installed in the consuming project;\n * leave off (default) for CI where structured JSON logs are preferred.\n */\n pretty?: boolean;\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const {\n level = process.env.LOG_LEVEL ?? \"info\",\n name = \"playwright-core\",\n pretty = process.env.LOG_PRETTY === \"true\",\n } = options;\n\n return pino({\n name,\n level,\n ...(pretty\n ? {\n transport: {\n target: \"pino-pretty\",\n options: { colorize: true, translateTime: \"SYS:standard\" },\n },\n }\n : {}),\n });\n}\n\n/** Default shared logger instance. Prefer `createLogger()` when a project needs a distinct name/level. */\nexport const logger = createLogger();\n\nexport type { Logger };\n"]}
@@ -0,0 +1,18 @@
1
+ import pino, { Logger } from 'pino';
2
+ export { Logger } from 'pino';
3
+
4
+ interface LoggerOptions {
5
+ level?: string;
6
+ name?: string;
7
+ /**
8
+ * Pretty-print logs for local/interactive runs. Requires the optional
9
+ * `pino-pretty` dev dependency to be installed in the consuming project;
10
+ * leave off (default) for CI where structured JSON logs are preferred.
11
+ */
12
+ pretty?: boolean;
13
+ }
14
+ declare function createLogger(options?: LoggerOptions): Logger;
15
+ /** Default shared logger instance. Prefer `createLogger()` when a project needs a distinct name/level. */
16
+ declare const logger: pino.Logger;
17
+
18
+ export { type LoggerOptions, createLogger, logger };
@@ -0,0 +1,18 @@
1
+ import pino, { Logger } from 'pino';
2
+ export { Logger } from 'pino';
3
+
4
+ interface LoggerOptions {
5
+ level?: string;
6
+ name?: string;
7
+ /**
8
+ * Pretty-print logs for local/interactive runs. Requires the optional
9
+ * `pino-pretty` dev dependency to be installed in the consuming project;
10
+ * leave off (default) for CI where structured JSON logs are preferred.
11
+ */
12
+ pretty?: boolean;
13
+ }
14
+ declare function createLogger(options?: LoggerOptions): Logger;
15
+ /** Default shared logger instance. Prefer `createLogger()` when a project needs a distinct name/level. */
16
+ declare const logger: pino.Logger;
17
+
18
+ export { type LoggerOptions, createLogger, logger };
@@ -0,0 +1,25 @@
1
+ import pino from 'pino';
2
+
3
+ // src/logging/logger.ts
4
+ function createLogger(options = {}) {
5
+ const {
6
+ level = process.env.LOG_LEVEL ?? "info",
7
+ name = "playwright-core",
8
+ pretty = process.env.LOG_PRETTY === "true"
9
+ } = options;
10
+ return pino({
11
+ name,
12
+ level,
13
+ ...pretty ? {
14
+ transport: {
15
+ target: "pino-pretty",
16
+ options: { colorize: true, translateTime: "SYS:standard" }
17
+ }
18
+ } : {}
19
+ });
20
+ }
21
+ var logger = createLogger();
22
+
23
+ export { createLogger, logger };
24
+ //# sourceMappingURL=index.js.map
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/logging/logger.ts"],"names":[],"mappings":";;;AAaO,SAAS,YAAA,CAAa,OAAA,GAAyB,EAAC,EAAW;AAChE,EAAA,MAAM;AAAA,IACJ,KAAA,GAAQ,OAAA,CAAQ,GAAA,CAAI,SAAA,IAAa,MAAA;AAAA,IACjC,IAAA,GAAO,iBAAA;AAAA,IACP,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,UAAA,KAAe;AAAA,GACtC,GAAI,OAAA;AAEJ,EAAA,OAAO,IAAA,CAAK;AAAA,IACV,IAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAI,MAAA,GACA;AAAA,MACE,SAAA,EAAW;AAAA,QACT,MAAA,EAAQ,aAAA;AAAA,QACR,OAAA,EAAS,EAAE,QAAA,EAAU,IAAA,EAAM,eAAe,cAAA;AAAe;AAC3D,QAEF;AAAC,GACN,CAAA;AACH;AAGO,IAAM,SAAS,YAAA","file":"index.js","sourcesContent":["import pino, { type Logger } from \"pino\";\n\nexport interface LoggerOptions {\n level?: string;\n name?: string;\n /**\n * Pretty-print logs for local/interactive runs. Requires the optional\n * `pino-pretty` dev dependency to be installed in the consuming project;\n * leave off (default) for CI where structured JSON logs are preferred.\n */\n pretty?: boolean;\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const {\n level = process.env.LOG_LEVEL ?? \"info\",\n name = \"playwright-core\",\n pretty = process.env.LOG_PRETTY === \"true\",\n } = options;\n\n return pino({\n name,\n level,\n ...(pretty\n ? {\n transport: {\n target: \"pino-pretty\",\n options: { colorize: true, translateTime: \"SYS:standard\" },\n },\n }\n : {}),\n });\n}\n\n/** Default shared logger instance. Prefer `createLogger()` when a project needs a distinct name/level. */\nexport const logger = createLogger();\n\nexport type { Logger };\n"]}
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ // src/reporting/allure-setup.ts
4
+ function buildReporterConfig(config) {
5
+ const reporters = [["html", { open: "never" }]];
6
+ if (config.reporting.allureEnabled) {
7
+ reporters.push(["allure-playwright", { resultsDir: config.reporting.resultsDir, detail: true }]);
8
+ }
9
+ return reporters;
10
+ }
11
+
12
+ // src/reporting/attachments.ts
13
+ async function attachText(testInfo, name, body) {
14
+ await testInfo.attach(name, { body, contentType: "text/plain" });
15
+ }
16
+ async function attachJson(testInfo, name, value) {
17
+ await testInfo.attach(name, {
18
+ body: JSON.stringify(value, null, 2),
19
+ contentType: "application/json"
20
+ });
21
+ }
22
+ async function attachScreenshot(testInfo, name, buffer) {
23
+ await testInfo.attach(name, { body: buffer, contentType: "image/png" });
24
+ }
25
+
26
+ // src/reporting/meta.ts
27
+ function toArray(value) {
28
+ if (value === void 0) return [];
29
+ return Array.isArray(value) ? value : [value];
30
+ }
31
+ function meta(options) {
32
+ const tags = toArray(options.tag).map((tag) => tag.startsWith("@") ? tag : `@${tag}`);
33
+ const testCaseAnnotations = toArray(options.testCase).map((id) => ({
34
+ type: "testCase",
35
+ description: id
36
+ }));
37
+ const annotation = [...testCaseAnnotations, ...options.annotation ?? []];
38
+ return {
39
+ ...tags.length > 0 ? { tag: tags } : {},
40
+ ...annotation.length > 0 ? { annotation } : {}
41
+ };
42
+ }
43
+ function linkTestCases(testInfo, urlTemplate) {
44
+ if (!urlTemplate) return;
45
+ for (const annotation of testInfo.annotations) {
46
+ if (annotation.type === "testCase" && annotation.description) {
47
+ annotation.description = urlTemplate.replace("{id}", annotation.description);
48
+ }
49
+ }
50
+ }
51
+
52
+ exports.attachJson = attachJson;
53
+ exports.attachScreenshot = attachScreenshot;
54
+ exports.attachText = attachText;
55
+ exports.buildReporterConfig = buildReporterConfig;
56
+ exports.linkTestCases = linkTestCases;
57
+ exports.meta = meta;
58
+ //# sourceMappingURL=index.cjs.map
59
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/reporting/allure-setup.ts","../../src/reporting/attachments.ts","../../src/reporting/meta.ts"],"names":[],"mappings":";;;AAaO,SAAS,oBAAoB,MAAA,EAAiE;AACnG,EAAA,MAAM,SAAA,GAAuC,CAAC,CAAC,MAAA,EAAQ,EAAE,IAAA,EAAM,OAAA,EAAS,CAAC,CAAA;AACzE,EAAA,IAAI,MAAA,CAAO,UAAU,aAAA,EAAe;AAClC,IAAA,SAAA,CAAU,IAAA,CAAK,CAAC,mBAAA,EAAqB,EAAE,UAAA,EAAY,MAAA,CAAO,SAAA,CAAU,UAAA,EAAY,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAA;AAAA,EACjG;AACA,EAAA,OAAO,SAAA;AACT;;;ACXA,eAAsB,UAAA,CAAW,QAAA,EAAoB,IAAA,EAAc,IAAA,EAA6B;AAC9F,EAAA,MAAM,SAAS,MAAA,CAAO,IAAA,EAAM,EAAE,IAAA,EAAM,WAAA,EAAa,cAAc,CAAA;AACjE;AAEA,eAAsB,UAAA,CAAW,QAAA,EAAoB,IAAA,EAAc,KAAA,EAA+B;AAChG,EAAA,MAAM,QAAA,CAAS,OAAO,IAAA,EAAM;AAAA,IAC1B,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,MAAM,CAAC,CAAA;AAAA,IACnC,WAAA,EAAa;AAAA,GACd,CAAA;AACH;AAEA,eAAsB,gBAAA,CAAiB,QAAA,EAAoB,IAAA,EAAc,MAAA,EAA+B;AACtG,EAAA,MAAM,QAAA,CAAS,OAAO,IAAA,EAAM,EAAE,MAAM,MAAA,EAAQ,WAAA,EAAa,aAAa,CAAA;AACxE;;;ACLA,SAAS,QAAQ,KAAA,EAAgD;AAC/D,EAAA,IAAI,KAAA,KAAU,MAAA,EAAW,OAAO,EAAC;AACjC,EAAA,OAAO,MAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,KAAA,GAAQ,CAAC,KAAK,CAAA;AAC9C;AAcO,SAAS,KAAK,OAAA,EAAoC;AACvD,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,GAAG,EAAE,GAAA,CAAI,CAAC,GAAA,KAAS,GAAA,CAAI,WAAW,GAAG,CAAA,GAAI,GAAA,GAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAG,CAAA;AACtF,EAAA,MAAM,sBAAsB,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,CAAE,GAAA,CAAI,CAAC,EAAA,MAAQ;AAAA,IACjE,IAAA,EAAM,UAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf,CAAE,CAAA;AAEF,EAAA,MAAM,UAAA,GAAa,CAAC,GAAG,mBAAA,EAAqB,GAAI,OAAA,CAAQ,UAAA,IAAc,EAAG,CAAA;AAEzE,EAAA,OAAO;AAAA,IACL,GAAI,KAAK,MAAA,GAAS,CAAA,GAAI,EAAE,GAAA,EAAK,IAAA,KAAS,EAAC;AAAA,IACvC,GAAI,UAAA,CAAW,MAAA,GAAS,IAAI,EAAE,UAAA,KAAe;AAAC,GAChD;AACF;AAMO,SAAS,aAAA,CAAc,UAAoB,WAAA,EAAuC;AACvF,EAAA,IAAI,CAAC,WAAA,EAAa;AAClB,EAAA,KAAA,MAAW,UAAA,IAAc,SAAS,WAAA,EAAa;AAC7C,IAAA,IAAI,UAAA,CAAW,IAAA,KAAS,UAAA,IAAc,UAAA,CAAW,WAAA,EAAa;AAC5D,MAAA,UAAA,CAAW,WAAA,GAAc,WAAA,CAAY,OAAA,CAAQ,MAAA,EAAQ,WAAW,WAAW,CAAA;AAAA,IAC7E;AAAA,EACF;AACF","file":"index.cjs","sourcesContent":["import type { AppConfig } from \"../config/schema.js\";\n\nexport type PlaywrightReporterEntry = [string] | [string, Record<string, unknown>];\n\n/**\n * Builds the `reporter` array for a project's `playwright.config.ts`. Always includes\n * the built-in HTML reporter; adds Allure when `reporting.allureEnabled` is true.\n *\n * Allure is optional and NOT bundled transitively: because Playwright resolves reporter\n * packages relative to the project that runs the tests, a project enabling Allure must add\n * `allure-playwright` (and `allure-js-commons` if using manual annotations) to its own\n * `devDependencies`. See `docs/EXTENDING.md`.\n */\nexport function buildReporterConfig(config: Pick<AppConfig, \"reporting\">): PlaywrightReporterEntry[] {\n const reporters: PlaywrightReporterEntry[] = [[\"html\", { open: \"never\" }]];\n if (config.reporting.allureEnabled) {\n reporters.push([\"allure-playwright\", { resultsDir: config.reporting.resultsDir, detail: true }]);\n }\n return reporters;\n}\n","import type { TestInfo } from \"@playwright/test\";\n\n/**\n * Report attachment helpers. These show up in the HTML report (and Allure, when enabled)\n * next to the test, which is usually the difference between a failure you can diagnose from\n * CI and one you have to reproduce locally.\n */\n\nexport async function attachText(testInfo: TestInfo, name: string, body: string): Promise<void> {\n await testInfo.attach(name, { body, contentType: \"text/plain\" });\n}\n\nexport async function attachJson(testInfo: TestInfo, name: string, value: unknown): Promise<void> {\n await testInfo.attach(name, {\n body: JSON.stringify(value, null, 2),\n contentType: \"application/json\",\n });\n}\n\nexport async function attachScreenshot(testInfo: TestInfo, name: string, buffer: Buffer): Promise<void> {\n await testInfo.attach(name, { body: buffer, contentType: \"image/png\" });\n}\n","import type { TestInfo } from \"@playwright/test\";\n\nexport interface TestMetaOptions {\n /** Test-case id(s) in your test management tool, e.g. `\"TC-1234\"` or `[\"TC-1\", \"TC-2\"]`. */\n testCase?: string | string[];\n /** Tag(s) for filtering with `--grep`, e.g. `\"@smoke\"`. The leading `@` is added if missing. */\n tag?: string | string[];\n /** Free-form annotations, e.g. `{ type: \"issue\", description: \"JIRA-42\" }`. */\n annotation?: { type: string; description?: string }[];\n}\n\nexport interface TestMeta {\n tag?: string[];\n annotation?: { type: string; description?: string }[];\n}\n\nfunction toArray(value: string | string[] | undefined): string[] {\n if (value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n}\n\n/**\n * Builds the `details` argument of `test(title, details, body)` from test-case ids and tags,\n * so the mapping between an automated test and its test-case id lives in the test itself and\n * shows up in the report.\n *\n * ```ts\n * test(\"login success\", meta({ testCase: \"TC-1234\", tag: \"@smoke\" }), async ({ page }) => { ... });\n * ```\n *\n * Set `reporting.testCaseUrlTemplate` (env `TEST_CASE_URL_TEMPLATE`, with `{id}` as the\n * placeholder) to turn the ids into links — see `linkTestCases`.\n */\nexport function meta(options: TestMetaOptions): TestMeta {\n const tags = toArray(options.tag).map((tag) => (tag.startsWith(\"@\") ? tag : `@${tag}`));\n const testCaseAnnotations = toArray(options.testCase).map((id) => ({\n type: \"testCase\",\n description: id,\n }));\n\n const annotation = [...testCaseAnnotations, ...(options.annotation ?? [])];\n\n return {\n ...(tags.length > 0 ? { tag: tags } : {}),\n ...(annotation.length > 0 ? { annotation } : {}),\n };\n}\n\n/**\n * Rewrites `testCase` annotations into full URLs using a template containing `{id}`.\n * Call from a project's `beforeEach`/fixture when `reporting.testCaseUrlTemplate` is set.\n */\nexport function linkTestCases(testInfo: TestInfo, urlTemplate: string | undefined): void {\n if (!urlTemplate) return;\n for (const annotation of testInfo.annotations) {\n if (annotation.type === \"testCase\" && annotation.description) {\n annotation.description = urlTemplate.replace(\"{id}\", annotation.description);\n }\n }\n}\n"]}
@@ -0,0 +1,63 @@
1
+ import { A as AppConfig } from '../schema-y5w2hbT-.cjs';
2
+ import { TestInfo } from '@playwright/test';
3
+ import 'zod';
4
+
5
+ type PlaywrightReporterEntry = [string] | [string, Record<string, unknown>];
6
+ /**
7
+ * Builds the `reporter` array for a project's `playwright.config.ts`. Always includes
8
+ * the built-in HTML reporter; adds Allure when `reporting.allureEnabled` is true.
9
+ *
10
+ * Allure is optional and NOT bundled transitively: because Playwright resolves reporter
11
+ * packages relative to the project that runs the tests, a project enabling Allure must add
12
+ * `allure-playwright` (and `allure-js-commons` if using manual annotations) to its own
13
+ * `devDependencies`. See `docs/EXTENDING.md`.
14
+ */
15
+ declare function buildReporterConfig(config: Pick<AppConfig, "reporting">): PlaywrightReporterEntry[];
16
+
17
+ /**
18
+ * Report attachment helpers. These show up in the HTML report (and Allure, when enabled)
19
+ * next to the test, which is usually the difference between a failure you can diagnose from
20
+ * CI and one you have to reproduce locally.
21
+ */
22
+ declare function attachText(testInfo: TestInfo, name: string, body: string): Promise<void>;
23
+ declare function attachJson(testInfo: TestInfo, name: string, value: unknown): Promise<void>;
24
+ declare function attachScreenshot(testInfo: TestInfo, name: string, buffer: Buffer): Promise<void>;
25
+
26
+ interface TestMetaOptions {
27
+ /** Test-case id(s) in your test management tool, e.g. `"TC-1234"` or `["TC-1", "TC-2"]`. */
28
+ testCase?: string | string[];
29
+ /** Tag(s) for filtering with `--grep`, e.g. `"@smoke"`. The leading `@` is added if missing. */
30
+ tag?: string | string[];
31
+ /** Free-form annotations, e.g. `{ type: "issue", description: "JIRA-42" }`. */
32
+ annotation?: {
33
+ type: string;
34
+ description?: string;
35
+ }[];
36
+ }
37
+ interface TestMeta {
38
+ tag?: string[];
39
+ annotation?: {
40
+ type: string;
41
+ description?: string;
42
+ }[];
43
+ }
44
+ /**
45
+ * Builds the `details` argument of `test(title, details, body)` from test-case ids and tags,
46
+ * so the mapping between an automated test and its test-case id lives in the test itself and
47
+ * shows up in the report.
48
+ *
49
+ * ```ts
50
+ * test("login success", meta({ testCase: "TC-1234", tag: "@smoke" }), async ({ page }) => { ... });
51
+ * ```
52
+ *
53
+ * Set `reporting.testCaseUrlTemplate` (env `TEST_CASE_URL_TEMPLATE`, with `{id}` as the
54
+ * placeholder) to turn the ids into links — see `linkTestCases`.
55
+ */
56
+ declare function meta(options: TestMetaOptions): TestMeta;
57
+ /**
58
+ * Rewrites `testCase` annotations into full URLs using a template containing `{id}`.
59
+ * Call from a project's `beforeEach`/fixture when `reporting.testCaseUrlTemplate` is set.
60
+ */
61
+ declare function linkTestCases(testInfo: TestInfo, urlTemplate: string | undefined): void;
62
+
63
+ export { type PlaywrightReporterEntry, type TestMeta, type TestMetaOptions, attachJson, attachScreenshot, attachText, buildReporterConfig, linkTestCases, meta };
@@ -0,0 +1,63 @@
1
+ import { A as AppConfig } from '../schema-y5w2hbT-.js';
2
+ import { TestInfo } from '@playwright/test';
3
+ import 'zod';
4
+
5
+ type PlaywrightReporterEntry = [string] | [string, Record<string, unknown>];
6
+ /**
7
+ * Builds the `reporter` array for a project's `playwright.config.ts`. Always includes
8
+ * the built-in HTML reporter; adds Allure when `reporting.allureEnabled` is true.
9
+ *
10
+ * Allure is optional and NOT bundled transitively: because Playwright resolves reporter
11
+ * packages relative to the project that runs the tests, a project enabling Allure must add
12
+ * `allure-playwright` (and `allure-js-commons` if using manual annotations) to its own
13
+ * `devDependencies`. See `docs/EXTENDING.md`.
14
+ */
15
+ declare function buildReporterConfig(config: Pick<AppConfig, "reporting">): PlaywrightReporterEntry[];
16
+
17
+ /**
18
+ * Report attachment helpers. These show up in the HTML report (and Allure, when enabled)
19
+ * next to the test, which is usually the difference between a failure you can diagnose from
20
+ * CI and one you have to reproduce locally.
21
+ */
22
+ declare function attachText(testInfo: TestInfo, name: string, body: string): Promise<void>;
23
+ declare function attachJson(testInfo: TestInfo, name: string, value: unknown): Promise<void>;
24
+ declare function attachScreenshot(testInfo: TestInfo, name: string, buffer: Buffer): Promise<void>;
25
+
26
+ interface TestMetaOptions {
27
+ /** Test-case id(s) in your test management tool, e.g. `"TC-1234"` or `["TC-1", "TC-2"]`. */
28
+ testCase?: string | string[];
29
+ /** Tag(s) for filtering with `--grep`, e.g. `"@smoke"`. The leading `@` is added if missing. */
30
+ tag?: string | string[];
31
+ /** Free-form annotations, e.g. `{ type: "issue", description: "JIRA-42" }`. */
32
+ annotation?: {
33
+ type: string;
34
+ description?: string;
35
+ }[];
36
+ }
37
+ interface TestMeta {
38
+ tag?: string[];
39
+ annotation?: {
40
+ type: string;
41
+ description?: string;
42
+ }[];
43
+ }
44
+ /**
45
+ * Builds the `details` argument of `test(title, details, body)` from test-case ids and tags,
46
+ * so the mapping between an automated test and its test-case id lives in the test itself and
47
+ * shows up in the report.
48
+ *
49
+ * ```ts
50
+ * test("login success", meta({ testCase: "TC-1234", tag: "@smoke" }), async ({ page }) => { ... });
51
+ * ```
52
+ *
53
+ * Set `reporting.testCaseUrlTemplate` (env `TEST_CASE_URL_TEMPLATE`, with `{id}` as the
54
+ * placeholder) to turn the ids into links — see `linkTestCases`.
55
+ */
56
+ declare function meta(options: TestMetaOptions): TestMeta;
57
+ /**
58
+ * Rewrites `testCase` annotations into full URLs using a template containing `{id}`.
59
+ * Call from a project's `beforeEach`/fixture when `reporting.testCaseUrlTemplate` is set.
60
+ */
61
+ declare function linkTestCases(testInfo: TestInfo, urlTemplate: string | undefined): void;
62
+
63
+ export { type PlaywrightReporterEntry, type TestMeta, type TestMetaOptions, attachJson, attachScreenshot, attachText, buildReporterConfig, linkTestCases, meta };