Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default defineConfig({
{ text: "Examples", link: "/examples/" },
{ text: "Overlay Testing", link: "/overlay/" },
{
text: "v2.2.0",
text: "v2.3.0",
items: [{ text: "Changelog", link: "/changelog" }],
},
],
Expand Down Expand Up @@ -277,6 +277,11 @@ export default defineConfig({
{ text: "Plugin Metadata", link: "/api/utils/plugin-metadata" },
],
},
{
text: "Secrets",
collapsed: true,
items: [{ text: "Secrets API", link: "/api/secrets" }],
},
{
text: "ESLint",
collapsed: true,
Expand Down
4 changes: 2 additions & 2 deletions docs/api/helpers/login-helper.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ async loginAsGithubUser(): Promise<void>
Login using GitHub OAuth.

**Required environment variables:**
- `VAULT_GH_USER_NAME`
- `VAULT_GH_USER_PASSWORD`
- `VAULT_GH_USER_ID`
- `VAULT_GH_USER_PASS`
- `VAULT_GH_2FA_SECRET`

### `signOut()`
Expand Down
5 changes: 5 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Complete API documentation for all exports from `@red-hat-developer-hub/e2e-test
| [`/helpers`](/api/helpers/ui-helper) | Helper classes |
| [`/pages`](/api/pages/catalog-page) | Page object classes |
| [`/eslint`](/api/eslint/create-eslint-config) | ESLint configuration |
| [`/secrets`](/api/secrets) | Bitwarden local secret execution |

## Categories

Expand Down Expand Up @@ -57,6 +58,10 @@ Complete API documentation for all exports from `@red-hat-developer-hub/e2e-test
- [envsubst](/api/utils/common) - Environment substitution
- [Plugin Metadata](/api/utils/plugin-metadata) - Plugin metadata injection

### Secrets

- [Secrets](/api/secrets) - Bitwarden-backed local execution APIs

### ESLint

- [createEslintConfig](/api/eslint/create-eslint-config) - ESLint factory
39 changes: 39 additions & 0 deletions docs/api/secrets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Secrets API

The `@red-hat-developer-hub/e2e-test-utils/secrets` export provides provider
access and child-process execution for local tests. It does not run from
Playwright global setup.

## Local Command

```bash
export BW_SESSION="<session-from-an-unlocked-bw-cli>"
rhdh-e2e-secrets exec \
--profile e2e-secrets.profile.json \
--workspace tech-radar \
-- yarn playwright test
```

The `bw` executable must be installed locally and available on `PATH`. The
tool does not log in, unlock, lock, or persist the Bitwarden session.

## Public Functions

```typescript
parseProfile(value: unknown): SecretProfile
expandProfile(profile: SecretProfile, workspaces?: readonly string[]): ExpandedSecretProfile
getCollectionMapping(collection: string): CollectionMapping
new BitwardenClient(options?: BitwardenClientOptions)
executeCommand(options: ExecuteCommandOptions): Promise<number>
materializeEnvironment(secrets, selectors, parent?): NodeJS.ProcessEnv
```

Profiles contain collection and prefix selectors but never secret values. Only
the approved readable collections are accepted; `rhdh-aws-credentials` is
explicitly denied. Environment destinations preserve legacy `VAULT_*` names
when the profile requests the `legacy-env` transformation.

## Related Pages

- [Global Setup](/guide/core-concepts/global-setup) - Provider-neutral Playwright setup
- [Package Exports](/guide/core-concepts/package-exports) - All package entry points
15 changes: 13 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@

All notable changes to this project will be documented in this file.

## [2.1.13] - Current
## [2.3.0] - Current

### Added

- **Bitwarden local secret execution**: Added the `./secrets` export and `rhdh-e2e-secrets exec` command for scoped, value-free profile loading into a child test process.

### Changed

- **Playwright global setup**: Secret-provider access is now external to global setup, and `.env` values fill only missing environment variables.
- **Overlay local workflows**: Secret-backed tests use the `test:secrets` command and preserve the existing `VAULT_*` payload variable names.

## [2.1.13]

### Added

Expand Down Expand Up @@ -68,6 +79,7 @@ All notable changes to this project will be documented in this file.
### Changed

- **Trace retention on all test runs**: Changed Playwright trace setting from `"retain-on-failure"` to `"on"` so traces are always retained, including on passed tests. This enables the fullsend e2e-triage agent to compare passing and failing traces for more accurate root cause analysis.

## [2.1.4]

### Changed
Expand Down Expand Up @@ -123,7 +135,6 @@ All notable changes to this project will be documented in this file.

- Starting CSV version for OSL operator was removed so latest stable will now be installed directly.


## [1.1.43]

### Fixed
Expand Down
8 changes: 4 additions & 4 deletions docs/examples/custom-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ import { test } from "@red-hat-developer-hub/e2e-test-utils/test";

test.beforeAll(async ({ rhdh }) => {
// Set secrets at runtime
process.env.GITHUB_TOKEN = await getSecretFromVault("github-token");
process.env.API_KEY = await getSecretFromVault("api-key");
process.env.GITHUB_TOKEN = await getSecret("github-token");
process.env.API_KEY = await getSecret("api-key");

await rhdh.configure({ auth: "keycloak" });
await rhdh.deploy();
});

async function getSecretFromVault(name: string): Promise<string> {
// Your vault integration
async function getSecret(name: string): Promise<string> {
// Use the secret provider approved for your environment.
return "secret-value";
}
```
Expand Down
6 changes: 3 additions & 3 deletions docs/guide/configuration/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ For GitHub integration:
| Variable | Description | Required |
| ------------------------- | ---------------------------- | ------------ |
| `VAULT_GITHUB_USER_TOKEN` | GitHub personal access token | For API/auth |
| `VAULT_GH_USER_NAME` | GitHub username | For login |
| `VAULT_GH_USER_PASSWORD` | GitHub password | For login |
| `VAULT_GH_USER_ID` | GitHub username | For login |
| `VAULT_GH_USER_PASS` | GitHub password | For login |
| `VAULT_GH_2FA_SECRET` | 2FA secret for OTP | For login |

## Custom Variables
Expand Down Expand Up @@ -145,7 +145,7 @@ GITHUB_TOKEN=ghp_xxxxx
MY_API_KEY=secret-value
```

The `.env` file is automatically loaded by global setup. Variables defined here take priority over Vault secrets.
The `.env` file is automatically loaded by global setup. Variables already supplied by the local secret wrapper are preserved; `.env` fills only missing values.

### CI/CD

Expand Down
29 changes: 9 additions & 20 deletions docs/guide/core-concepts/global-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,20 @@ The package includes a global setup function that runs once before all tests. Th

## What Global Setup Does

### 1. Vault Secret Loading (Local Development)
### 1. Provider-Neutral Setup

When `VAULT=1` or `VAULT=true` is set, global setup fetches secrets from HashiCorp Vault before anything else runs:

- Checks that the `vault` CLI is installed
- Logs in via OIDC if not already authenticated (opens browser)
- Fetches global secrets and per-workspace secrets
- Injects all `VAULT_*` keys into `process.env`
- Only logs key names, never secret values
Global setup does not access a secret provider. For local runs, invoke the
standalone `rhdh-e2e-secrets` command before Playwright so selected values are
available before configuration files, imports, and global setup execute:

```bash
# From workspace
VAULT=1 yarn test

# From repo root
VAULT=1 ./run-e2e.sh -w argocd
export BW_SESSION="<session-from-an-unlocked-bw-cli>"
rhdh-e2e-secrets exec --profile e2e-secrets.profile.json --workspace argocd -- yarn playwright test
```

If you don't have Vault access, request it in Slack: `#rhdh-e2e-tests`.

| Variable | Description | Default |
|----------|-------------|---------|
| `VAULT` | Enable Vault secret loading (`1` or `true`) | - |
| `VAULT_ADDR` | Vault server URL | `https://vault.ci.openshift.org` |
| `VAULT_BASE_PATH` | Base path in Vault | `selfservice/rhdh-plugin-export-overlays` |
The wrapper reads only the prefixes declared by the profile and passes the
selected values to the child process. Existing environment values take
priority over `.env` values loaded by global setup.

### 2. Binary Validation

Expand Down
16 changes: 16 additions & 0 deletions docs/guide/core-concepts/package-exports.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The package provides multiple entry points for different use cases. Each export
| `@red-hat-developer-hub/e2e-test-utils/pages` | Page object classes for common RHDH pages |
| `@red-hat-developer-hub/e2e-test-utils/eslint` | ESLint configuration factory |
| `@red-hat-developer-hub/e2e-test-utils/tsconfig` | Base TypeScript configuration |
| `@red-hat-developer-hub/e2e-test-utils/secrets` | Bitwarden local secret execution APIs |

## Detailed Exports

Expand Down Expand Up @@ -113,6 +114,21 @@ Factory function for creating ESLint flat config with Playwright and TypeScript

Base TypeScript configuration to extend in your project.

### Secrets (`/secrets`)

```typescript
import {
BitwardenClient,
executeCommand,
parseProfile,
} from "@red-hat-developer-hub/e2e-test-utils/secrets";
```

The secrets export provides profile validation, scoped Bitwarden reads, safe
child-environment materialization, and programmatic command execution. The
`rhdh-e2e-secrets` CLI is a separate executable and is not imported by
Playwright global setup.

## Usage Patterns

### Minimal Test Setup
Expand Down
6 changes: 3 additions & 3 deletions docs/guide/deployment/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ test.beforeEach(async ({ loginHelper }) => {
await loginHelper.loginAsGithubUser();
});
```
By default, test user credentials will be pulled from the global workspace in vault.
When supplied by a local secret wrapper or CI, test user credentials are read from the global secret set.

::: warning
GitHub authentication requires 2FA secret for automated logins. This is more complex to set up than guest or Keycloak auth.
Expand All @@ -154,7 +154,7 @@ No additional environment variables required.

### Keycloak Auth

These are automatically set by `KeycloakHelper.configureForRHDH()` or populated from global workspace in the vault:
These are automatically set by `KeycloakHelper.configureForRHDH()` or populated from the caller's environment:

| Variable | Description |
| ------------------------------- | --------------------- |
Expand All @@ -169,7 +169,7 @@ These are automatically set by `KeycloakHelper.configureForRHDH()` or populated

### GitHub Auth

Configuring github auth provider will populate the following variables from global workspace in the vault:
Configuring the GitHub auth provider consumes the following variables from the caller's environment:

| Variable | Description |
|----------|-------------|
Expand Down
8 changes: 4 additions & 4 deletions docs/guide/helpers/login-helper.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ await loginHelper.loginAsGithubUser();
```

Required environment variables:
- `VAULT_GH_USER_NAME` - GitHub username
- `VAULT_GH_USER_PASSWORD` - GitHub password
- `VAULT_GH_USER_ID` - GitHub username
- `VAULT_GH_USER_PASS` - GitHub password
- `VAULT_GH_2FA_SECRET` - GitHub 2FA secret (for OTP generation)

::: warning
Expand Down Expand Up @@ -192,8 +192,8 @@ test("login flow", async ({ page, loginHelper }) => {

| Variable | Description | Required |
|----------|-------------|----------|
| `VAULT_GH_USER_NAME` | GitHub username | Yes |
| `VAULT_GH_USER_PASSWORD` | GitHub password | Yes |
| `VAULT_GH_USER_ID` | GitHub username | Yes |
| `VAULT_GH_USER_PASS` | GitHub password | Yes |
| `VAULT_GH_2FA_SECRET` | 2FA secret for OTP | Yes |

## Troubleshooting
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ The package simplifies end-to-end testing for RHDH plugins by providing:
4. [Core Concepts](/guide/core-concepts/) - Understand the key concepts

::: tip For Overlay Repository Contributors
If you're writing tests in the **rhdh-plugin-export-overlays** repository, see the [Overlay Testing](/overlay/) documentation for repository-specific guidance including CI/CD integration, Vault secrets, and workspace structure.
If you're writing tests in the **rhdh-plugin-export-overlays** repository, see the [Overlay Testing](/overlay/) documentation for repository-specific guidance including CI/CD integration, local Bitwarden secrets, and workspace structure.
:::
23 changes: 12 additions & 11 deletions docs/overlay/examples/basic-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This is a minimal example of E2E tests for a simple plugin that doesn't require
## Overview

This example shows the simplest possible E2E test setup for a plugin in the overlay repository. Use this as a starting point for plugins that:

- Don't require external data providers
- Don't need custom Kubernetes resources
- Have straightforward UI interactions
Expand Down Expand Up @@ -49,7 +50,7 @@ workspaces/<plugin>/e2e-tests/
"description": "E2E tests for <plugin>",
"scripts": {
"test": "playwright test",
"test:vault": "VAULT=1 playwright test",
"test:secrets": "rhdh-e2e-secrets exec --profile ../../../e2e-secrets.profile.json --workspace <workspace> -- playwright test",
"report": "playwright show-report",
"test:ui": "playwright test --ui",
"test:headed": "playwright test --headed",
Expand All @@ -63,7 +64,7 @@ workspaces/<plugin>/e2e-tests/
"devDependencies": {
"@eslint/js": "10.0.1",
"@playwright/test": "1.59.1",
"@red-hat-developer-hub/e2e-test-utils": "1.1.33",
"@red-hat-developer-hub/e2e-test-utils": "2.3.0",
"@types/node": "25.5.2",
"eslint": "10.2.0",
"eslint-plugin-check-file": "3.3.1",
Expand Down Expand Up @@ -209,15 +210,15 @@ test.describe("Test <plugin>", () => {

## Common UIhelper Methods

| Method | Description |
|--------|-------------|
| `openSidebar(name)` | Click sidebar navigation item |
| `verifyHeading(text)` | Verify heading text is visible |
| `verifyText(text)` | Verify text is visible |
| `clickButton(name)` | Click button by name |
| `clickLink(text)` | Click link by text |
| `fillTextInputByLabel(label, value)` | Fill input field |
| `waitForLoad()` | Wait for page to finish loading |
| Method | Description |
| ------------------------------------ | ------------------------------- |
| `openSidebar(name)` | Click sidebar navigation item |
| `verifyHeading(text)` | Verify heading text is visible |
| `verifyText(text)` | Verify text is visible |
| `clickButton(name)` | Click button by name |
| `clickLink(text)` | Click link by text |
| `fillTextInputByLabel(label, value)` | Fill input field |
| `waitForLoad()` | Wait for page to finish loading |

See [UIhelper API](/api/helpers/ui-helper) for the full API reference.

Expand Down
Loading
Loading