@reasonabletech/config-playwright 0.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.
- package/README.md +113 -0
- package/dist/base.js +170 -0
- package/dist/base.js.map +1 -0
- package/dist/cross-app.js +269 -0
- package/dist/cross-app.js.map +1 -0
- package/dist/index.js +253 -0
- package/dist/index.js.map +1 -0
- package/dist/src/base.d.ts +44 -0
- package/dist/src/base.d.ts.map +1 -0
- package/dist/src/cross-app.d.ts +96 -0
- package/dist/src/cross-app.d.ts.map +1 -0
- package/dist/src/index.d.ts +61 -0
- package/dist/src/index.d.ts.map +1 -0
- package/docs/README.md +31 -0
- package/docs/api/api-reference.md +689 -0
- package/docs/guides/migration.md +47 -0
- package/docs/guides/usage-guide.md +111 -0
- package/package.json +93 -0
- package/src/base.ts +124 -0
- package/src/cross-app.ts +299 -0
- package/src/index.ts +207 -0
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# @reasonabletech/config-playwright
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@reasonabletech/config-playwright)
|
|
4
|
+
[](https://www.npmjs.com/package/@reasonabletech/config-playwright)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
|
|
8
|
+
`@reasonabletech/config-playwright` provides shared Playwright configuration factories for single-app and cross-app browser test suites. `createCrossAppConfig` is designed for suites that test across multiple running services, while `createPlaywrightConfig` handles the common single-app case.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add -D @reasonabletech/config-playwright @playwright/test
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Peer Dependencies
|
|
17
|
+
|
|
18
|
+
| Dependency | Version | Required |
|
|
19
|
+
| ---------------- | --------- | -------- |
|
|
20
|
+
| @playwright/test | >= 1.40 | Yes |
|
|
21
|
+
| lighthouse | >= 10.0 | Optional |
|
|
22
|
+
|
|
23
|
+
This package provides Playwright configuration factories and requires @playwright/test 1.40+ for modern browser testing features. Install `lighthouse` if using the performance configuration exports.
|
|
24
|
+
|
|
25
|
+
## Exported Entry Points
|
|
26
|
+
|
|
27
|
+
| Import Path | Purpose | Main Exports |
|
|
28
|
+
| --------------------------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
29
|
+
| `@reasonabletech/config-playwright` | General Playwright defaults | `createPlaywrightConfig`, `createCIConfig`, `createBaseConfig`, `createCrossAppConfig` |
|
|
30
|
+
| `@reasonabletech/config-playwright/base` | Single-app browser presets | `createBaseConfig`, `createDesktopConfig`, `createMobileConfig`, `createChromiumConfig` |
|
|
31
|
+
| `@reasonabletech/config-playwright/cross-app` | Cross-app and specialized suites | `createCrossAppConfig`, `createAccessibilityConfig`, `createPerformanceConfig`, `createAuthTestConfig`, `createAuthWorkflowConfig` |
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### Standard Project Configuration
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
// playwright.config.ts
|
|
39
|
+
import { createPlaywrightConfig } from "@reasonabletech/config-playwright";
|
|
40
|
+
|
|
41
|
+
export default createPlaywrightConfig({
|
|
42
|
+
use: {
|
|
43
|
+
baseURL: "http://localhost:3000",
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### CI-Oriented Configuration
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// playwright.config.ts
|
|
52
|
+
import { createCIConfig } from "@reasonabletech/config-playwright";
|
|
53
|
+
|
|
54
|
+
export default createCIConfig({
|
|
55
|
+
use: {
|
|
56
|
+
baseURL: "https://staging.example.com",
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Desktop-Only Configuration
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// playwright.config.ts
|
|
65
|
+
import { createDesktopConfig } from "@reasonabletech/config-playwright/base";
|
|
66
|
+
|
|
67
|
+
export default createDesktopConfig();
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Cross-App Configuration
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// playwright.config.ts
|
|
74
|
+
import { createCrossAppConfig } from "@reasonabletech/config-playwright/cross-app";
|
|
75
|
+
|
|
76
|
+
const environments = {
|
|
77
|
+
development: {
|
|
78
|
+
baseUrls: {
|
|
79
|
+
app: "http://localhost:3000",
|
|
80
|
+
admin: "http://localhost:3001",
|
|
81
|
+
},
|
|
82
|
+
services: {
|
|
83
|
+
useRealServices: false,
|
|
84
|
+
mockExternalAPIs: true,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
staging: {
|
|
88
|
+
baseUrls: {
|
|
89
|
+
app: "https://staging.example.com",
|
|
90
|
+
admin: "https://admin-staging.example.com",
|
|
91
|
+
},
|
|
92
|
+
services: {
|
|
93
|
+
useRealServices: true,
|
|
94
|
+
mockExternalAPIs: false,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
} as const;
|
|
98
|
+
|
|
99
|
+
export default createCrossAppConfig({ environments });
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`createCrossAppConfig` uses `TEST_ENV` to select the active environment (`development` by default).
|
|
103
|
+
|
|
104
|
+
## Changelog
|
|
105
|
+
|
|
106
|
+
See [CHANGELOG.md](./CHANGELOG.md) for release history.
|
|
107
|
+
|
|
108
|
+
This package follows [Semantic Versioning](https://semver.org/). Breaking changes are documented with migration guides when applicable.
|
|
109
|
+
|
|
110
|
+
## Additional References
|
|
111
|
+
|
|
112
|
+
- [Usage Guide](./docs/guides/usage-guide.md)
|
|
113
|
+
- [Package Docs](./docs/README.md)
|
package/dist/base.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
// src/base.ts
|
|
4
|
+
var baseConfig = {
|
|
5
|
+
// Test discovery and execution
|
|
6
|
+
testDir: "./tests/acceptance",
|
|
7
|
+
testMatch: "**/*.{test,spec}.{ts,js}",
|
|
8
|
+
// Global test settings
|
|
9
|
+
fullyParallel: true,
|
|
10
|
+
forbidOnly: Boolean(process.env.CI),
|
|
11
|
+
retries: process.env.CI !== void 0 ? 2 : 0,
|
|
12
|
+
workers: process.env.CI !== void 0 ? 4 : void 0,
|
|
13
|
+
// Test execution timeouts
|
|
14
|
+
timeout: 30 * 1e3,
|
|
15
|
+
// 30 seconds for individual tests
|
|
16
|
+
expect: {
|
|
17
|
+
timeout: 5 * 1e3
|
|
18
|
+
// 5 seconds for assertions
|
|
19
|
+
},
|
|
20
|
+
// Reporter configuration for different environments
|
|
21
|
+
reporter: [
|
|
22
|
+
["html", { outputFolder: "./generated/playwright/reports" }],
|
|
23
|
+
["json", { outputFile: "./generated/playwright/results.json" }],
|
|
24
|
+
process.env.CI !== void 0 ? ["github"] : ["list"]
|
|
25
|
+
],
|
|
26
|
+
// Output folder for test results
|
|
27
|
+
outputDir: "./generated/playwright/test-results",
|
|
28
|
+
// Global test options
|
|
29
|
+
use: {
|
|
30
|
+
// Browser context settings
|
|
31
|
+
viewport: { width: 1280, height: 720 },
|
|
32
|
+
ignoreHTTPSErrors: true,
|
|
33
|
+
headless: true,
|
|
34
|
+
// Always headless by default (use --headed flag to override)
|
|
35
|
+
// Action timeouts
|
|
36
|
+
actionTimeout: 10 * 1e3,
|
|
37
|
+
// 10 seconds for actions
|
|
38
|
+
navigationTimeout: 30 * 1e3,
|
|
39
|
+
// 30 seconds for navigation
|
|
40
|
+
// Debugging and artifact collection - sensible defaults
|
|
41
|
+
trace: "on-first-retry",
|
|
42
|
+
video: "retain-on-failure",
|
|
43
|
+
screenshot: "only-on-failure",
|
|
44
|
+
// No authentication state by default (apps can override)
|
|
45
|
+
storageState: void 0
|
|
46
|
+
},
|
|
47
|
+
// Browser and device matrix
|
|
48
|
+
// Local dev: Chromium only for speed
|
|
49
|
+
// CI: Full browser matrix for compatibility testing
|
|
50
|
+
projects: process.env.CI !== void 0 ? [
|
|
51
|
+
// Desktop browsers
|
|
52
|
+
{
|
|
53
|
+
name: "chromium",
|
|
54
|
+
use: { ...devices["Desktop Chrome"] }
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "firefox",
|
|
58
|
+
use: { ...devices["Desktop Firefox"] }
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "webkit",
|
|
62
|
+
use: { ...devices["Desktop Safari"] }
|
|
63
|
+
},
|
|
64
|
+
// Mobile devices
|
|
65
|
+
{
|
|
66
|
+
name: "Mobile Chrome",
|
|
67
|
+
use: { ...devices["Pixel 5"] }
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "Mobile Safari",
|
|
71
|
+
use: { ...devices["iPhone 12"] }
|
|
72
|
+
},
|
|
73
|
+
// Tablet devices
|
|
74
|
+
{
|
|
75
|
+
name: "iPad",
|
|
76
|
+
use: { ...devices["iPad Pro"] }
|
|
77
|
+
}
|
|
78
|
+
] : [
|
|
79
|
+
// Local development: Chromium only for fast iteration
|
|
80
|
+
{
|
|
81
|
+
name: "chromium",
|
|
82
|
+
use: { ...devices["Desktop Chrome"] }
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
// Development server integration - common defaults for web apps
|
|
86
|
+
webServer: process.env.CI !== void 0 ? void 0 : {
|
|
87
|
+
command: "pnpm dev",
|
|
88
|
+
reuseExistingServer: true,
|
|
89
|
+
timeout: 120 * 1e3
|
|
90
|
+
// 2 minutes to start
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// src/base.ts
|
|
95
|
+
var EMPTY_CONFIG = {};
|
|
96
|
+
var desktopConfig = {
|
|
97
|
+
projects: [
|
|
98
|
+
{
|
|
99
|
+
name: "chromium",
|
|
100
|
+
use: { ...devices["Desktop Chrome"] }
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "firefox",
|
|
104
|
+
use: { ...devices["Desktop Firefox"] }
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "webkit",
|
|
108
|
+
use: { ...devices["Desktop Safari"] }
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
};
|
|
112
|
+
var mobileConfig = {
|
|
113
|
+
projects: [
|
|
114
|
+
{
|
|
115
|
+
name: "Mobile Chrome",
|
|
116
|
+
use: { ...devices["Pixel 5"] }
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "Mobile Safari",
|
|
120
|
+
use: { ...devices["iPhone 12"] }
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
};
|
|
124
|
+
var chromiumOnlyConfig = {
|
|
125
|
+
projects: [
|
|
126
|
+
{
|
|
127
|
+
name: "chromium",
|
|
128
|
+
use: { ...devices["Desktop Chrome"] }
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
};
|
|
132
|
+
function createBaseConfig(customConfig = EMPTY_CONFIG) {
|
|
133
|
+
return {
|
|
134
|
+
...baseConfig,
|
|
135
|
+
...customConfig,
|
|
136
|
+
use: {
|
|
137
|
+
...baseConfig.use,
|
|
138
|
+
...customConfig.use,
|
|
139
|
+
// Single-app specific settings
|
|
140
|
+
storageState: void 0
|
|
141
|
+
// No cross-app auth state by default
|
|
142
|
+
},
|
|
143
|
+
projects: customConfig.projects ?? baseConfig.projects
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function createDesktopConfig(customConfig = EMPTY_CONFIG) {
|
|
147
|
+
return createBaseConfig({
|
|
148
|
+
...customConfig,
|
|
149
|
+
projects: desktopConfig.projects
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function createMobileConfig(customConfig = EMPTY_CONFIG) {
|
|
153
|
+
return createBaseConfig({
|
|
154
|
+
...customConfig,
|
|
155
|
+
projects: mobileConfig.projects
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function createChromiumConfig(customConfig = EMPTY_CONFIG) {
|
|
159
|
+
return createBaseConfig({
|
|
160
|
+
...customConfig,
|
|
161
|
+
projects: chromiumOnlyConfig.projects,
|
|
162
|
+
workers: 1
|
|
163
|
+
// Single worker for development
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
var base_default = createBaseConfig;
|
|
167
|
+
|
|
168
|
+
export { chromiumOnlyConfig, createBaseConfig, createChromiumConfig, createDesktopConfig, createMobileConfig, base_default as default, desktopConfig, mobileConfig };
|
|
169
|
+
//# sourceMappingURL=base.js.map
|
|
170
|
+
//# sourceMappingURL=base.js.map
|
package/dist/base.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/base.ts"],"names":["devices"],"mappings":"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","file":"base.js","sourcesContent":["/**\n * Base Playwright configuration for all applications\n * @module @reasonabletech/config-playwright\n */\n\nimport { type PlaywrightTestConfig, devices } from \"@playwright/test\";\n\n/**\n * Recursively makes all properties of `T` readonly.\n *\n * Useful for configuration objects defined with `as const`, ensuring callers\n * don't accidentally mutate shared config.\n */\nexport type DeepReadonly<T> = {\n readonly [P in keyof T]: T[P] extends ReadonlyArray<infer U>\n ? ReadonlyArray<DeepReadonly<U>>\n : T[P] extends Array<infer U>\n ? ReadonlyArray<DeepReadonly<U>>\n : T[P] extends object\n ? DeepReadonly<T[P]>\n : T[P];\n};\n\n/**\n * Immutable Playwright config type accepted by config helpers.\n */\nexport type PlaywrightConfig = DeepReadonly<PlaywrightTestConfig>;\n\n// Empty readonly config for default parameters\nconst EMPTY_CONFIG = {} as const satisfies PlaywrightConfig;\n\n/**\n * Service configuration for a test environment.\n */\nexport interface TestEnvironmentServices {\n /** Whether to use real backend services instead of mocks. */\n useRealServices: boolean;\n /** Whether to mock external (third-party) API calls. */\n mockExternalAPIs: boolean;\n}\n\n/**\n * Configuration for a single test environment (e.g. development, staging, production).\n *\n * Consumers define their own environment map and pass it to helpers like\n * {@link createCrossAppConfig} in `cross-app.ts`.\n */\nexport interface TestEnvironmentConfig {\n /** Map of application names to their base URLs. */\n baseUrls: Record<string, string>;\n /** Service-layer settings for this environment. */\n services: TestEnvironmentServices;\n /** When true, only smoke tests should run (e.g. in production). */\n smokeTestsOnly?: boolean;\n}\n\n/**\n * Base configuration options that apply to all acceptance test environments\n */\nexport const baseConfig: PlaywrightTestConfig = {\n // Test discovery and execution\n testDir: \"./tests/acceptance\",\n testMatch: \"**/*.{test,spec}.{ts,js}\",\n\n // Global test settings\n fullyParallel: true,\n forbidOnly: Boolean(process.env.CI),\n retries: process.env.CI !== undefined ? 2 : 0,\n workers: process.env.CI !== undefined ? 4 : undefined,\n\n // Test execution timeouts\n timeout: 30 * 1000, // 30 seconds for individual tests\n expect: {\n timeout: 5 * 1000, // 5 seconds for assertions\n },\n\n // Reporter configuration for different environments\n reporter: [\n [\"html\", { outputFolder: \"./generated/playwright/reports\" }],\n [\"json\", { outputFile: \"./generated/playwright/results.json\" }],\n process.env.CI !== undefined ? [\"github\"] : [\"list\"],\n ],\n\n // Output folder for test results\n outputDir: \"./generated/playwright/test-results\",\n\n // Global test options\n use: {\n // Browser context settings\n viewport: { width: 1280, height: 720 },\n ignoreHTTPSErrors: true,\n headless: true, // Always headless by default (use --headed flag to override)\n\n // Action timeouts\n actionTimeout: 10 * 1000, // 10 seconds for actions\n navigationTimeout: 30 * 1000, // 30 seconds for navigation\n\n // Debugging and artifact collection - sensible defaults\n trace: \"on-first-retry\",\n video: \"retain-on-failure\",\n screenshot: \"only-on-failure\",\n\n // No authentication state by default (apps can override)\n storageState: undefined,\n },\n\n // Browser and device matrix\n // Local dev: Chromium only for speed\n // CI: Full browser matrix for compatibility testing\n projects:\n process.env.CI !== undefined\n ? [\n // Desktop browsers\n {\n name: \"chromium\",\n use: { ...devices[\"Desktop Chrome\"] },\n },\n {\n name: \"firefox\",\n use: { ...devices[\"Desktop Firefox\"] },\n },\n {\n name: \"webkit\",\n use: { ...devices[\"Desktop Safari\"] },\n },\n\n // Mobile devices\n {\n name: \"Mobile Chrome\",\n use: { ...devices[\"Pixel 5\"] },\n },\n {\n name: \"Mobile Safari\",\n use: { ...devices[\"iPhone 12\"] },\n },\n\n // Tablet devices\n {\n name: \"iPad\",\n use: { ...devices[\"iPad Pro\"] },\n },\n ]\n : [\n // Local development: Chromium only for fast iteration\n {\n name: \"chromium\",\n use: { ...devices[\"Desktop Chrome\"] },\n },\n ],\n\n // Development server integration - common defaults for web apps\n webServer:\n process.env.CI !== undefined\n ? undefined\n : {\n command: \"pnpm dev\",\n reuseExistingServer: true,\n timeout: 120 * 1000, // 2 minutes to start\n },\n};\n\n/**\n * Creates a merged configuration from the base and any custom options\n * @param customConfig - Additional configuration options\n * @returns A merged Playwright configuration\n */\nexport function createPlaywrightConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return {\n ...baseConfig,\n ...customConfig,\n use: {\n ...baseConfig.use,\n ...customConfig.use,\n },\n projects: customConfig.projects ?? baseConfig.projects,\n };\n}\n\n/**\n * Creates a configuration optimized for CI/CD environments\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration optimized for CI/CD\n */\nexport function createCIConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return createPlaywrightConfig({\n ...customConfig,\n fullyParallel: true,\n retries: 3,\n workers: 4,\n use: {\n ...customConfig.use,\n trace: \"retain-on-failure\",\n video: \"retain-on-failure\",\n screenshot: \"only-on-failure\",\n },\n });\n}\n\n// Re-export for convenience\nexport { createCrossAppConfig } from \"./cross-app.js\";\nexport { createBaseConfig } from \"./base.js\";\n\nexport default createPlaywrightConfig;\n","/**\n * Base browser configuration for Playwright testing\n * @module @reasonabletech/config-playwright/base\n */\n\nimport { type PlaywrightTestConfig, devices } from \"@playwright/test\";\nimport { baseConfig, type PlaywrightConfig } from \"./index.js\";\n\n// Empty readonly config for default parameters\nconst EMPTY_CONFIG = {} as const satisfies PlaywrightConfig;\n\n/**\n * Desktop-only browser configuration\n */\nexport const desktopConfig: PlaywrightTestConfig = {\n projects: [\n {\n name: \"chromium\",\n use: { ...devices[\"Desktop Chrome\"] },\n },\n {\n name: \"firefox\",\n use: { ...devices[\"Desktop Firefox\"] },\n },\n {\n name: \"webkit\",\n use: { ...devices[\"Desktop Safari\"] },\n },\n ],\n};\n\n/**\n * Mobile-only browser configuration\n */\nexport const mobileConfig: PlaywrightTestConfig = {\n projects: [\n {\n name: \"Mobile Chrome\",\n use: { ...devices[\"Pixel 5\"] },\n },\n {\n name: \"Mobile Safari\",\n use: { ...devices[\"iPhone 12\"] },\n },\n ],\n};\n\n/**\n * Chromium-only configuration for faster development testing\n */\nexport const chromiumOnlyConfig: PlaywrightTestConfig = {\n projects: [\n {\n name: \"chromium\",\n use: { ...devices[\"Desktop Chrome\"] },\n },\n ],\n};\n\n/**\n * Creates a base Playwright configuration for single-app testing\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration for standard single-app testing\n */\nexport function createBaseConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return {\n ...baseConfig,\n ...customConfig,\n use: {\n ...baseConfig.use,\n ...customConfig.use,\n // Single-app specific settings\n storageState: undefined, // No cross-app auth state by default\n },\n projects: customConfig.projects ?? baseConfig.projects,\n };\n}\n\n/**\n * Creates a desktop-only configuration for faster testing cycles\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration for desktop browsers only\n */\nexport function createDesktopConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return createBaseConfig({\n ...customConfig,\n projects: desktopConfig.projects,\n });\n}\n\n/**\n * Creates a mobile-only configuration for mobile-specific testing\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration for mobile browsers only\n */\nexport function createMobileConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return createBaseConfig({\n ...customConfig,\n projects: mobileConfig.projects,\n });\n}\n\n/**\n * Creates a Chromium-only configuration for development\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration for Chromium browser only\n */\nexport function createChromiumConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return createBaseConfig({\n ...customConfig,\n projects: chromiumOnlyConfig.projects,\n workers: 1, // Single worker for development\n });\n}\n\nexport default createBaseConfig;\n"]}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
var baseConfig = {
|
|
5
|
+
// Test discovery and execution
|
|
6
|
+
testDir: "./tests/acceptance",
|
|
7
|
+
testMatch: "**/*.{test,spec}.{ts,js}",
|
|
8
|
+
// Global test settings
|
|
9
|
+
fullyParallel: true,
|
|
10
|
+
forbidOnly: Boolean(process.env.CI),
|
|
11
|
+
retries: process.env.CI !== void 0 ? 2 : 0,
|
|
12
|
+
workers: process.env.CI !== void 0 ? 4 : void 0,
|
|
13
|
+
// Test execution timeouts
|
|
14
|
+
timeout: 30 * 1e3,
|
|
15
|
+
// 30 seconds for individual tests
|
|
16
|
+
expect: {
|
|
17
|
+
timeout: 5 * 1e3
|
|
18
|
+
// 5 seconds for assertions
|
|
19
|
+
},
|
|
20
|
+
// Reporter configuration for different environments
|
|
21
|
+
reporter: [
|
|
22
|
+
["html", { outputFolder: "./generated/playwright/reports" }],
|
|
23
|
+
["json", { outputFile: "./generated/playwright/results.json" }],
|
|
24
|
+
process.env.CI !== void 0 ? ["github"] : ["list"]
|
|
25
|
+
],
|
|
26
|
+
// Output folder for test results
|
|
27
|
+
outputDir: "./generated/playwright/test-results",
|
|
28
|
+
// Global test options
|
|
29
|
+
use: {
|
|
30
|
+
// Browser context settings
|
|
31
|
+
viewport: { width: 1280, height: 720 },
|
|
32
|
+
ignoreHTTPSErrors: true,
|
|
33
|
+
headless: true,
|
|
34
|
+
// Always headless by default (use --headed flag to override)
|
|
35
|
+
// Action timeouts
|
|
36
|
+
actionTimeout: 10 * 1e3,
|
|
37
|
+
// 10 seconds for actions
|
|
38
|
+
navigationTimeout: 30 * 1e3,
|
|
39
|
+
// 30 seconds for navigation
|
|
40
|
+
// Debugging and artifact collection - sensible defaults
|
|
41
|
+
trace: "on-first-retry",
|
|
42
|
+
video: "retain-on-failure",
|
|
43
|
+
screenshot: "only-on-failure",
|
|
44
|
+
// No authentication state by default (apps can override)
|
|
45
|
+
storageState: void 0
|
|
46
|
+
},
|
|
47
|
+
// Browser and device matrix
|
|
48
|
+
// Local dev: Chromium only for speed
|
|
49
|
+
// CI: Full browser matrix for compatibility testing
|
|
50
|
+
projects: process.env.CI !== void 0 ? [
|
|
51
|
+
// Desktop browsers
|
|
52
|
+
{
|
|
53
|
+
name: "chromium",
|
|
54
|
+
use: { ...devices["Desktop Chrome"] }
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "firefox",
|
|
58
|
+
use: { ...devices["Desktop Firefox"] }
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "webkit",
|
|
62
|
+
use: { ...devices["Desktop Safari"] }
|
|
63
|
+
},
|
|
64
|
+
// Mobile devices
|
|
65
|
+
{
|
|
66
|
+
name: "Mobile Chrome",
|
|
67
|
+
use: { ...devices["Pixel 5"] }
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "Mobile Safari",
|
|
71
|
+
use: { ...devices["iPhone 12"] }
|
|
72
|
+
},
|
|
73
|
+
// Tablet devices
|
|
74
|
+
{
|
|
75
|
+
name: "iPad",
|
|
76
|
+
use: { ...devices["iPad Pro"] }
|
|
77
|
+
}
|
|
78
|
+
] : [
|
|
79
|
+
// Local development: Chromium only for fast iteration
|
|
80
|
+
{
|
|
81
|
+
name: "chromium",
|
|
82
|
+
use: { ...devices["Desktop Chrome"] }
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
// Development server integration - common defaults for web apps
|
|
86
|
+
webServer: process.env.CI !== void 0 ? void 0 : {
|
|
87
|
+
command: "pnpm dev",
|
|
88
|
+
reuseExistingServer: true,
|
|
89
|
+
timeout: 120 * 1e3
|
|
90
|
+
// 2 minutes to start
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// src/cross-app.ts
|
|
95
|
+
var EMPTY_CONFIG = {};
|
|
96
|
+
var crossAppConfig = {
|
|
97
|
+
testDir: "./tests/acceptance/cross-app",
|
|
98
|
+
testMatch: "**/*.{test,spec}.{ts,js}",
|
|
99
|
+
use: {
|
|
100
|
+
// Extended timeout for cross-app navigation
|
|
101
|
+
actionTimeout: 1e4,
|
|
102
|
+
navigationTimeout: 15e3,
|
|
103
|
+
// Cross-domain configuration
|
|
104
|
+
extraHTTPHeaders: {
|
|
105
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
106
|
+
},
|
|
107
|
+
// Authentication state for cross-app flows
|
|
108
|
+
storageState: "tests/fixtures/auth/cross-app-authenticated.json",
|
|
109
|
+
// Enable video for complex cross-app debugging
|
|
110
|
+
video: "retain-on-failure",
|
|
111
|
+
trace: "retain-on-failure"
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
var accessibilityConfig = {
|
|
115
|
+
testDir: "./tests/acceptance/accessibility",
|
|
116
|
+
testMatch: "**/*.{test,spec}.{ts,js}",
|
|
117
|
+
use: {
|
|
118
|
+
// Slower execution for accessibility checks
|
|
119
|
+
actionTimeout: 15e3,
|
|
120
|
+
navigationTimeout: 2e4
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var performanceConfig = {
|
|
124
|
+
testDir: "./tests/acceptance/performance",
|
|
125
|
+
testMatch: "**/*.{test,spec}.{ts,js}",
|
|
126
|
+
// Sequential execution for accurate performance measurements
|
|
127
|
+
fullyParallel: false,
|
|
128
|
+
workers: 1,
|
|
129
|
+
use: {
|
|
130
|
+
// Extended timeouts for performance measurements
|
|
131
|
+
actionTimeout: 3e4,
|
|
132
|
+
navigationTimeout: 45e3,
|
|
133
|
+
// Minimal interference for accurate measurements
|
|
134
|
+
video: "off",
|
|
135
|
+
screenshot: "off",
|
|
136
|
+
trace: "off"
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
function createAuthWorkflowConfig(options) {
|
|
140
|
+
return {
|
|
141
|
+
cookieConfig: {
|
|
142
|
+
domain: options.domain,
|
|
143
|
+
secure: true,
|
|
144
|
+
httpOnly: true,
|
|
145
|
+
sameSite: "lax"
|
|
146
|
+
},
|
|
147
|
+
expectedPersistence: options.expectedPersistence
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function createCrossAppConfig(options) {
|
|
151
|
+
const { environments, customConfig = EMPTY_CONFIG } = options;
|
|
152
|
+
const environment = process.env.TEST_ENV ?? "development";
|
|
153
|
+
const envConfig = environments[environment];
|
|
154
|
+
if (envConfig === void 0) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Unknown test environment "${environment}". Available environments: ${Object.keys(environments).join(", ")}`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
const defaultBaseUrl = Object.values(envConfig.baseUrls).at(0);
|
|
160
|
+
if (defaultBaseUrl === void 0) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`Environment "${environment}" must define at least one base URL`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
...baseConfig,
|
|
167
|
+
...crossAppConfig,
|
|
168
|
+
...customConfig,
|
|
169
|
+
use: {
|
|
170
|
+
...baseConfig.use,
|
|
171
|
+
...crossAppConfig.use,
|
|
172
|
+
...customConfig.use,
|
|
173
|
+
// Set base URL to the first entry in baseUrls (typically the landing page)
|
|
174
|
+
baseURL: defaultBaseUrl
|
|
175
|
+
},
|
|
176
|
+
projects: [
|
|
177
|
+
// Desktop browsers for cross-app flows
|
|
178
|
+
{
|
|
179
|
+
name: "cross-app-chromium",
|
|
180
|
+
testDir: "./tests/acceptance/cross-app",
|
|
181
|
+
use: {
|
|
182
|
+
...baseConfig.projects?.[0]?.use,
|
|
183
|
+
// Cross-app specific browser settings
|
|
184
|
+
viewport: { width: 1920, height: 1080 }
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: "cross-app-firefox",
|
|
189
|
+
testDir: "./tests/acceptance/cross-app",
|
|
190
|
+
use: {
|
|
191
|
+
...baseConfig.projects?.[1]?.use,
|
|
192
|
+
viewport: { width: 1920, height: 1080 }
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "cross-app-webkit",
|
|
197
|
+
testDir: "./tests/acceptance/cross-app",
|
|
198
|
+
use: {
|
|
199
|
+
...baseConfig.projects?.[2]?.use,
|
|
200
|
+
viewport: { width: 1920, height: 1080 }
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function createAccessibilityConfig(customConfig = EMPTY_CONFIG) {
|
|
207
|
+
return {
|
|
208
|
+
...baseConfig,
|
|
209
|
+
...accessibilityConfig,
|
|
210
|
+
...customConfig,
|
|
211
|
+
use: {
|
|
212
|
+
...baseConfig.use,
|
|
213
|
+
...accessibilityConfig.use,
|
|
214
|
+
...customConfig.use
|
|
215
|
+
},
|
|
216
|
+
projects: [
|
|
217
|
+
{
|
|
218
|
+
name: "accessibility-chromium",
|
|
219
|
+
testDir: "./tests/acceptance/accessibility",
|
|
220
|
+
use: {
|
|
221
|
+
...baseConfig.projects?.[0]?.use,
|
|
222
|
+
viewport: { width: 1280, height: 720 }
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function createPerformanceConfig(customConfig = EMPTY_CONFIG) {
|
|
229
|
+
return {
|
|
230
|
+
...baseConfig,
|
|
231
|
+
...performanceConfig,
|
|
232
|
+
...customConfig,
|
|
233
|
+
use: {
|
|
234
|
+
...baseConfig.use,
|
|
235
|
+
...performanceConfig.use,
|
|
236
|
+
...customConfig.use
|
|
237
|
+
},
|
|
238
|
+
projects: [
|
|
239
|
+
{
|
|
240
|
+
name: "performance-chromium",
|
|
241
|
+
testDir: "./tests/acceptance/performance",
|
|
242
|
+
use: {
|
|
243
|
+
...baseConfig.projects?.[0]?.use,
|
|
244
|
+
viewport: { width: 1920, height: 1080 }
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
]
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function createAuthTestConfig(options) {
|
|
251
|
+
const { environments, customConfig = EMPTY_CONFIG } = options;
|
|
252
|
+
return createCrossAppConfig({
|
|
253
|
+
environments,
|
|
254
|
+
customConfig: {
|
|
255
|
+
...customConfig,
|
|
256
|
+
testDir: "./tests/acceptance/auth",
|
|
257
|
+
use: {
|
|
258
|
+
...customConfig.use,
|
|
259
|
+
// No pre-authenticated state for auth tests
|
|
260
|
+
storageState: void 0
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
var cross_app_default = createCrossAppConfig;
|
|
266
|
+
|
|
267
|
+
export { accessibilityConfig, createAccessibilityConfig, createAuthTestConfig, createAuthWorkflowConfig, createCrossAppConfig, createPerformanceConfig, crossAppConfig, cross_app_default as default, performanceConfig };
|
|
268
|
+
//# sourceMappingURL=cross-app.js.map
|
|
269
|
+
//# sourceMappingURL=cross-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/cross-app.ts"],"names":[],"mappings":"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","file":"cross-app.js","sourcesContent":["/**\n * Base Playwright configuration for all applications\n * @module @reasonabletech/config-playwright\n */\n\nimport { type PlaywrightTestConfig, devices } from \"@playwright/test\";\n\n/**\n * Recursively makes all properties of `T` readonly.\n *\n * Useful for configuration objects defined with `as const`, ensuring callers\n * don't accidentally mutate shared config.\n */\nexport type DeepReadonly<T> = {\n readonly [P in keyof T]: T[P] extends ReadonlyArray<infer U>\n ? ReadonlyArray<DeepReadonly<U>>\n : T[P] extends Array<infer U>\n ? ReadonlyArray<DeepReadonly<U>>\n : T[P] extends object\n ? DeepReadonly<T[P]>\n : T[P];\n};\n\n/**\n * Immutable Playwright config type accepted by config helpers.\n */\nexport type PlaywrightConfig = DeepReadonly<PlaywrightTestConfig>;\n\n// Empty readonly config for default parameters\nconst EMPTY_CONFIG = {} as const satisfies PlaywrightConfig;\n\n/**\n * Service configuration for a test environment.\n */\nexport interface TestEnvironmentServices {\n /** Whether to use real backend services instead of mocks. */\n useRealServices: boolean;\n /** Whether to mock external (third-party) API calls. */\n mockExternalAPIs: boolean;\n}\n\n/**\n * Configuration for a single test environment (e.g. development, staging, production).\n *\n * Consumers define their own environment map and pass it to helpers like\n * {@link createCrossAppConfig} in `cross-app.ts`.\n */\nexport interface TestEnvironmentConfig {\n /** Map of application names to their base URLs. */\n baseUrls: Record<string, string>;\n /** Service-layer settings for this environment. */\n services: TestEnvironmentServices;\n /** When true, only smoke tests should run (e.g. in production). */\n smokeTestsOnly?: boolean;\n}\n\n/**\n * Base configuration options that apply to all acceptance test environments\n */\nexport const baseConfig: PlaywrightTestConfig = {\n // Test discovery and execution\n testDir: \"./tests/acceptance\",\n testMatch: \"**/*.{test,spec}.{ts,js}\",\n\n // Global test settings\n fullyParallel: true,\n forbidOnly: Boolean(process.env.CI),\n retries: process.env.CI !== undefined ? 2 : 0,\n workers: process.env.CI !== undefined ? 4 : undefined,\n\n // Test execution timeouts\n timeout: 30 * 1000, // 30 seconds for individual tests\n expect: {\n timeout: 5 * 1000, // 5 seconds for assertions\n },\n\n // Reporter configuration for different environments\n reporter: [\n [\"html\", { outputFolder: \"./generated/playwright/reports\" }],\n [\"json\", { outputFile: \"./generated/playwright/results.json\" }],\n process.env.CI !== undefined ? [\"github\"] : [\"list\"],\n ],\n\n // Output folder for test results\n outputDir: \"./generated/playwright/test-results\",\n\n // Global test options\n use: {\n // Browser context settings\n viewport: { width: 1280, height: 720 },\n ignoreHTTPSErrors: true,\n headless: true, // Always headless by default (use --headed flag to override)\n\n // Action timeouts\n actionTimeout: 10 * 1000, // 10 seconds for actions\n navigationTimeout: 30 * 1000, // 30 seconds for navigation\n\n // Debugging and artifact collection - sensible defaults\n trace: \"on-first-retry\",\n video: \"retain-on-failure\",\n screenshot: \"only-on-failure\",\n\n // No authentication state by default (apps can override)\n storageState: undefined,\n },\n\n // Browser and device matrix\n // Local dev: Chromium only for speed\n // CI: Full browser matrix for compatibility testing\n projects:\n process.env.CI !== undefined\n ? [\n // Desktop browsers\n {\n name: \"chromium\",\n use: { ...devices[\"Desktop Chrome\"] },\n },\n {\n name: \"firefox\",\n use: { ...devices[\"Desktop Firefox\"] },\n },\n {\n name: \"webkit\",\n use: { ...devices[\"Desktop Safari\"] },\n },\n\n // Mobile devices\n {\n name: \"Mobile Chrome\",\n use: { ...devices[\"Pixel 5\"] },\n },\n {\n name: \"Mobile Safari\",\n use: { ...devices[\"iPhone 12\"] },\n },\n\n // Tablet devices\n {\n name: \"iPad\",\n use: { ...devices[\"iPad Pro\"] },\n },\n ]\n : [\n // Local development: Chromium only for fast iteration\n {\n name: \"chromium\",\n use: { ...devices[\"Desktop Chrome\"] },\n },\n ],\n\n // Development server integration - common defaults for web apps\n webServer:\n process.env.CI !== undefined\n ? undefined\n : {\n command: \"pnpm dev\",\n reuseExistingServer: true,\n timeout: 120 * 1000, // 2 minutes to start\n },\n};\n\n/**\n * Creates a merged configuration from the base and any custom options\n * @param customConfig - Additional configuration options\n * @returns A merged Playwright configuration\n */\nexport function createPlaywrightConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return {\n ...baseConfig,\n ...customConfig,\n use: {\n ...baseConfig.use,\n ...customConfig.use,\n },\n projects: customConfig.projects ?? baseConfig.projects,\n };\n}\n\n/**\n * Creates a configuration optimized for CI/CD environments\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration optimized for CI/CD\n */\nexport function createCIConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return createPlaywrightConfig({\n ...customConfig,\n fullyParallel: true,\n retries: 3,\n workers: 4,\n use: {\n ...customConfig.use,\n trace: \"retain-on-failure\",\n video: \"retain-on-failure\",\n screenshot: \"only-on-failure\",\n },\n });\n}\n\n// Re-export for convenience\nexport { createCrossAppConfig } from \"./cross-app.js\";\nexport { createBaseConfig } from \"./base.js\";\n\nexport default createPlaywrightConfig;\n","/**\n * Cross-app Playwright configuration for multi-frontend testing\n * @module @reasonabletech/config-playwright/cross-app\n */\n\nimport { type PlaywrightTestConfig } from \"@playwright/test\";\nimport {\n baseConfig,\n type PlaywrightConfig,\n type TestEnvironmentConfig,\n} from \"./index.js\";\n\n// Empty readonly config for default parameters\nconst EMPTY_CONFIG = {} as const satisfies PlaywrightConfig;\n\n/**\n * Cross-app specific configuration options\n */\nexport const crossAppConfig: PlaywrightTestConfig = {\n testDir: \"./tests/acceptance/cross-app\",\n testMatch: \"**/*.{test,spec}.{ts,js}\",\n\n use: {\n // Extended timeout for cross-app navigation\n actionTimeout: 10000,\n navigationTimeout: 15000,\n\n // Cross-domain configuration\n extraHTTPHeaders: {\n Accept: \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n },\n\n // Authentication state for cross-app flows\n storageState: \"tests/fixtures/auth/cross-app-authenticated.json\",\n\n // Enable video for complex cross-app debugging\n video: \"retain-on-failure\",\n trace: \"retain-on-failure\",\n },\n};\n\n/**\n * Accessibility testing configuration with axe-core\n */\nexport const accessibilityConfig: PlaywrightTestConfig = {\n testDir: \"./tests/acceptance/accessibility\",\n testMatch: \"**/*.{test,spec}.{ts,js}\",\n\n use: {\n // Slower execution for accessibility checks\n actionTimeout: 15000,\n navigationTimeout: 20000,\n },\n};\n\n/**\n * Performance testing configuration for Lighthouse integration\n */\nexport const performanceConfig: PlaywrightTestConfig = {\n testDir: \"./tests/acceptance/performance\",\n testMatch: \"**/*.{test,spec}.{ts,js}\",\n\n // Sequential execution for accurate performance measurements\n fullyParallel: false,\n workers: 1,\n\n use: {\n // Extended timeouts for performance measurements\n actionTimeout: 30000,\n navigationTimeout: 45000,\n\n // Minimal interference for accurate measurements\n video: \"off\",\n screenshot: \"off\",\n trace: \"off\",\n },\n};\n\n/**\n * Options for creating a cross-domain authentication workflow configuration.\n */\nexport interface AuthWorkflowOptions {\n /** The cookie domain (e.g. \".example.com\"). */\n domain: string;\n /**\n * List of subdomains where authentication cookies should persist\n * (e.g. [\"accounts.example.com\", \"app.example.com\"]).\n */\n expectedPersistence: readonly string[];\n}\n\n/**\n * Configuration shape returned by {@link createAuthWorkflowConfig}.\n */\nexport interface AuthWorkflowConfig {\n /**\n * Cookie settings used for cross-domain authentication.\n */\n readonly cookieConfig: {\n readonly domain: string;\n readonly secure: true;\n readonly httpOnly: true;\n readonly sameSite: \"lax\";\n };\n /**\n * Subdomains where authentication should remain valid.\n */\n readonly expectedPersistence: readonly string[];\n}\n\n/**\n * Creates a cross-domain authentication configuration for the given domain.\n * @param options - Domain and persistence settings\n * @returns An authentication workflow config object\n */\nexport function createAuthWorkflowConfig(\n options: AuthWorkflowOptions,\n): AuthWorkflowConfig {\n return {\n cookieConfig: {\n domain: options.domain,\n secure: true,\n httpOnly: true,\n sameSite: \"lax\" as const,\n },\n expectedPersistence: options.expectedPersistence,\n } as const;\n}\n\n/**\n * Options for creating a cross-app Playwright configuration.\n */\nexport interface CrossAppConfigOptions {\n /**\n * Map of environment names to their configuration.\n * The key used is determined by the `TEST_ENV` environment variable,\n * falling back to `\"development\"`.\n */\n environments: Readonly<Record<string, TestEnvironmentConfig | undefined>>;\n /** Additional Playwright configuration overrides. */\n customConfig?: PlaywrightConfig;\n}\n\n/**\n * Creates a Playwright configuration for cross-app workflows.\n *\n * Consumers must supply their own environment map so that base URLs are not\n * hardcoded in this shared package.\n * @param options - Environments map and optional custom config overrides\n * @returns A Playwright configuration optimized for cross-app testing\n */\nexport function createCrossAppConfig(\n options: CrossAppConfigOptions,\n): PlaywrightTestConfig {\n const { environments, customConfig = EMPTY_CONFIG } = options;\n\n const environment = process.env.TEST_ENV ?? \"development\";\n const envConfig = environments[environment];\n\n if (envConfig === undefined) {\n throw new Error(\n `Unknown test environment \"${environment}\". Available environments: ${Object.keys(environments).join(\", \")}`,\n );\n }\n\n const defaultBaseUrl = Object.values(envConfig.baseUrls).at(0);\n\n if (defaultBaseUrl === undefined) {\n throw new Error(\n `Environment \"${environment}\" must define at least one base URL`,\n );\n }\n\n return {\n ...baseConfig,\n ...crossAppConfig,\n ...customConfig,\n use: {\n ...baseConfig.use,\n ...crossAppConfig.use,\n ...(customConfig as PlaywrightTestConfig).use,\n // Set base URL to the first entry in baseUrls (typically the landing page)\n baseURL: defaultBaseUrl,\n },\n projects: [\n // Desktop browsers for cross-app flows\n {\n name: \"cross-app-chromium\",\n testDir: \"./tests/acceptance/cross-app\",\n use: {\n ...baseConfig.projects?.[0]?.use,\n // Cross-app specific browser settings\n viewport: { width: 1920, height: 1080 },\n },\n },\n {\n name: \"cross-app-firefox\",\n testDir: \"./tests/acceptance/cross-app\",\n use: {\n ...baseConfig.projects?.[1]?.use,\n viewport: { width: 1920, height: 1080 },\n },\n },\n {\n name: \"cross-app-webkit\",\n testDir: \"./tests/acceptance/cross-app\",\n use: {\n ...baseConfig.projects?.[2]?.use,\n viewport: { width: 1920, height: 1080 },\n },\n },\n ],\n };\n}\n\n/**\n * Creates a configuration for accessibility testing with axe-core\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration with accessibility testing setup\n */\nexport function createAccessibilityConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return {\n ...baseConfig,\n ...accessibilityConfig,\n ...customConfig,\n use: {\n ...baseConfig.use,\n ...accessibilityConfig.use,\n ...(customConfig as PlaywrightTestConfig).use,\n },\n projects: [\n {\n name: \"accessibility-chromium\",\n testDir: \"./tests/acceptance/accessibility\",\n use: {\n ...baseConfig.projects?.[0]?.use,\n viewport: { width: 1280, height: 720 },\n },\n },\n ],\n };\n}\n\n/**\n * Creates a configuration for performance testing with Lighthouse\n * @param customConfig - Additional configuration options\n * @returns A Playwright configuration with performance testing setup\n */\nexport function createPerformanceConfig(\n customConfig: PlaywrightConfig = EMPTY_CONFIG,\n): PlaywrightTestConfig {\n return {\n ...baseConfig,\n ...performanceConfig,\n ...customConfig,\n use: {\n ...baseConfig.use,\n ...performanceConfig.use,\n ...(customConfig as PlaywrightTestConfig).use,\n },\n projects: [\n {\n name: \"performance-chromium\",\n testDir: \"./tests/acceptance/performance\",\n use: {\n ...baseConfig.projects?.[0]?.use,\n viewport: { width: 1920, height: 1080 },\n },\n },\n ],\n };\n}\n\n/**\n * Creates a configuration optimized for authentication workflow testing\n * @param options - Cross-app config options (environments map and optional custom config)\n * @returns A Playwright configuration for auth workflow testing\n */\nexport function createAuthTestConfig(\n options: CrossAppConfigOptions,\n): PlaywrightTestConfig {\n const { environments, customConfig = EMPTY_CONFIG } = options;\n return createCrossAppConfig({\n environments,\n customConfig: {\n ...customConfig,\n testDir: \"./tests/acceptance/auth\",\n use: {\n ...(customConfig as PlaywrightTestConfig).use,\n // No pre-authenticated state for auth tests\n storageState: undefined,\n },\n },\n });\n}\n\nexport default createCrossAppConfig;\n"]}
|