rhdh-e2e-test-utils 1.0.1 → 1.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 +577 -56
- package/dist/deployment/keycloak/config/keycloak-values.yaml +94 -0
- package/dist/deployment/keycloak/constants.d.ts +29 -0
- package/dist/deployment/keycloak/constants.d.ts.map +1 -0
- package/dist/deployment/keycloak/constants.js +75 -0
- package/dist/deployment/keycloak/deployment.d.ts +89 -0
- package/dist/deployment/keycloak/deployment.d.ts.map +1 -0
- package/dist/deployment/keycloak/deployment.js +437 -0
- package/dist/deployment/keycloak/index.d.ts +2 -0
- package/dist/deployment/keycloak/index.d.ts.map +1 -0
- package/dist/deployment/keycloak/index.js +1 -0
- package/dist/deployment/keycloak/types.d.ts +59 -0
- package/dist/deployment/keycloak/types.d.ts.map +1 -0
- package/dist/deployment/keycloak/types.js +1 -0
- package/dist/deployment/rhdh/config/auth/guest/app-config.yaml +5 -0
- package/dist/deployment/rhdh/config/auth/keycloak/app-config.yaml +19 -0
- package/dist/deployment/rhdh/config/auth/keycloak/dynamic-plugins.yaml +3 -0
- package/dist/deployment/rhdh/config/auth/keycloak/secrets.yaml +12 -0
- package/dist/deployment/rhdh/config/{dynamic-plugins.yaml → common/dynamic-plugins.yaml} +1 -0
- package/dist/deployment/rhdh/constants.d.ts +6 -0
- package/dist/deployment/rhdh/constants.d.ts.map +1 -1
- package/dist/deployment/rhdh/constants.js +17 -5
- package/dist/deployment/rhdh/deployment.d.ts +8 -1
- package/dist/deployment/rhdh/deployment.d.ts.map +1 -1
- package/dist/deployment/rhdh/deployment.js +47 -39
- package/dist/deployment/rhdh/index.d.ts +0 -1
- package/dist/deployment/rhdh/index.d.ts.map +1 -1
- package/dist/deployment/rhdh/types.d.ts +4 -1
- package/dist/deployment/rhdh/types.d.ts.map +1 -1
- package/dist/eslint/base.config.d.ts.map +1 -1
- package/dist/eslint/base.config.js +9 -2
- package/dist/playwright/base-config.d.ts +3 -3
- package/dist/playwright/base-config.d.ts.map +1 -1
- package/dist/playwright/base-config.js +5 -4
- package/dist/playwright/fixtures/test.d.ts +4 -1
- package/dist/playwright/fixtures/test.d.ts.map +1 -1
- package/dist/playwright/fixtures/test.js +16 -4
- package/dist/playwright/global-setup.d.ts.map +1 -1
- package/dist/playwright/global-setup.js +36 -1
- package/dist/playwright/helpers/accessibility.d.ts +13 -0
- package/dist/playwright/helpers/accessibility.d.ts.map +1 -0
- package/dist/playwright/helpers/accessibility.js +24 -0
- package/dist/playwright/helpers/api-endpoints.d.ts +11 -0
- package/dist/playwright/helpers/api-endpoints.d.ts.map +1 -0
- package/dist/playwright/helpers/api-endpoints.js +15 -0
- package/dist/playwright/helpers/api-helper.d.ts +77 -0
- package/dist/playwright/helpers/api-helper.d.ts.map +1 -0
- package/dist/playwright/helpers/api-helper.js +285 -0
- package/dist/playwright/helpers/common.d.ts +31 -0
- package/dist/playwright/helpers/common.d.ts.map +1 -0
- package/dist/playwright/helpers/common.js +342 -0
- package/dist/playwright/helpers/index.d.ts +5 -0
- package/dist/playwright/helpers/index.d.ts.map +1 -0
- package/dist/playwright/helpers/index.js +4 -0
- package/dist/playwright/helpers/navbar.d.ts +2 -0
- package/dist/playwright/helpers/navbar.d.ts.map +1 -0
- package/dist/playwright/helpers/navbar.js +1 -0
- package/dist/playwright/helpers/ui-helper.d.ts +106 -0
- package/dist/playwright/helpers/ui-helper.d.ts.map +1 -0
- package/dist/playwright/helpers/ui-helper.js +439 -0
- package/dist/playwright/page-objects/global-obj.d.ts +25 -0
- package/dist/playwright/page-objects/global-obj.d.ts.map +1 -0
- package/dist/playwright/page-objects/global-obj.js +24 -0
- package/dist/playwright/page-objects/page-obj.d.ts +41 -0
- package/dist/playwright/page-objects/page-obj.d.ts.map +1 -0
- package/dist/playwright/page-objects/page-obj.js +40 -0
- package/dist/playwright/pages/catalog-import.d.ts +31 -0
- package/dist/playwright/pages/catalog-import.d.ts.map +1 -0
- package/dist/playwright/pages/catalog-import.js +65 -0
- package/dist/playwright/pages/catalog.d.ts +14 -0
- package/dist/playwright/pages/catalog.d.ts.map +1 -0
- package/dist/playwright/pages/catalog.js +37 -0
- package/dist/playwright/pages/extensions.d.ts +38 -0
- package/dist/playwright/pages/extensions.d.ts.map +1 -0
- package/dist/playwright/pages/extensions.js +110 -0
- package/dist/playwright/pages/home-page.d.ts +10 -0
- package/dist/playwright/pages/home-page.d.ts.map +1 -0
- package/dist/playwright/pages/home-page.js +46 -0
- package/dist/playwright/pages/index.d.ts +6 -0
- package/dist/playwright/pages/index.d.ts.map +1 -0
- package/dist/playwright/pages/index.js +5 -0
- package/dist/playwright/pages/notifications.d.ts +24 -0
- package/dist/playwright/pages/notifications.d.ts.map +1 -0
- package/dist/playwright/pages/notifications.js +112 -0
- package/dist/utils/kubernetes-client.d.ts +9 -0
- package/dist/utils/kubernetes-client.d.ts.map +1 -1
- package/dist/utils/kubernetes-client.js +57 -2
- package/dist/utils/merge-yamls.d.ts +25 -4
- package/dist/utils/merge-yamls.d.ts.map +1 -1
- package/dist/utils/merge-yamls.js +52 -12
- package/package.json +18 -2
- /package/dist/deployment/rhdh/config/{app-config-rhdh.yaml → common/app-config-rhdh.yaml} +0 -0
- /package/dist/deployment/rhdh/config/{rhdh-secrets.yaml → common/rhdh-secrets.yaml} +0 -0
- /package/dist/deployment/rhdh/{helm → config/helm}/value_file.yaml +0 -0
- /package/dist/deployment/rhdh/{operator → config/operator}/subscription.yaml +0 -0
package/README.md
CHANGED
|
@@ -13,8 +13,12 @@ A comprehensive test utility package for Red Hat Developer Hub (RHDH) end-to-end
|
|
|
13
13
|
- [Detailed Usage](#detailed-usage)
|
|
14
14
|
- [Playwright Test Fixtures](#playwright-test-fixtures)
|
|
15
15
|
- [Playwright Configuration](#playwright-configuration)
|
|
16
|
+
- [Global Setup](#global-setup)
|
|
16
17
|
- [RHDH Deployment](#rhdh-deployment)
|
|
18
|
+
- [Keycloak Deployment](#keycloak-deployment)
|
|
17
19
|
- [Utilities](#utilities)
|
|
20
|
+
- [Helpers](#helpers)
|
|
21
|
+
- [Page Objects](#page-objects)
|
|
18
22
|
- [ESLint Configuration](#eslint-configuration)
|
|
19
23
|
- [TypeScript Configuration](#typescript-configuration)
|
|
20
24
|
- [Configuration Files](#configuration-files)
|
|
@@ -28,6 +32,8 @@ A comprehensive test utility package for Red Hat Developer Hub (RHDH) end-to-end
|
|
|
28
32
|
`rhdh-e2e-test-utils` simplifies end-to-end testing for RHDH plugins by providing:
|
|
29
33
|
|
|
30
34
|
- **Automated RHDH Deployment**: Deploy RHDH instances via Helm or the RHDH Operator
|
|
35
|
+
- **Keycloak Integration**: Deploy and configure Keycloak for OIDC authentication testing
|
|
36
|
+
- **Modular Auth Configuration**: Switch between guest and Keycloak authentication with a single option
|
|
31
37
|
- **Playwright Integration**: Custom test fixtures that manage deployment lifecycle
|
|
32
38
|
- **Kubernetes Utilities**: Helper functions for managing namespaces, ConfigMaps, Secrets, and Routes
|
|
33
39
|
- **Configuration Merging**: YAML merging with environment variable substitution
|
|
@@ -36,6 +42,8 @@ A comprehensive test utility package for Red Hat Developer Hub (RHDH) end-to-end
|
|
|
36
42
|
## Features
|
|
37
43
|
|
|
38
44
|
- Deploy RHDH using Helm charts or the RHDH Operator
|
|
45
|
+
- Deploy Keycloak for authentication testing with automatic realm, client, and user configuration
|
|
46
|
+
- Modular authentication configuration (guest, Keycloak)
|
|
39
47
|
- Automatic namespace creation and cleanup
|
|
40
48
|
- Dynamic plugin configuration
|
|
41
49
|
- Helpers for UI, API and common Utils
|
|
@@ -80,7 +88,10 @@ The package provides multiple entry points for different use cases:
|
|
|
80
88
|
| `rhdh-e2e-test-utils/test` | Playwright test fixtures with RHDH deployment |
|
|
81
89
|
| `rhdh-e2e-test-utils/playwright-config` | Base Playwright configuration |
|
|
82
90
|
| `rhdh-e2e-test-utils/rhdh` | RHDH deployment class and types |
|
|
91
|
+
| `rhdh-e2e-test-utils/keycloak` | Keycloak deployment helper for authentication testing |
|
|
83
92
|
| `rhdh-e2e-test-utils/utils` | Utility functions (bash, YAML, Kubernetes) |
|
|
93
|
+
| `rhdh-e2e-test-utils/helpers` | UI, API, and login helper classes |
|
|
94
|
+
| `rhdh-e2e-test-utils/pages` | Page object classes for common RHDH pages |
|
|
84
95
|
| `rhdh-e2e-test-utils/eslint` | ESLint configuration factory |
|
|
85
96
|
| `rhdh-e2e-test-utils/tsconfig` | Base TypeScript configuration |
|
|
86
97
|
|
|
@@ -98,18 +109,15 @@ yarn add @playwright/test rhdh-e2e-test-utils
|
|
|
98
109
|
|
|
99
110
|
```typescript
|
|
100
111
|
// playwright.config.ts
|
|
101
|
-
import { defineConfig } from "
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
],
|
|
111
|
-
})
|
|
112
|
-
);
|
|
112
|
+
import { defineConfig } from "rhdh-e2e-test-utils/playwright-config";
|
|
113
|
+
|
|
114
|
+
export default defineConfig({
|
|
115
|
+
projects: [
|
|
116
|
+
{
|
|
117
|
+
name: "my-plugin",
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
});
|
|
113
121
|
```
|
|
114
122
|
|
|
115
123
|
### 3. Create Your Test
|
|
@@ -130,10 +138,10 @@ test("my plugin test", async ({ page }) => {
|
|
|
130
138
|
|
|
131
139
|
### 4. Create Configuration Files
|
|
132
140
|
|
|
133
|
-
Create a `config/` directory with your RHDH configuration:
|
|
141
|
+
Create a `tests/config/` directory with your RHDH configuration:
|
|
134
142
|
|
|
135
143
|
```
|
|
136
|
-
config/
|
|
144
|
+
tests/config/
|
|
137
145
|
├── app-config-rhdh.yaml # App configuration
|
|
138
146
|
├── dynamic-plugins.yaml # Dynamic plugins configuration
|
|
139
147
|
└── rhdh-secrets.yaml # Secrets (with env var placeholders)
|
|
@@ -167,6 +175,8 @@ import { test, expect } from "rhdh-e2e-test-utils/test";
|
|
|
167
175
|
| Fixture | Scope | Description |
|
|
168
176
|
|---------|-------|-------------|
|
|
169
177
|
| `rhdh` | worker | Shared RHDHDeployment across all tests in a worker |
|
|
178
|
+
| `uiHelper` | test | UIhelper instance for common UI interactions |
|
|
179
|
+
| `loginHelper` | test | LoginHelper instance for authentication flows |
|
|
170
180
|
| `baseURL` | test | Automatically set to the RHDH instance URL |
|
|
171
181
|
|
|
172
182
|
#### Fixture Behavior
|
|
@@ -177,6 +187,7 @@ import { test, expect } from "rhdh-e2e-test-utils/test";
|
|
|
177
187
|
|
|
178
188
|
```typescript
|
|
179
189
|
import { test, expect } from "rhdh-e2e-test-utils/test";
|
|
190
|
+
|
|
180
191
|
test.beforeAll(async ({ rhdh }) => {
|
|
181
192
|
// Configure RHDH (creates namespace, and optional DeploymentOptions)
|
|
182
193
|
await rhdh.configure();
|
|
@@ -188,10 +199,17 @@ test.beforeAll(async ({ rhdh }) => {
|
|
|
188
199
|
await rhdh.deploy();
|
|
189
200
|
});
|
|
190
201
|
|
|
191
|
-
test("example test", async ({ page, rhdh }) => {
|
|
202
|
+
test("example test", async ({ page, rhdh, uiHelper, loginHelper }) => {
|
|
192
203
|
// page.goto("/") will use rhdh.rhdhUrl as base
|
|
193
204
|
await page.goto("/");
|
|
194
205
|
|
|
206
|
+
// Login as guest user
|
|
207
|
+
await loginHelper.loginAsGuest();
|
|
208
|
+
|
|
209
|
+
// Use UI helper for common interactions
|
|
210
|
+
await uiHelper.verifyHeading("Welcome");
|
|
211
|
+
await uiHelper.clickButton("Get Started");
|
|
212
|
+
|
|
195
213
|
// Access deployment info
|
|
196
214
|
console.log(`Namespace: ${rhdh.deploymentConfig.namespace}`);
|
|
197
215
|
console.log(`URL: ${rhdh.rhdhUrl}`);
|
|
@@ -205,24 +223,22 @@ test("example test", async ({ page, rhdh }) => {
|
|
|
205
223
|
|
|
206
224
|
### Playwright Configuration
|
|
207
225
|
|
|
208
|
-
Use `
|
|
226
|
+
Use `defineConfig` for sensible defaults:
|
|
209
227
|
|
|
210
228
|
```typescript
|
|
211
|
-
|
|
212
|
-
import {
|
|
213
|
-
|
|
214
|
-
export default defineConfig(
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
})
|
|
225
|
-
);
|
|
229
|
+
// playwright.config.ts
|
|
230
|
+
import { defineConfig } from "rhdh-e2e-test-utils/playwright-config";
|
|
231
|
+
|
|
232
|
+
export default defineConfig({
|
|
233
|
+
projects: [
|
|
234
|
+
{
|
|
235
|
+
name: "tech-radar", // Also used as namespace
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: "catalog",
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
});
|
|
226
242
|
```
|
|
227
243
|
|
|
228
244
|
#### Base Configuration Defaults
|
|
@@ -238,6 +254,41 @@ export default defineConfig(
|
|
|
238
254
|
| `trace` | Retain on failure |
|
|
239
255
|
| `screenshot` | Only on failure |
|
|
240
256
|
|
|
257
|
+
#### Global Setup
|
|
258
|
+
|
|
259
|
+
The package includes a global setup function that runs once before all tests. It performs the following:
|
|
260
|
+
|
|
261
|
+
1. **Binary Check**: Verifies that required binaries (`oc`, `kubectl`, `helm`) are installed
|
|
262
|
+
2. **Cluster Router Base**: Fetches the OpenShift ingress domain and sets `K8S_CLUSTER_ROUTER_BASE`
|
|
263
|
+
3. **Keycloak Deployment**: Automatically deploys and configures Keycloak for OIDC authentication
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
// playwright.config.ts
|
|
267
|
+
import { defineConfig } from "rhdh-e2e-test-utils/playwright-config";
|
|
268
|
+
|
|
269
|
+
export default defineConfig({
|
|
270
|
+
// Global setup is automatically included
|
|
271
|
+
projects: [{ name: "my-plugin" }],
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Keycloak Auto-Deployment Behavior:**
|
|
276
|
+
|
|
277
|
+
- Keycloak is deployed to the `rhdh-keycloak` namespace
|
|
278
|
+
- If Keycloak is already running, deployment is skipped
|
|
279
|
+
- All Keycloak environment variables are automatically set after deployment
|
|
280
|
+
- The following test credentials are created:
|
|
281
|
+
- Username: `test1`, Password: `test1@123`
|
|
282
|
+
- Username: `test2`, Password: `test2@123`
|
|
283
|
+
|
|
284
|
+
**Skip Keycloak Deployment:**
|
|
285
|
+
|
|
286
|
+
If your tests don't require Keycloak/OIDC authentication, set the environment variable:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
SKIP_KEYCLOAK_DEPLOYMENT=true yarn playwright test
|
|
290
|
+
```
|
|
291
|
+
|
|
241
292
|
### RHDH Deployment
|
|
242
293
|
|
|
243
294
|
#### RHDHDeployment Class
|
|
@@ -247,25 +298,33 @@ The core class for managing RHDH deployments:
|
|
|
247
298
|
```typescript
|
|
248
299
|
import { RHDHDeployment } from "rhdh-e2e-test-utils/rhdh";
|
|
249
300
|
|
|
250
|
-
|
|
251
|
-
|
|
301
|
+
// Create deployment with namespace (required)
|
|
302
|
+
const deployment = new RHDHDeployment("my-test-namespace");
|
|
303
|
+
|
|
304
|
+
// Configure with options (call before deploy)
|
|
305
|
+
await deployment.configure({
|
|
252
306
|
version: "1.5", // Optional, uses RHDH_VERSION env
|
|
253
307
|
method: "helm", // Optional, uses INSTALLATION_METHOD env
|
|
308
|
+
auth: "keycloak", // Optional, defaults to "keycloak"
|
|
254
309
|
appConfig: "config/app-config-rhdh.yaml", // Optional
|
|
255
310
|
secrets: "config/rhdh-secrets.yaml", // Optional
|
|
256
311
|
dynamicPlugins: "config/dynamic-plugins.yaml", // Optional
|
|
257
312
|
valueFile: "config/value_file.yaml", // Optional & Helm only
|
|
258
313
|
subscription: "config/subscription.yaml", // Optional & Operator only
|
|
259
314
|
});
|
|
315
|
+
|
|
316
|
+
// Deploy RHDH
|
|
317
|
+
await deployment.deploy();
|
|
260
318
|
```
|
|
261
319
|
|
|
262
320
|
#### Deployment Options
|
|
263
321
|
|
|
264
322
|
```typescript
|
|
265
323
|
type DeploymentOptions = {
|
|
266
|
-
namespace
|
|
324
|
+
namespace?: string; // Kubernetes namespace (set via constructor)
|
|
267
325
|
version?: string; // RHDH version (e.g., "1.5", "1.5.1-CI")
|
|
268
326
|
method?: "helm" | "operator"; // Installation method
|
|
327
|
+
auth?: "guest" | "keycloak"; // Authentication provider (default: "keycloak")
|
|
269
328
|
appConfig?: string; // Path to app-config YAML
|
|
270
329
|
secrets?: string; // Path to secrets YAML
|
|
271
330
|
dynamicPlugins?: string; // Path to dynamic-plugins YAML
|
|
@@ -274,6 +333,17 @@ type DeploymentOptions = {
|
|
|
274
333
|
};
|
|
275
334
|
```
|
|
276
335
|
|
|
336
|
+
#### Authentication Providers
|
|
337
|
+
|
|
338
|
+
The package supports modular authentication configuration. Set the `auth` option to automatically include the appropriate auth-specific configurations:
|
|
339
|
+
|
|
340
|
+
| Provider | Description |
|
|
341
|
+
|----------|-------------|
|
|
342
|
+
| `guest` | Guest authentication for development/testing |
|
|
343
|
+
| `keycloak` | OIDC authentication via Keycloak (default) |
|
|
344
|
+
|
|
345
|
+
Auth-specific configurations are automatically merged with your project configurations. For Keycloak authentication, see [Keycloak Deployment](#keycloak-deployment).
|
|
346
|
+
|
|
277
347
|
#### Deployment Methods
|
|
278
348
|
|
|
279
349
|
##### Helm Deployment
|
|
@@ -318,6 +388,162 @@ await rhdh.deploy();
|
|
|
318
388
|
| `deploymentConfig` | `DeploymentConfig` | Current deployment configuration |
|
|
319
389
|
| `k8sClient` | `KubernetesClientHelper` | Kubernetes client instance |
|
|
320
390
|
|
|
391
|
+
### Keycloak Deployment
|
|
392
|
+
|
|
393
|
+
The package provides a `KeycloakHelper` class for deploying and configuring Keycloak in OpenShift, enabling OIDC authentication testing with RHDH.
|
|
394
|
+
|
|
395
|
+
#### KeycloakHelper Class
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
import { KeycloakHelper } from "rhdh-e2e-test-utils/keycloak";
|
|
399
|
+
|
|
400
|
+
const keycloak = new KeycloakHelper({
|
|
401
|
+
namespace: "rhdh-keycloak", // Optional, defaults to "rhdh-keycloak"
|
|
402
|
+
releaseName: "keycloak", // Optional, defaults to "keycloak"
|
|
403
|
+
adminUser: "admin", // Optional, defaults to "admin"
|
|
404
|
+
adminPassword: "admin123", // Optional, defaults to "admin123"
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Deploy Keycloak using Bitnami Helm chart
|
|
408
|
+
await keycloak.deploy();
|
|
409
|
+
|
|
410
|
+
// Configure realm, client, groups, and users for RHDH
|
|
411
|
+
await keycloak.configureForRHDH();
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
#### Deployment Options
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
type KeycloakDeploymentOptions = {
|
|
418
|
+
namespace?: string; // Kubernetes namespace (default: "rhdh-keycloak")
|
|
419
|
+
releaseName?: string; // Helm release name (default: "keycloak")
|
|
420
|
+
valuesFile?: string; // Custom Helm values file
|
|
421
|
+
adminUser?: string; // Admin username (default: "admin")
|
|
422
|
+
adminPassword?: string; // Admin password (default: "admin123")
|
|
423
|
+
};
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### KeycloakHelper API
|
|
427
|
+
|
|
428
|
+
| Method | Description |
|
|
429
|
+
|--------|-------------|
|
|
430
|
+
| `deploy()` | Deploy Keycloak using Helm and wait for it to be ready |
|
|
431
|
+
| `configureForRHDH(options?)` | Configure realm, client, groups, and users for RHDH |
|
|
432
|
+
| `isRunning()` | Check if Keycloak is accessible |
|
|
433
|
+
| `connect(config)` | Connect to an existing Keycloak instance |
|
|
434
|
+
| `createRealm(config)` | Create a new realm |
|
|
435
|
+
| `createClient(realm, config)` | Create a client in a realm |
|
|
436
|
+
| `createGroup(realm, config)` | Create a group in a realm |
|
|
437
|
+
| `createUser(realm, config)` | Create a user with optional group membership |
|
|
438
|
+
| `getUsers(realm)` | Get all users in a realm |
|
|
439
|
+
| `getGroups(realm)` | Get all groups in a realm |
|
|
440
|
+
| `deleteUser(realm, username)` | Delete a user |
|
|
441
|
+
| `deleteGroup(realm, groupName)` | Delete a group |
|
|
442
|
+
| `deleteRealm(realm)` | Delete a realm |
|
|
443
|
+
| `teardown()` | Delete the Keycloak namespace |
|
|
444
|
+
| `waitUntilReady(timeout?)` | Wait for Keycloak StatefulSet to be ready |
|
|
445
|
+
|
|
446
|
+
#### Properties
|
|
447
|
+
|
|
448
|
+
| Property | Type | Description |
|
|
449
|
+
|----------|------|-------------|
|
|
450
|
+
| `keycloakUrl` | `string` | The Keycloak instance URL |
|
|
451
|
+
| `realm` | `string` | Configured realm name |
|
|
452
|
+
| `clientId` | `string` | Configured client ID |
|
|
453
|
+
| `clientSecret` | `string` | Configured client secret |
|
|
454
|
+
| `deploymentConfig` | `KeycloakDeploymentConfig` | Current deployment configuration |
|
|
455
|
+
| `k8sClient` | `KubernetesClientHelper` | Kubernetes client instance |
|
|
456
|
+
|
|
457
|
+
#### Default Configuration
|
|
458
|
+
|
|
459
|
+
When using `configureForRHDH()`, the following defaults are applied:
|
|
460
|
+
|
|
461
|
+
**Default Realm**: `rhdh`
|
|
462
|
+
|
|
463
|
+
**Default Client** (`rhdh-client`):
|
|
464
|
+
- Client secret: `rhdh-client-secret`
|
|
465
|
+
- Standard flow, implicit flow, direct access grants enabled
|
|
466
|
+
- Service accounts enabled with realm-management roles
|
|
467
|
+
|
|
468
|
+
**Default Groups**:
|
|
469
|
+
- `developers`
|
|
470
|
+
- `admins`
|
|
471
|
+
- `viewers`
|
|
472
|
+
|
|
473
|
+
**Default Users**:
|
|
474
|
+
| Username | Password | Groups |
|
|
475
|
+
|----------|----------|--------|
|
|
476
|
+
| `test1` | `test1@123` | developers |
|
|
477
|
+
| `test2` | `test2@123` | developers |
|
|
478
|
+
|
|
479
|
+
#### Example: Full RHDH + Keycloak Setup
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
import { test } from "rhdh-e2e-test-utils/test";
|
|
483
|
+
import { KeycloakHelper } from "rhdh-e2e-test-utils/keycloak";
|
|
484
|
+
|
|
485
|
+
let keycloak: KeycloakHelper;
|
|
486
|
+
|
|
487
|
+
test.beforeAll(async ({ rhdh }) => {
|
|
488
|
+
// Deploy Keycloak
|
|
489
|
+
keycloak = new KeycloakHelper({ namespace: "rhdh-keycloak" });
|
|
490
|
+
await keycloak.deploy();
|
|
491
|
+
await keycloak.configureForRHDH();
|
|
492
|
+
|
|
493
|
+
// Set environment variables for RHDH
|
|
494
|
+
process.env.KEYCLOAK_BASE_URL = keycloak.keycloakUrl;
|
|
495
|
+
process.env.KEYCLOAK_REALM = keycloak.realm;
|
|
496
|
+
process.env.KEYCLOAK_CLIENT_ID = keycloak.clientId;
|
|
497
|
+
process.env.KEYCLOAK_CLIENT_SECRET = keycloak.clientSecret;
|
|
498
|
+
process.env.KEYCLOAK_METADATA_URL = `${keycloak.keycloakUrl}/realms/${keycloak.realm}/.well-known/openid-configuration`;
|
|
499
|
+
process.env.KEYCLOAK_LOGIN_REALM = keycloak.realm;
|
|
500
|
+
|
|
501
|
+
// Deploy RHDH with Keycloak authentication
|
|
502
|
+
await rhdh.configure({ auth: "keycloak" });
|
|
503
|
+
await rhdh.deploy();
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
test("login with Keycloak user", async ({ page, loginHelper }) => {
|
|
507
|
+
await page.goto("/");
|
|
508
|
+
await loginHelper.loginAsKeycloakUser("test1", "test1@123");
|
|
509
|
+
// ... test assertions
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
test.afterAll(async () => {
|
|
513
|
+
await keycloak.teardown();
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
#### Connect to Existing Keycloak
|
|
518
|
+
|
|
519
|
+
```typescript
|
|
520
|
+
import { KeycloakHelper } from "rhdh-e2e-test-utils/keycloak";
|
|
521
|
+
|
|
522
|
+
const keycloak = new KeycloakHelper();
|
|
523
|
+
|
|
524
|
+
// Connect with admin credentials
|
|
525
|
+
await keycloak.connect({
|
|
526
|
+
baseUrl: "https://keycloak.example.com",
|
|
527
|
+
username: "admin",
|
|
528
|
+
password: "admin-password",
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// Or connect with client credentials
|
|
532
|
+
await keycloak.connect({
|
|
533
|
+
baseUrl: "https://keycloak.example.com",
|
|
534
|
+
realm: "my-realm",
|
|
535
|
+
clientId: "admin-client",
|
|
536
|
+
clientSecret: "client-secret",
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// Now you can manage users, groups, etc.
|
|
540
|
+
await keycloak.createUser("my-realm", {
|
|
541
|
+
username: "newuser",
|
|
542
|
+
password: "password123",
|
|
543
|
+
groups: ["developers"],
|
|
544
|
+
});
|
|
545
|
+
```
|
|
546
|
+
|
|
321
547
|
### Utilities
|
|
322
548
|
|
|
323
549
|
#### Bash Command Execution
|
|
@@ -388,6 +614,222 @@ const result = envsubst("Port: ${PORT:-8080}");
|
|
|
388
614
|
const result = envsubst("API: ${API_URL}");
|
|
389
615
|
```
|
|
390
616
|
|
|
617
|
+
### Helpers
|
|
618
|
+
|
|
619
|
+
The package provides helper classes for common testing operations.
|
|
620
|
+
|
|
621
|
+
#### UIhelper
|
|
622
|
+
|
|
623
|
+
A utility class for common UI interactions with Material-UI components:
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
import { UIhelper } from "rhdh-e2e-test-utils/helpers";
|
|
627
|
+
|
|
628
|
+
const uiHelper = new UIhelper(page);
|
|
629
|
+
|
|
630
|
+
// Wait for page to fully load
|
|
631
|
+
await uiHelper.waitForLoad();
|
|
632
|
+
|
|
633
|
+
// Verify headings and text
|
|
634
|
+
await uiHelper.verifyHeading("Welcome to RHDH");
|
|
635
|
+
await uiHelper.verifyText("Some content");
|
|
636
|
+
|
|
637
|
+
// Button interactions
|
|
638
|
+
await uiHelper.clickButton("Submit");
|
|
639
|
+
await uiHelper.clickButtonByLabel("Close");
|
|
640
|
+
|
|
641
|
+
// Navigation
|
|
642
|
+
await uiHelper.openSidebar("Catalog");
|
|
643
|
+
await uiHelper.clickTab("Overview");
|
|
644
|
+
|
|
645
|
+
// Table operations
|
|
646
|
+
await uiHelper.verifyRowsInTable(["row1", "row2"]);
|
|
647
|
+
await uiHelper.verifyCellsInTable(["cell1", "cell2"]);
|
|
648
|
+
|
|
649
|
+
// MUI component interactions
|
|
650
|
+
await uiHelper.selectMuiBox("Kind", "Component");
|
|
651
|
+
await uiHelper.fillTextInputByLabel("Name", "my-component");
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
#### LoginHelper
|
|
655
|
+
|
|
656
|
+
Handles authentication flows for different providers:
|
|
657
|
+
|
|
658
|
+
```typescript
|
|
659
|
+
import { LoginHelper } from "rhdh-e2e-test-utils/helpers";
|
|
660
|
+
|
|
661
|
+
const loginHelper = new LoginHelper(page);
|
|
662
|
+
|
|
663
|
+
// Guest authentication
|
|
664
|
+
await loginHelper.loginAsGuest();
|
|
665
|
+
await loginHelper.signOut();
|
|
666
|
+
|
|
667
|
+
// Keycloak authentication
|
|
668
|
+
await loginHelper.loginAsKeycloakUser("username", "password");
|
|
669
|
+
|
|
670
|
+
// GitHub authentication (requires environment variables)
|
|
671
|
+
await loginHelper.loginAsGithubUser();
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
#### APIHelper
|
|
675
|
+
|
|
676
|
+
Provides utilities for API interactions with both GitHub and Backstage catalog:
|
|
677
|
+
|
|
678
|
+
```typescript
|
|
679
|
+
import { APIHelper } from "rhdh-e2e-test-utils/helpers";
|
|
680
|
+
|
|
681
|
+
// GitHub API operations
|
|
682
|
+
await APIHelper.createGitHubRepo("owner", "repo-name");
|
|
683
|
+
await APIHelper.deleteGitHubRepo("owner", "repo-name");
|
|
684
|
+
const prs = await APIHelper.getGitHubPRs("owner", "repo", "open");
|
|
685
|
+
|
|
686
|
+
// Backstage catalog API operations
|
|
687
|
+
const apiHelper = new APIHelper();
|
|
688
|
+
await apiHelper.setBaseUrl(rhdhUrl);
|
|
689
|
+
await apiHelper.setStaticToken(token);
|
|
690
|
+
|
|
691
|
+
const users = await apiHelper.getAllCatalogUsersFromAPI();
|
|
692
|
+
const groups = await apiHelper.getAllCatalogGroupsFromAPI();
|
|
693
|
+
const locations = await apiHelper.getAllCatalogLocationsFromAPI();
|
|
694
|
+
|
|
695
|
+
// Schedule entity refresh
|
|
696
|
+
await apiHelper.scheduleEntityRefreshFromAPI("my-component", "component", token);
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
#### setupBrowser
|
|
700
|
+
|
|
701
|
+
Utility function for setting up a shared browser context with video recording. Use this in `test.beforeAll` for serial test suites or when you want to persist the browser context across multiple tests (e.g., to avoid repeated logins):
|
|
702
|
+
|
|
703
|
+
```typescript
|
|
704
|
+
import { test } from "@playwright/test";
|
|
705
|
+
import { setupBrowser, LoginHelper } from "rhdh-e2e-test-utils/helpers";
|
|
706
|
+
import type { Page, BrowserContext } from "@playwright/test";
|
|
707
|
+
|
|
708
|
+
test.describe.configure({ mode: "serial" });
|
|
709
|
+
|
|
710
|
+
let page: Page;
|
|
711
|
+
let context: BrowserContext;
|
|
712
|
+
|
|
713
|
+
test.beforeAll(async ({ browser }, testInfo) => {
|
|
714
|
+
// Setup shared browser context with video recording
|
|
715
|
+
({ page, context } = await setupBrowser(browser, testInfo));
|
|
716
|
+
|
|
717
|
+
// Login once, session persists across all tests in this suite
|
|
718
|
+
const loginHelper = new LoginHelper(page);
|
|
719
|
+
await page.goto("/");
|
|
720
|
+
await loginHelper.loginAsKeycloakUser();
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
test.afterAll(async () => {
|
|
724
|
+
await context.close();
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
test("first test - already logged in", async () => {
|
|
728
|
+
await page.goto("/catalog");
|
|
729
|
+
// No need to login again
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
test("second test - session persists", async () => {
|
|
733
|
+
await page.goto("/settings");
|
|
734
|
+
// Still logged in from beforeAll
|
|
735
|
+
});
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### Page Objects
|
|
739
|
+
|
|
740
|
+
Pre-built page object classes for common RHDH pages:
|
|
741
|
+
|
|
742
|
+
```typescript
|
|
743
|
+
import {
|
|
744
|
+
CatalogPage,
|
|
745
|
+
HomePage,
|
|
746
|
+
CatalogImportPage,
|
|
747
|
+
ExtensionsPage,
|
|
748
|
+
NotificationPage,
|
|
749
|
+
} from "rhdh-e2e-test-utils/pages";
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
#### CatalogPage
|
|
753
|
+
|
|
754
|
+
```typescript
|
|
755
|
+
const catalogPage = new CatalogPage(page);
|
|
756
|
+
|
|
757
|
+
// Navigate to catalog
|
|
758
|
+
await catalogPage.go();
|
|
759
|
+
|
|
760
|
+
// Search for entities
|
|
761
|
+
await catalogPage.search("my-component");
|
|
762
|
+
|
|
763
|
+
// Navigate to specific component
|
|
764
|
+
await catalogPage.goToByName("my-component");
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
#### HomePage
|
|
768
|
+
|
|
769
|
+
```typescript
|
|
770
|
+
const homePage = new HomePage(page);
|
|
771
|
+
|
|
772
|
+
// Verify quick search functionality
|
|
773
|
+
await homePage.verifyQuickSearchBar("search-term");
|
|
774
|
+
|
|
775
|
+
// Verify quick access sections
|
|
776
|
+
await homePage.verifyQuickAccess("Favorites", "My Component");
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
#### CatalogImportPage
|
|
780
|
+
|
|
781
|
+
```typescript
|
|
782
|
+
const catalogImportPage = new CatalogImportPage(page);
|
|
783
|
+
|
|
784
|
+
// Register or refresh an existing component
|
|
785
|
+
const wasAlreadyRegistered = await catalogImportPage.registerExistingComponent(
|
|
786
|
+
"https://github.com/org/repo/blob/main/catalog-info.yaml"
|
|
787
|
+
);
|
|
788
|
+
|
|
789
|
+
// Analyze a component URL
|
|
790
|
+
await catalogImportPage.analyzeComponent("https://github.com/org/repo/blob/main/catalog-info.yaml");
|
|
791
|
+
|
|
792
|
+
// Inspect entity and verify YAML content
|
|
793
|
+
await catalogImportPage.inspectEntityAndVerifyYaml("kind: Component");
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
#### ExtensionsPage
|
|
797
|
+
|
|
798
|
+
```typescript
|
|
799
|
+
const extensionsPage = new ExtensionsPage(page);
|
|
800
|
+
|
|
801
|
+
// Filter by support type
|
|
802
|
+
await extensionsPage.selectSupportTypeFilter("Red Hat");
|
|
803
|
+
|
|
804
|
+
// Verify plugin details
|
|
805
|
+
await extensionsPage.verifyPluginDetails({
|
|
806
|
+
pluginName: "Topology",
|
|
807
|
+
badgeLabel: "Red Hat support",
|
|
808
|
+
badgeText: "Red Hat",
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
// Search and verify results
|
|
812
|
+
await extensionsPage.waitForSearchResults("catalog");
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
#### NotificationPage
|
|
816
|
+
|
|
817
|
+
```typescript
|
|
818
|
+
const notificationPage = new NotificationPage(page);
|
|
819
|
+
|
|
820
|
+
// Navigate to notifications
|
|
821
|
+
await notificationPage.clickNotificationsNavBarItem();
|
|
822
|
+
|
|
823
|
+
// Check notification content
|
|
824
|
+
await notificationPage.notificationContains("Build completed");
|
|
825
|
+
|
|
826
|
+
// Manage notifications
|
|
827
|
+
await notificationPage.markAllNotificationsAsRead();
|
|
828
|
+
await notificationPage.selectSeverity("critical");
|
|
829
|
+
await notificationPage.viewSaved();
|
|
830
|
+
await notificationPage.sortByNewestOnTop();
|
|
831
|
+
```
|
|
832
|
+
|
|
391
833
|
### ESLint Configuration
|
|
392
834
|
|
|
393
835
|
Pre-configured ESLint rules for Playwright tests:
|
|
@@ -415,23 +857,40 @@ Extend the base tsconfig:
|
|
|
415
857
|
|
|
416
858
|
### Default Configuration Structure
|
|
417
859
|
|
|
418
|
-
The package includes default configurations
|
|
860
|
+
The package includes default configurations organized in a modular structure:
|
|
419
861
|
|
|
420
862
|
```
|
|
421
|
-
src/deployment/rhdh/
|
|
422
|
-
├──
|
|
423
|
-
│ ├── app-config-rhdh.yaml
|
|
424
|
-
│ ├── dynamic-plugins.yaml
|
|
425
|
-
│ └── rhdh-secrets.yaml
|
|
863
|
+
src/deployment/rhdh/config/
|
|
864
|
+
├── common/ # Base configurations (always applied)
|
|
865
|
+
│ ├── app-config-rhdh.yaml # Base app configuration
|
|
866
|
+
│ ├── dynamic-plugins.yaml # Default dynamic plugins
|
|
867
|
+
│ └── rhdh-secrets.yaml # Base secrets template
|
|
868
|
+
├── auth/ # Auth-specific configurations
|
|
869
|
+
│ ├── guest/
|
|
870
|
+
│ │ └── app-config.yaml # Guest auth configuration
|
|
871
|
+
│ └── keycloak/
|
|
872
|
+
│ ├── app-config.yaml # Keycloak OIDC configuration
|
|
873
|
+
│ ├── dynamic-plugins.yaml # Keycloak-specific plugins
|
|
874
|
+
│ └── secrets.yaml # Keycloak secrets template
|
|
426
875
|
├── helm/
|
|
427
|
-
│ └── value_file.yaml
|
|
876
|
+
│ └── value_file.yaml # Default Helm values
|
|
428
877
|
└── operator/
|
|
429
|
-
└── subscription.yaml
|
|
878
|
+
└── subscription.yaml # Default Backstage CR
|
|
430
879
|
```
|
|
431
880
|
|
|
881
|
+
### Configuration Merging
|
|
882
|
+
|
|
883
|
+
Configurations are merged in the following order (later overrides earlier):
|
|
884
|
+
|
|
885
|
+
1. **Common configs** (`config/common/`) - Base configurations
|
|
886
|
+
2. **Auth configs** (`config/auth/{provider}/`) - Auth-provider-specific configurations
|
|
887
|
+
3. **Project configs** (`tests/config/`) - Your project's custom configurations
|
|
888
|
+
|
|
889
|
+
This allows you to use built-in defaults while only overriding what you need.
|
|
890
|
+
|
|
432
891
|
### Project Configuration
|
|
433
892
|
|
|
434
|
-
Create these files in your project's `config/` directory:
|
|
893
|
+
Create these files in your project's `tests/config/` directory:
|
|
435
894
|
|
|
436
895
|
#### app-config-rhdh.yaml
|
|
437
896
|
|
|
@@ -444,15 +903,12 @@ backend:
|
|
|
444
903
|
allow:
|
|
445
904
|
- host: ${MY_BACKEND_HOST}
|
|
446
905
|
|
|
447
|
-
auth:
|
|
448
|
-
environment: development
|
|
449
|
-
providers:
|
|
450
|
-
guest:
|
|
451
|
-
dangerouslyAllowOutsideDevelopment: true
|
|
452
|
-
|
|
453
906
|
# Plugin-specific config
|
|
454
907
|
techRadar:
|
|
455
908
|
url: "http://${DATA_SOURCE_URL}/tech-radar"
|
|
909
|
+
|
|
910
|
+
# Note: Auth configuration is automatically included based on the 'auth' option
|
|
911
|
+
# You only need to add auth config here if you want to override the defaults
|
|
456
912
|
```
|
|
457
913
|
|
|
458
914
|
#### dynamic-plugins.yaml
|
|
@@ -509,6 +965,22 @@ stringData:
|
|
|
509
965
|
|----------|-------------|
|
|
510
966
|
| `CI` | If set, namespaces are auto-deleted after tests |
|
|
511
967
|
| `CHART_URL` | Custom Helm chart URL (default: `oci://quay.io/rhdh/chart`) |
|
|
968
|
+
| `SKIP_KEYCLOAK_DEPLOYMENT` | Set to `true` to skip automatic Keycloak deployment in global setup |
|
|
969
|
+
|
|
970
|
+
### Keycloak Environment Variables (for `auth: "keycloak"`)
|
|
971
|
+
|
|
972
|
+
When using Keycloak authentication, these environment variables are required:
|
|
973
|
+
|
|
974
|
+
| Variable | Description |
|
|
975
|
+
|----------|-------------|
|
|
976
|
+
| `KEYCLOAK_BASE_URL` | Keycloak instance URL |
|
|
977
|
+
| `KEYCLOAK_METADATA_URL` | OIDC metadata URL (e.g., `{KEYCLOAK_BASE_URL}/realms/{realm}/.well-known/openid-configuration`) |
|
|
978
|
+
| `KEYCLOAK_CLIENT_ID` | OIDC client ID |
|
|
979
|
+
| `KEYCLOAK_CLIENT_SECRET` | OIDC client secret |
|
|
980
|
+
| `KEYCLOAK_REALM` | Keycloak realm name |
|
|
981
|
+
| `KEYCLOAK_LOGIN_REALM` | Login realm (usually same as `KEYCLOAK_REALM`) |
|
|
982
|
+
|
|
983
|
+
These are automatically set when using `KeycloakHelper.configureForRHDH()`. See [Keycloak Deployment](#keycloak-deployment) for details.
|
|
512
984
|
|
|
513
985
|
|
|
514
986
|
## Examples
|
|
@@ -516,21 +988,70 @@ stringData:
|
|
|
516
988
|
### Custom Deployment Configuration
|
|
517
989
|
|
|
518
990
|
```typescript
|
|
519
|
-
import {
|
|
991
|
+
import { test } from "rhdh-e2e-test-utils/test";
|
|
520
992
|
|
|
521
993
|
test.beforeAll(async ({ rhdh }) => {
|
|
522
|
-
rhdh.configure({
|
|
523
|
-
namespace: "custom-test-ns",
|
|
994
|
+
await rhdh.configure({
|
|
524
995
|
version: "1.5",
|
|
525
996
|
method: "helm",
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
997
|
+
auth: "keycloak", // or "guest" for development
|
|
998
|
+
appConfig: "tests/config/app-config.yaml",
|
|
999
|
+
secrets: "tests/config/secrets.yaml",
|
|
1000
|
+
dynamicPlugins: "tests/config/plugins.yaml",
|
|
1001
|
+
valueFile: "tests/config/values.yaml",
|
|
530
1002
|
});
|
|
531
1003
|
|
|
532
1004
|
await rhdh.deploy();
|
|
1005
|
+
});
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
### Guest Authentication (Development)
|
|
1009
|
+
|
|
1010
|
+
```typescript
|
|
1011
|
+
import { test } from "rhdh-e2e-test-utils/test";
|
|
1012
|
+
|
|
1013
|
+
test.beforeAll(async ({ rhdh }) => {
|
|
1014
|
+
await rhdh.configure({ auth: "guest" });
|
|
1015
|
+
await rhdh.deploy();
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
test("test with guest login", async ({ page, loginHelper }) => {
|
|
1019
|
+
await page.goto("/");
|
|
1020
|
+
await loginHelper.loginAsGuest();
|
|
1021
|
+
// ... test assertions
|
|
1022
|
+
});
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
### Using Helpers and Page Objects
|
|
1026
|
+
|
|
1027
|
+
```typescript
|
|
1028
|
+
import { test, expect } from "rhdh-e2e-test-utils/test";
|
|
1029
|
+
import { CatalogPage } from "rhdh-e2e-test-utils/pages";
|
|
1030
|
+
import { APIHelper } from "rhdh-e2e-test-utils/helpers";
|
|
1031
|
+
|
|
1032
|
+
test.beforeAll(async ({ rhdh }) => {
|
|
1033
|
+
await rhdh.deploy();
|
|
1034
|
+
});
|
|
1035
|
+
|
|
1036
|
+
test("catalog interaction", async ({ page, uiHelper, loginHelper }) => {
|
|
1037
|
+
// Login
|
|
1038
|
+
await loginHelper.loginAsKeycloakUser();
|
|
1039
|
+
|
|
1040
|
+
// Use page object for catalog operations
|
|
1041
|
+
const catalogPage = new CatalogPage(page);
|
|
1042
|
+
await catalogPage.go();
|
|
1043
|
+
await catalogPage.search("my-component");
|
|
1044
|
+
|
|
1045
|
+
// Use UI helper for assertions
|
|
1046
|
+
await uiHelper.verifyRowsInTable(["my-component"]);
|
|
1047
|
+
});
|
|
1048
|
+
|
|
1049
|
+
test("API operations", async ({ rhdh }) => {
|
|
1050
|
+
// Create GitHub repo via API
|
|
1051
|
+
await APIHelper.createGitHubRepo("my-org", "test-repo");
|
|
533
1052
|
|
|
1053
|
+
// Clean up
|
|
1054
|
+
await APIHelper.deleteGitHubRepo("my-org", "test-repo");
|
|
534
1055
|
});
|
|
535
1056
|
```
|
|
536
1057
|
|