You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Shared RHDH deployment across all tests in a worker. Wrap expensive setup in `test.runOnce` to avoid re-deploying when workers restart after test failures.
19
+
Shared RHDH deployment across all tests in a worker. `deploy()` automatically skips if the deployment already succeeded, even after worker restarts.
Executes `fn` exactly once per test run, even across worker restarts. Returns `true` if executed, `false` if skipped. Useful for expensive or persistent operations (deployments, database seeding, service provisioning) that should not repeat after a worker restart.
89
+
Executes `fn` exactly once per test run, even across worker restarts. Returns `true` if executed, `false` if skipped.
90
+
91
+
::: tip
92
+
`rhdh.deploy()` already uses `runOnce` internally, so you don't need to wrap simple deployments. Use `test.runOnce` when you have **additional expensive operations** (external services, scripts, data seeding) alongside `deploy()`.
93
+
:::
92
94
93
95
| Parameter | Type | Description |
94
96
|-----------|------|-------------|
95
97
|`key`|`string`| Unique identifier for this operation |
96
98
|`fn`|`() => Promise<void> \| void`| Function to execute once |
97
99
98
100
```typescript
101
+
// Wrap pre-deploy setup that shouldn't repeat
99
102
test.beforeAll(async ({ rhdh }) => {
100
-
awaittest.runOnce("my-deploy", async () => {
103
+
awaittest.runOnce("full-setup", async () => {
104
+
await$`bash deploy-external-service.sh`;
101
105
awaitrhdh.configure({ auth: "keycloak" });
102
-
awaitrhdh.deploy();
106
+
awaitrhdh.deploy();// safe to nest, has its own internal protection
103
107
});
104
108
});
105
109
```
106
110
107
-
See [Playwright Fixtures — `test.runOnce`](/guide/core-concepts/playwright-fixtures#test-runonce-—-execute-a-function-once-per-test-run) for detailed usage and examples.
111
+
See [Deployment Protection](/guide/core-concepts/playwright-fixtures#deployment-protection-built-in) and [`test.runOnce`](/guide/core-concepts/playwright-fixtures#test-runonce-—-run-any-expensive-operation-once) for details.
Copy file name to clipboardExpand all lines: docs/changelog.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,8 @@ All notable changes to this project will be documented in this file.
5
5
## [1.1.14] - Current
6
6
7
7
### Added
8
-
-**`test.runOnce(key, fn)`**: Execute a function exactly once per test run, even across worker restarts. Prevents re-running expensive operations (deployments, service provisioning, data seeding) when Playwright creates new workers after test failures.
8
+
-**`deploy()` built-in protection**: `rhdh.deploy()` now automatically skips if the deployment already succeeded in the current test run. No code changes needed — existing `beforeAll` patterns work as before, but deployments are no longer repeated when Playwright restarts workers after test failures.
9
+
-**`test.runOnce(key, fn)`**: Execute any function exactly once per test run, even across worker restarts. Use for expensive pre-deploy operations (external services, setup scripts, data seeding) that `deploy()` alone doesn't cover. Safe to nest with `deploy()`'s built-in protection.
9
10
-**Teardown reporter**: Built-in Playwright reporter that automatically deletes Kubernetes namespaces after all tests complete. Active only in CI (`process.env.CI`).
10
11
-**`registerTeardownNamespace(projectName, namespace)`**: Register custom namespaces for automatic cleanup. Import from `@red-hat-developer-hub/e2e-test-utils/teardown`.
## `test.runOnce` — Execute a Function Once Per Test Run
157
+
## Deployment Protection (Built-in)
158
158
159
-
Playwright's `beforeAll` runs once **per worker**, not once per test run. When a test fails, Playwright kills the worker and creates a new one for remaining tests — causing `beforeAll` to run again. For operations that are expensive or produce persistent side effects, this leads to unnecessary re-execution.
159
+
`rhdh.deploy()` is automatically protected against redundant re-execution. When a test fails and Playwright restarts the worker, `deploy()` detects that the deployment already succeeded and skips — no re-deployment, no wasted time.
160
160
161
-
`test.runOnce` ensures a function executes **exactly once per test run**, even across worker restarts:
161
+
This works out of the box. A simple `beforeAll` is all you need:
awaitrhdh.deploy(); // runs once, skips on worker restart
167
+
});
168
+
```
169
+
170
+
::: tip Why is this needed?
171
+
Playwright's `beforeAll` runs once **per worker**, not once per test run. When a test fails, Playwright kills the worker and creates a new one for remaining tests — causing `beforeAll` to run again. Without protection, this would re-deploy RHDH from scratch every time a test fails.
172
+
:::
173
+
174
+
## `test.runOnce` — Run Any Expensive Operation Once
175
+
176
+
While `rhdh.deploy()` has built-in protection, you may have **other expensive operations** in your `beforeAll` that also shouldn't repeat on worker restart — deploying external services, seeding databases, running setup scripts, etc.
177
+
178
+
`test.runOnce` ensures any function executes **exactly once per test run**, even across worker restarts:
`test.runOnce` can be safely nested. Since `rhdh.deploy()` uses `runOnce` internally, wrapping it in an outer `test.runOnce` is harmless — the outer call skips everything on worker restart, and the inner one never runs:
265
+
266
+
```typescript
267
+
awaittest.runOnce("full-setup", async () => {
268
+
await$`bash setup.sh`; // protected by outer runOnce
269
+
awaitrhdh.deploy(); // has its own internal runOnce (harmless)
In CI environments (`CI` environment variable is set), namespaces are automatically deleted after all tests complete. This is handled by a built-in **teardown reporter** that:
216
276
217
277
1. Runs in the main Playwright process (survives worker restarts)
218
-
2. Waits for **all tests**in a project to finish
278
+
2. Waits for **all tests** to finish
219
279
3. Deletes the namespace matching the project name
220
280
221
281
### Default Behavior
@@ -238,11 +298,9 @@ If you deploy to a namespace that differs from the project name, register it for
awaitrhdh.deploy(); // automatically skips if already deployed
40
38
});
41
39
42
40
test("example", async ({ rhdh }) => {
@@ -112,6 +110,8 @@ test.setTimeout(900_000);
112
110
awaitrhdh.deploy({ timeout: null });
113
111
```
114
112
113
+
`deploy()` automatically skips if the deployment already succeeded in the current test run (e.g., after a worker restart due to test failure). This prevents expensive re-deployments.
0 commit comments