@eclipse-che/che-e2e 7.115.0-next-bbc9257 → 7.115.0-next-07d7770
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/.claude/commands/run-e2e-test.md +573 -0
- package/.claude/settings.local.json +13 -0
- package/.claude/skills/e2e-test-developer/SKILL.md +456 -0
- package/CLAUDE.md +150 -0
- package/README.md +1 -1
- package/constants/TIMEOUT_CONSTANTS.ts +6 -0
- package/dist/constants/TIMEOUT_CONSTANTS.js +4 -0
- package/dist/constants/TIMEOUT_CONSTANTS.js.map +1 -1
- package/dist/specs/miscellaneous/PredefinedNamespace.spec.js +12 -0
- package/dist/specs/miscellaneous/PredefinedNamespace.spec.js.map +1 -1
- package/dist/tests-library/ProjectAndFileTests.js +1 -1
- package/dist/tests-library/ProjectAndFileTests.js.map +1 -1
- package/package.json +1 -1
- package/specs/miscellaneous/PredefinedNamespace.spec.ts +14 -0
- package/tests-library/ProjectAndFileTests.ts +1 -1
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
# Run E2E Tests - Unified Command
|
|
2
|
+
|
|
3
|
+
Run E2E tests against **Eclipse Che** or **Red Hat OpenShift Dev Spaces** using either a **local Chrome browser** or **Podman container**.
|
|
4
|
+
|
|
5
|
+
## Arguments: $ARGUMENTS
|
|
6
|
+
|
|
7
|
+
**Usage:** `/run-e2e-test [URL USERNAME PASSWORD [TESTNAME]]`
|
|
8
|
+
|
|
9
|
+
**Examples:**
|
|
10
|
+
|
|
11
|
+
- `/run-e2e-test` - Interactive mode (recommended)
|
|
12
|
+
- `/run-e2e-test https://devspaces.apps.cluster.example.com/ admin mypassword SmokeTest npm`
|
|
13
|
+
- `/run-e2e-test https://che.apps.cluster.example.com/ admin mypassword EmptyWorkspace podman`
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Execution Flow
|
|
18
|
+
|
|
19
|
+
1. **Parse arguments** - Extract parameters from `$ARGUMENTS`
|
|
20
|
+
2. **Prompt if missing** - Collect missing values via AskUserQuestion
|
|
21
|
+
3. **Auto-detect platform** - Determine Eclipse Che vs Dev Spaces from URL
|
|
22
|
+
4. **Detect local changes** - Check if rebuild is needed based on git status
|
|
23
|
+
5. **Detect test-specific parameters** - Read spec file for required env vars
|
|
24
|
+
6. **Generate bash commands** - Build appropriate bash commands
|
|
25
|
+
7. **Execute** - Run the test after user confirmation
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## ⚠️ MANDATORY RULES
|
|
30
|
+
|
|
31
|
+
1. **Never print bash commands with `&& \` or multi-line continuations using `\`** - Commands using line continuation characters (`\`) or chained with `&& \` cannot be copy-pasted properly from the terminal. Instead, present commands as separate lines or use semicolons for simple chains.
|
|
32
|
+
|
|
33
|
+
❌ **Wrong (line continuations):**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd /path/to/dir && \
|
|
37
|
+
npm ci && \
|
|
38
|
+
npm run test
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
❌ **Wrong (backslash continuations):**
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
podman run -it \
|
|
45
|
+
--shm-size=2g \
|
|
46
|
+
-p 5920:5920 \
|
|
47
|
+
quay.io/eclipse/che-e2e:next
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
✅ **Correct (separate lines):**
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd /path/to/dir
|
|
54
|
+
npm ci
|
|
55
|
+
npm run test
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
✅ **Correct (single line for podman):**
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
podman run -it --shm-size=2g -p 5920:5920 quay.io/eclipse/che-e2e:next
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Step 1: Parse Arguments
|
|
67
|
+
|
|
68
|
+
Parse `$ARGUMENTS` to extract positional parameters:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
$ARGUMENTS = "URL USERNAME PASSWORD [TESTNAME]"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Parsing logic:**
|
|
75
|
+
|
|
76
|
+
1. Split `$ARGUMENTS` by whitespace
|
|
77
|
+
2. Assign to variables: `URL`, `USERNAME`, `PASSWORD`, `TESTNAME`, `RUN_METHOD`
|
|
78
|
+
3. If `TESTNAME` is not provided, default to `EmptyWorkspace`
|
|
79
|
+
|
|
80
|
+
**Example:**
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
Input: "https://devspaces.apps.example.com/ admin secret123 SmokeTest npm"
|
|
84
|
+
Result:
|
|
85
|
+
- URL = "https://devspaces.apps.example.com/"
|
|
86
|
+
- USERNAME = "admin"
|
|
87
|
+
- PASSWORD = "secret123"
|
|
88
|
+
- TESTNAME = "SmokeTest"
|
|
89
|
+
- RUN_METHOD = "npm"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Step 2: Prompt for Missing Values
|
|
95
|
+
|
|
96
|
+
If `$ARGUMENTS` is empty or incomplete, use **AskUserQuestion** to collect missing parameters.
|
|
97
|
+
|
|
98
|
+
### Question 1 - Run Method (header: "Method")
|
|
99
|
+
|
|
100
|
+
- "How do you want to run the test?"
|
|
101
|
+
- Options:
|
|
102
|
+
- Option 1: "npm run in local browser (Recommended)" - "Uses local Chrome and Node.js - faster, see browser in real-time"
|
|
103
|
+
- Option 2: "Podman container" - "Isolated environment with VNC support at localhost:5920"
|
|
104
|
+
|
|
105
|
+
### Question 2 - Execution Mode (header: "Build")
|
|
106
|
+
|
|
107
|
+
- "How should local changes be handled?"
|
|
108
|
+
- Options:
|
|
109
|
+
- Option 1: "Build and run (Recommended)" - "Compare to origin/main, rebuild if any changes exist"
|
|
110
|
+
- Option 2: "Just run" - "Skip build, assume code is already compiled"
|
|
111
|
+
|
|
112
|
+
### Question 3 - Test Name (header: "Test")
|
|
113
|
+
|
|
114
|
+
- "Which test do you want to run?"
|
|
115
|
+
- Options:
|
|
116
|
+
- Option 1: "EmptyWorkspace (Recommended)" - "Basic workspace creation test"
|
|
117
|
+
- Option 2: "SmokeTest" - "Quick validation of core functionality"
|
|
118
|
+
- Option 3: "Factory" - "Factory URL workspace creation with git operations"
|
|
119
|
+
- Option 4: "EmptyWorkspaceAPI" - "API-only test (no browser needed)"
|
|
120
|
+
|
|
121
|
+
### For URL - Ask in plain text:
|
|
122
|
+
|
|
123
|
+
> "What is the dashboard URL? (e.g., https://devspaces.apps.cluster.example.com/ or https://che.apps.cluster.example.com/)"
|
|
124
|
+
|
|
125
|
+
### For Username and Password - Ask in plain text:
|
|
126
|
+
|
|
127
|
+
> "Please provide your credentials:
|
|
128
|
+
>
|
|
129
|
+
> - **Username**: (e.g., admin, user)
|
|
130
|
+
> - **Password**: your password"
|
|
131
|
+
|
|
132
|
+
Wait for the user's response before proceeding.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Step 3: Auto-detect Testing Product from URL
|
|
137
|
+
|
|
138
|
+
Analyze the URL to determine which product is being tested and set appropriate defaults:
|
|
139
|
+
|
|
140
|
+
| URL Pattern | Product | Auto-configured Settings |
|
|
141
|
+
| ---------------------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
142
|
+
| Contains `devspaces` | **Red Hat OpenShift Dev Spaces** | `TS_SELENIUM_VALUE_OPENSHIFT_OAUTH=true`, `TS_OCP_LOGIN_PAGE_PROVIDER_TITLE=htpasswd` `TS_PLATFORM=openshift` |
|
|
143
|
+
| Contains `eclipse-che` | **Eclipse Che** | May need OAuth config based on deployment. I host contains `crw-qe.com` - it is `TS_PLATFORM=openshift`. Otherwise ask user for platform: openshift or kubernetes |
|
|
144
|
+
|
|
145
|
+
**Detection logic:**
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
if [[ "$URL" == *"devspaces"* ]]; then
|
|
149
|
+
PRODUCT="devspaces"
|
|
150
|
+
TS_SELENIUM_VALUE_OPENSHIFT_OAUTH=true
|
|
151
|
+
TS_OCP_LOGIN_PAGE_PROVIDER_TITLE="htpasswd"
|
|
152
|
+
elif [[ "$URL" == *"eclipse-che"* ]]; then
|
|
153
|
+
PRODUCT="che"
|
|
154
|
+
fi
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Step 4: Detect Local Changes
|
|
160
|
+
|
|
161
|
+
Check the git status to determine if code needs to be rebuilt before running tests.
|
|
162
|
+
|
|
163
|
+
**Important:** Ignore changes to documentation and Claude configuration files:
|
|
164
|
+
|
|
165
|
+
- `CLAUDE.md`
|
|
166
|
+
- `.claude/**/*`
|
|
167
|
+
- `*.md` files (documentation)
|
|
168
|
+
|
|
169
|
+
### For Local Browser Method:
|
|
170
|
+
|
|
171
|
+
**Smart rebuild based on all changes vs origin/main** - rebuild when there are any test code modifications compared to origin/main.
|
|
172
|
+
|
|
173
|
+
**Logic:**
|
|
174
|
+
|
|
175
|
+
1. Compare working tree to `origin/main` to detect all changes (committed, staged, and unstaged)
|
|
176
|
+
2. Rebuild if any test code changes exist compared to `origin/main` (excluding docs/config files)
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
NEEDS_REBUILD=false
|
|
180
|
+
|
|
181
|
+
# Get current branch name for informational purposes
|
|
182
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
183
|
+
echo "Current branch: $CURRENT_BRANCH"
|
|
184
|
+
|
|
185
|
+
# Check for any changes compared to origin/main (committed, staged, and unstaged)
|
|
186
|
+
# Excludes docs and Claude config files
|
|
187
|
+
CODE_CHANGES=$(git diff --name-only origin/main -- . 2>/dev/null | grep -v -E '(CLAUDE\.md|\.claude/|README\.md|\.md$)')
|
|
188
|
+
|
|
189
|
+
if [[ -n "$CODE_CHANGES" ]]; then
|
|
190
|
+
echo "Code changes detected compared to origin/main:"
|
|
191
|
+
echo "$CODE_CHANGES"
|
|
192
|
+
NEEDS_REBUILD=true
|
|
193
|
+
else
|
|
194
|
+
echo "No test code changes compared to origin/main - no rebuild needed"
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
echo "Rebuild needed: $NEEDS_REBUILD"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### For Podman Container Method:
|
|
201
|
+
|
|
202
|
+
**Smart mounting based on all changes vs origin/main** - mount full directory when there are any test code modifications compared to origin/main.
|
|
203
|
+
|
|
204
|
+
**Logic:**
|
|
205
|
+
|
|
206
|
+
1. Compare working tree to `origin/main` to detect all changes (committed, staged, and unstaged)
|
|
207
|
+
2. Mount full directory if any test code changes exist compared to `origin/main` (excluding docs/config files)
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
E2E_IMAGE="quay.io/eclipse/che-e2e:next"
|
|
211
|
+
MOUNT_FULL_CODE=false
|
|
212
|
+
|
|
213
|
+
# Get current branch name for informational purposes
|
|
214
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
215
|
+
echo "Current branch: $CURRENT_BRANCH"
|
|
216
|
+
|
|
217
|
+
# Check for any changes compared to origin/main (committed, staged, and unstaged)
|
|
218
|
+
# Excludes docs and Claude config files
|
|
219
|
+
CODE_CHANGES=$(git diff --name-only origin/main -- . 2>/dev/null | grep -v -E '(CLAUDE\.md|\.claude/|README\.md|\.md$)')
|
|
220
|
+
|
|
221
|
+
if [[ -n "$CODE_CHANGES" ]]; then
|
|
222
|
+
echo "Code changes detected compared to origin/main:"
|
|
223
|
+
echo "$CODE_CHANGES"
|
|
224
|
+
MOUNT_FULL_CODE=true
|
|
225
|
+
PODMAN_MOUNT="-v $(pwd):/tmp/e2e:Z"
|
|
226
|
+
else
|
|
227
|
+
echo "No test code changes compared to origin/main - using published image code"
|
|
228
|
+
PODMAN_MOUNT="-v $(pwd)/report:/tmp/e2e/report:Z"
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
echo "Mount strategy: $PODMAN_MOUNT"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Step 5: Detect Test-Specific Parameters
|
|
237
|
+
|
|
238
|
+
After getting the test name, read the test spec file to identify additional required environment variables.
|
|
239
|
+
|
|
240
|
+
### Find and read the spec file:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Find the test file
|
|
244
|
+
SPEC_FILE=$(find specs -name "${USERSTORY}.spec.ts" 2>/dev/null | head -1)
|
|
245
|
+
|
|
246
|
+
if [[ -n "$SPEC_FILE" ]]; then
|
|
247
|
+
echo "Found test file: $SPEC_FILE"
|
|
248
|
+
# Read the file to identify required environment variables
|
|
249
|
+
cat "$SPEC_FILE"
|
|
250
|
+
fi
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Platform-Specific Configurations
|
|
254
|
+
|
|
255
|
+
#### OpenShift
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
export TS_PLATFORM=openshift
|
|
259
|
+
export TS_SELENIUM_VALUE_OPENSHIFT_OAUTH=true
|
|
260
|
+
export TS_OCP_LOGIN_PAGE_PROVIDER_TITLE="htpasswd"
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
#### Kubernetes
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
export TS_PLATFORM=kubernetes
|
|
267
|
+
export TS_SELENIUM_K8S_USERNAME=che@eclipse.org
|
|
268
|
+
export TS_SELENIUM_K8S_PASSWORD=admin
|
|
269
|
+
export TS_SELENIUM_VALUE_OPENSHIFT_OAUTH=false
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Test-specific parameters by category:
|
|
273
|
+
|
|
274
|
+
#### Factory URL Tests (Factory, RefusedOAuthFactory, NoSetupRepoFactory, etc.)
|
|
275
|
+
|
|
276
|
+
These tests navigate directly to a factory URL to create a workspace.
|
|
277
|
+
**Ask for these additional parameters:**
|
|
278
|
+
|
|
279
|
+
- **Git Repository URL** (`TS_SELENIUM_FACTORY_GIT_REPO_URL`) - Repository to clone
|
|
280
|
+
- **Git Provider** (`TS_SELENIUM_FACTORY_GIT_PROVIDER`) - `github`, `gitlab`, `bitbucket`, `azure-devops`
|
|
281
|
+
- **OAuth Enabled** (`TS_SELENIUM_GIT_PROVIDER_OAUTH`) - `true` or `false`
|
|
282
|
+
|
|
283
|
+
#### Git Repo Import Form Tests (FactoryWithGitRepoOptions, CreateWorkspaceWithExistingNameFromGitUrl, etc.)
|
|
284
|
+
|
|
285
|
+
These tests use the Dashboard's "Create Workspace" form.
|
|
286
|
+
**Ask for these additional parameters:**
|
|
287
|
+
|
|
288
|
+
- **Git Repository URL** (`TS_SELENIUM_FACTORY_GIT_REPO_URL`) - Repository URL
|
|
289
|
+
- **Branch Name** (`TS_SELENIUM_FACTORY_GIT_REPO_BRANCH`) - Optional (default: `main`)
|
|
290
|
+
- **Project Name** (`TS_SELENIUM_PROJECT_NAME`) - Optional
|
|
291
|
+
|
|
292
|
+
#### API Tests (EmptyWorkspaceAPI, ContainerOverridesAPI, etc.)
|
|
293
|
+
|
|
294
|
+
**Ask for these additional parameters:**
|
|
295
|
+
|
|
296
|
+
- **Namespace** (`TS_API_TEST_NAMESPACE`) - Optional
|
|
297
|
+
- **UDI Image** (`TS_API_TEST_UDI_IMAGE`) - Optional
|
|
298
|
+
|
|
299
|
+
#### Sample/Devfile Tests
|
|
300
|
+
|
|
301
|
+
**Ask for these additional parameters:**
|
|
302
|
+
|
|
303
|
+
- **Sample List** (`TS_SAMPLE_LIST`) - e.g., `Node.js Express`
|
|
304
|
+
|
|
305
|
+
#### SSH/PAT Tests (SshUrlNoOauthPatFactory, etc.)
|
|
306
|
+
|
|
307
|
+
**Ask for these additional parameters:**
|
|
308
|
+
|
|
309
|
+
- **SSH Private Key Path** or **Personal Access Token** details
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Step 6: Generate Bash Commands
|
|
314
|
+
|
|
315
|
+
Based on all collected parameters, generate the appropriate bash commands.
|
|
316
|
+
|
|
317
|
+
### Option A: Local Browser Commands
|
|
318
|
+
|
|
319
|
+
#### Browser/ChromeDriver Compatibility Check
|
|
320
|
+
|
|
321
|
+
Before running tests, verify ChromeDriver compatibility with local Chrome browser:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
# Get local Chrome version
|
|
325
|
+
CHROME_VERSION=$(google-chrome --version 2>/dev/null | grep -oP '\d+' | head -1)
|
|
326
|
+
echo "Local Chrome major version: $CHROME_VERSION"
|
|
327
|
+
|
|
328
|
+
# Get ChromeDriver version from package.json
|
|
329
|
+
CHROMEDRIVER_VERSION=$(npm list chromedriver --depth=0 2>/dev/null | grep -oP 'chromedriver@\K[\d.]+')
|
|
330
|
+
echo "ChromeDriver version in package.json: $CHROMEDRIVER_VERSION"
|
|
331
|
+
|
|
332
|
+
# If versions don't match, suggest installing compatible driver
|
|
333
|
+
if [[ "${CHROMEDRIVER_VERSION%%.*}" != "$CHROME_VERSION" ]]; then
|
|
334
|
+
echo "WARNING: ChromeDriver version mismatch!"
|
|
335
|
+
echo "Install compatible version: npm install chromedriver@$CHROME_VERSION"
|
|
336
|
+
fi
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**If ChromeDriver is incompatible**, install a matching version:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
npm install chromedriver@<chrome-major-version>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### Full Test Run (Build and Run)
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
cd tests/e2e
|
|
349
|
+
|
|
350
|
+
# Use correct Node.js version
|
|
351
|
+
nvm use v22.10.0
|
|
352
|
+
|
|
353
|
+
# Get current branch name for informational purposes
|
|
354
|
+
CURRENT_BRANCH=$(git branch --show-current)
|
|
355
|
+
echo "Current branch: $CURRENT_BRANCH"
|
|
356
|
+
|
|
357
|
+
# Check for any changes compared to origin/main (committed, staged, and unstaged)
|
|
358
|
+
# Excludes docs and Claude config files
|
|
359
|
+
CODE_CHANGES=$(git diff --name-only origin/main -- . 2>/dev/null | grep -v -E '(CLAUDE\.md|\.claude/|README\.md|\.md$)')
|
|
360
|
+
|
|
361
|
+
if [[ -n "$CODE_CHANGES" ]]; then
|
|
362
|
+
echo "Code changes detected compared to origin/main:"
|
|
363
|
+
echo "$CODE_CHANGES"
|
|
364
|
+
NEEDS_REBUILD=true
|
|
365
|
+
else
|
|
366
|
+
echo "No test code changes compared to origin/main - skipping rebuild"
|
|
367
|
+
NEEDS_REBUILD=false
|
|
368
|
+
fi
|
|
369
|
+
|
|
370
|
+
# Check if package.json was modified compared to origin/main
|
|
371
|
+
PACKAGE_JSON_CHANGED=$(git diff --name-only origin/main -- package.json 2>/dev/null)
|
|
372
|
+
|
|
373
|
+
# Rebuild if changes detected compared to origin/main
|
|
374
|
+
if [[ "$NEEDS_REBUILD" == "true" ]]; then
|
|
375
|
+
echo "Rebuilding TypeScript..."
|
|
376
|
+
rm -rf node_modules dist
|
|
377
|
+
|
|
378
|
+
# Use npm install if package.json changed, otherwise npm ci
|
|
379
|
+
if [[ -n "$PACKAGE_JSON_CHANGED" ]]; then
|
|
380
|
+
echo "package.json modified - using npm install to update package-lock.json"
|
|
381
|
+
npm install
|
|
382
|
+
else
|
|
383
|
+
npm ci
|
|
384
|
+
fi
|
|
385
|
+
|
|
386
|
+
npm run lint
|
|
387
|
+
npm run prettier
|
|
388
|
+
npm run tsc
|
|
389
|
+
fi
|
|
390
|
+
|
|
391
|
+
# Set environment variables
|
|
392
|
+
export TS_SELENIUM_BASE_URL="<URL>"
|
|
393
|
+
export TS_SELENIUM_OCP_USERNAME="<USERNAME>"
|
|
394
|
+
export TS_SELENIUM_OCP_PASSWORD="<PASSWORD>"
|
|
395
|
+
export USERSTORY="<TESTNAME>"
|
|
396
|
+
export TS_SELENIUM_VALUE_OPENSHIFT_OAUTH=true
|
|
397
|
+
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
398
|
+
|
|
399
|
+
# Run the test
|
|
400
|
+
npm run test
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
#### API-Only Tests (No Browser)
|
|
404
|
+
|
|
405
|
+
```bash
|
|
406
|
+
export USERSTORY=EmptyWorkspaceAPI
|
|
407
|
+
npm run driver-less-test
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Option B: Podman Container Commands
|
|
411
|
+
|
|
412
|
+
**Important:** Use `--env-host` to pass all exported environment variables from the host to the container.
|
|
413
|
+
|
|
414
|
+
**Smart mounting logic based on changes vs origin/main:**
|
|
415
|
+
|
|
416
|
+
- **Changes compared to origin/main**: Mount full directory `-v $(pwd):/tmp/e2e:Z` to test local code
|
|
417
|
+
- **No changes compared to origin/main**: Mount only report directory `-v $(pwd)/report:/tmp/e2e/report:Z`
|
|
418
|
+
|
|
419
|
+
#### With Test Code Changes vs origin/main (mount full directory):
|
|
420
|
+
|
|
421
|
+
Use this when there are test code changes compared to `origin/main` (works for feature branches or local main with unpushed changes).
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
cd tests/e2e
|
|
425
|
+
|
|
426
|
+
# Set environment variables
|
|
427
|
+
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
428
|
+
export TS_SELENIUM_BASE_URL=<URL>
|
|
429
|
+
export TS_SELENIUM_OCP_USERNAME=<USERNAME>
|
|
430
|
+
export TS_SELENIUM_OCP_PASSWORD=<PASSWORD>
|
|
431
|
+
export USERSTORY=<TESTNAME>
|
|
432
|
+
|
|
433
|
+
# Run with full local code mounted (testing changes vs origin/main)
|
|
434
|
+
podman rm -f selenium-e2e 2>/dev/null
|
|
435
|
+
podman run -it --shm-size=2g -p 5920:5920 --env-host -v $(pwd):/tmp/e2e:Z quay.io/eclipse/che-e2e:next
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### No Test Code Changes vs origin/main (mount only report directory):
|
|
439
|
+
|
|
440
|
+
```bash
|
|
441
|
+
cd tests/e2e
|
|
442
|
+
|
|
443
|
+
# Set environment variables
|
|
444
|
+
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
445
|
+
export TS_SELENIUM_BASE_URL=<URL>
|
|
446
|
+
export TS_SELENIUM_OCP_USERNAME=<USERNAME>
|
|
447
|
+
export TS_SELENIUM_OCP_PASSWORD=<PASSWORD>
|
|
448
|
+
export USERSTORY=<TESTNAME>
|
|
449
|
+
|
|
450
|
+
# Run with only report directory mounted (no changes vs origin/main, uses published image code)
|
|
451
|
+
podman rm -f selenium-e2e 2>/dev/null
|
|
452
|
+
podman run -it --shm-size=2g -p 5920:5920 --env-host -v $(pwd)/report:/tmp/e2e/report:Z quay.io/eclipse/che-e2e:next
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## Step 7: Execute After User Confirmation
|
|
458
|
+
|
|
459
|
+
Before executing, present the generated command(s) to the user and ask for confirmation.
|
|
460
|
+
|
|
461
|
+
### Confirmation prompt:
|
|
462
|
+
|
|
463
|
+
> "Here is the command I will run:
|
|
464
|
+
>
|
|
465
|
+
> ```bash
|
|
466
|
+
> <generated command>
|
|
467
|
+
> ```
|
|
468
|
+
>
|
|
469
|
+
> **Summary:**
|
|
470
|
+
>
|
|
471
|
+
> - **Platform:** [OpenShift/Kubernetes]
|
|
472
|
+
> - **Product:** [Eclipse Che/Dev Spaces]
|
|
473
|
+
> - **Test:** [TESTNAME]
|
|
474
|
+
> - **Method:** [Local browser/Podman container]
|
|
475
|
+
> - **URL:** [URL]
|
|
476
|
+
>
|
|
477
|
+
> Shall I proceed?"
|
|
478
|
+
|
|
479
|
+
### After confirmation:
|
|
480
|
+
|
|
481
|
+
1. Execute the bash command(s)
|
|
482
|
+
2. Monitor the output
|
|
483
|
+
3. Report success or failure
|
|
484
|
+
4. If using Podman, remind user about VNC access at `localhost:5920`
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
## Debugging Options
|
|
489
|
+
|
|
490
|
+
### Verbose Logging
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
export TS_SELENIUM_LOG_LEVEL=TRACE
|
|
494
|
+
export TS_SELENIUM_PRINT_TIMEOUT_VARIABLES=true
|
|
495
|
+
export TS_DEBUG_MODE=true
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Headless Mode (CI)
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
export TS_SELENIUM_HEADLESS=true
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Video Recording
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
export VIDEO_RECORDING=true
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Keep Workspace on Failure
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
export TS_DELETE_WORKSPACE_ON_FAILED_TEST=false
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## VNC Access for Visual Debugging (Podman only)
|
|
519
|
+
|
|
520
|
+
Connect to VNC at `localhost:5920` to watch tests running in the container.
|
|
521
|
+
|
|
522
|
+
**VNC clients:**
|
|
523
|
+
|
|
524
|
+
- **TigerVNC** (recommended): `sudo dnf install tigervnc` then `vncviewer localhost:5920`
|
|
525
|
+
- **Remmina**: `sudo dnf install remmina remmina-plugins-vnc` (GUI-based)
|
|
526
|
+
- **Vinagre**: `sudo dnf install vinagre` then `vinagre localhost:5920`
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## View Test Reports
|
|
531
|
+
|
|
532
|
+
After test execution:
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
npm run open-allure-dasboard
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## Troubleshooting
|
|
541
|
+
|
|
542
|
+
### Certificate Errors
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Slow Workspace Start
|
|
549
|
+
|
|
550
|
+
```bash
|
|
551
|
+
export TS_SELENIUM_START_WORKSPACE_TIMEOUT=600000
|
|
552
|
+
export TS_SELENIUM_DEFAULT_ATTEMPTS=3
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### OAuth Login Issues
|
|
556
|
+
|
|
557
|
+
Verify the login provider title matches exactly what appears on the login page:
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
export TS_OCP_LOGIN_PAGE_PROVIDER_TITLE="htpasswd"
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Container Cleanup
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
podman rm -f selenium-e2e
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## Debugging TypeScript Tests in VS Code
|
|
572
|
+
|
|
573
|
+
For debugging E2E tests with breakpoints, see: https://code.visualstudio.com/docs/typescript/typescript-debugging
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: e2e-test-developer
|
|
3
|
+
description: Comprehensive E2E test development guidance for Eclipse Che / Red Hat OpenShift Dev Spaces. Use this skill when writing, modifying, or reviewing TypeScript Mocha Selenium tests, page objects, utilities, or test infrastructure. Provides code style rules, patterns, dependency injection setup, and best practices.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Eclipse Che E2E TypeScript Mocha Selenium Test Development Skill
|
|
7
|
+
|
|
8
|
+
You are a Software Quality Engineer, who is an expert developer for Eclipse Che / Red Hat OpenShift Dev Spaces E2E tests. This skill provides comprehensive guidance for developing and maintaining E2E TypeScript Mocha Selenium tests.
|
|
9
|
+
|
|
10
|
+
## Project Overview
|
|
11
|
+
|
|
12
|
+
This is the E2E test suite for Eclipse Che / Red Hat OpenShift Dev Spaces. It uses:
|
|
13
|
+
|
|
14
|
+
- **Selenium WebDriver** with Chrome browser
|
|
15
|
+
- **Mocha** (TDD style - `suite()`, `test()`, `suiteSetup()`, `suiteTeardown()`)
|
|
16
|
+
- **TypeScript** with strict type checking
|
|
17
|
+
- **Inversify** for dependency injection
|
|
18
|
+
- **Chai** for assertions
|
|
19
|
+
- **Allure** for test reporting
|
|
20
|
+
|
|
21
|
+
## Directory Structure
|
|
22
|
+
|
|
23
|
+
| Directory | Purpose |
|
|
24
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| `specs/` | Test specifications organized by category (api/, factory/, dashboard-samples/, miscellaneous/) |
|
|
26
|
+
| `pageobjects/` | Page Object classes for UI elements (dashboard/, ide/, login/, openshift/, git-providers/, webterminal/) |
|
|
27
|
+
| `utils/` | Utilities (DriverHelper, BrowserTabsUtil, Logger, API handlers, KubernetesCommandLineToolsExecutor) |
|
|
28
|
+
| `tests-library/` | Reusable test helpers (WorkspaceHandlingTests, LoginTests, ProjectAndFileTests) |
|
|
29
|
+
| `constants/` | Environment variable mappings (BASE_TEST_CONSTANTS, TIMEOUT_CONSTANTS, FACTORY_TEST_CONSTANTS, etc.) |
|
|
30
|
+
| `configs/` | Mocha config, Inversify container (inversify.config.ts), shell scripts |
|
|
31
|
+
| `suites/` | Test suite configurations for different environments |
|
|
32
|
+
| `driver/` | Chrome driver configuration |
|
|
33
|
+
| `build/dockerfiles/` | Docker image for running tests |
|
|
34
|
+
|
|
35
|
+
## Essential Commands
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Install dependencies
|
|
39
|
+
npm ci
|
|
40
|
+
|
|
41
|
+
# Lint and format
|
|
42
|
+
npm run lint
|
|
43
|
+
npm run prettier
|
|
44
|
+
|
|
45
|
+
# Build TypeScript only
|
|
46
|
+
npm run tsc
|
|
47
|
+
|
|
48
|
+
# Run all tests (requires environment variables)
|
|
49
|
+
export TS_SELENIUM_BASE_URL=<che-url>
|
|
50
|
+
export TS_SELENIUM_OCP_USERNAME=<username>
|
|
51
|
+
export TS_SELENIUM_OCP_PASSWORD=<password>
|
|
52
|
+
npm run test
|
|
53
|
+
|
|
54
|
+
# Run a single test file (without .spec.ts extension)
|
|
55
|
+
export USERSTORY=SmokeTest
|
|
56
|
+
npm run test
|
|
57
|
+
|
|
58
|
+
# Run API-only tests (no browser)
|
|
59
|
+
export USERSTORY=EmptyWorkspaceAPI
|
|
60
|
+
npm run driver-less-test
|
|
61
|
+
|
|
62
|
+
# View Allure test report
|
|
63
|
+
npm run open-allure-dasboard
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## CODE STYLE REQUIREMENTS (CRITICAL)
|
|
67
|
+
|
|
68
|
+
### File Header (Required for ALL .ts files)
|
|
69
|
+
|
|
70
|
+
Every TypeScript file MUST start with this exact header:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
/** *******************************************************************
|
|
74
|
+
* copyright (c) 2026 Red Hat, Inc.
|
|
75
|
+
*
|
|
76
|
+
* This program and the accompanying materials are made
|
|
77
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
78
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
79
|
+
*
|
|
80
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
81
|
+
**********************************************************************/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Page Object and Utility Classes
|
|
85
|
+
|
|
86
|
+
1. **Class Declaration with Dependency Injection**
|
|
87
|
+
- Use `@injectable()` decorator on ALL page objects and utilities
|
|
88
|
+
- Use constructor injection with `@inject()` decorators
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { inject, injectable } from 'inversify';
|
|
92
|
+
import 'reflect-metadata';
|
|
93
|
+
import { CLASSES } from '../../configs/inversify.types';
|
|
94
|
+
|
|
95
|
+
@injectable()
|
|
96
|
+
export class MyPageObject {
|
|
97
|
+
constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
2. **Public Methods**
|
|
102
|
+
- Declare public methods WITHOUT the `public` keyword
|
|
103
|
+
- Add `Logger.debug()` at the START of every public method
|
|
104
|
+
- Always specify explicit return types
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
async clickButton(timeout: number = TIMEOUT_CONSTANTS.TS_CLICK_DASHBOARD_ITEM_TIMEOUT): Promise<void> {
|
|
108
|
+
Logger.debug();
|
|
109
|
+
await this.driverHelper.waitAndClick(MyPage.BUTTON_LOCATOR, timeout);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
3. **Locators**
|
|
114
|
+
- Static locators: `private static readonly` fields of type `By`
|
|
115
|
+
- Dynamic locators: `private` methods that return `By`
|
|
116
|
+
- NEVER declare locators as constants inside methods
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// Static locators (correct)
|
|
120
|
+
private static readonly SUBMIT_BUTTON: By = By.xpath('//button[@type="submit"]');
|
|
121
|
+
private static readonly INPUT_FIELD: By = By.id('input-field');
|
|
122
|
+
|
|
123
|
+
// Dynamic locators (correct)
|
|
124
|
+
private getItemLocator(itemName: string): By {
|
|
125
|
+
return By.xpath(`//div[text()="${itemName}"]`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// WRONG - Never do this inside a method
|
|
129
|
+
async wrongMethod(): Promise<void> {
|
|
130
|
+
const locator: By = By.xpath('//button'); // AVOID THIS
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Member Ordering (Enforced by ESLint)
|
|
135
|
+
|
|
136
|
+
Classes must follow this order:
|
|
137
|
+
|
|
138
|
+
1. Static fields
|
|
139
|
+
2. Public fields
|
|
140
|
+
3. Instance fields
|
|
141
|
+
4. Protected fields
|
|
142
|
+
5. Private fields
|
|
143
|
+
6. Abstract fields
|
|
144
|
+
7. Constructor
|
|
145
|
+
8. Public static methods
|
|
146
|
+
9. Protected static methods
|
|
147
|
+
10. Private static methods
|
|
148
|
+
11. Public methods
|
|
149
|
+
12. Protected methods
|
|
150
|
+
13. Private methods
|
|
151
|
+
|
|
152
|
+
### Test File Conventions
|
|
153
|
+
|
|
154
|
+
1. **Naming**
|
|
155
|
+
|
|
156
|
+
- UI tests: `*.spec.ts` (e.g., `Factory.spec.ts`)
|
|
157
|
+
- API-only tests: `*API.spec.ts` (e.g., `EmptyWorkspaceAPI.spec.ts`)
|
|
158
|
+
|
|
159
|
+
2. **Mocha TDD Style (Required)**
|
|
160
|
+
- Use `suite()`, `test()`, `suiteSetup()`, `suiteTeardown()`
|
|
161
|
+
- NEVER use arrow functions in test declarations (Mocha context issue)
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
suite('My Test Suite', function (): void {
|
|
165
|
+
// Inject dependencies inside suite() to avoid unnecessary execution
|
|
166
|
+
const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
|
|
167
|
+
const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
|
|
168
|
+
|
|
169
|
+
suiteSetup('Login to application', async function (): Promise<void> {
|
|
170
|
+
await loginTests.loginIntoChe();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('Verify dashboard is visible', async function (): Promise<void> {
|
|
174
|
+
await dashboard.waitPage();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
suiteTeardown('Cleanup', async function (): Promise<void> {
|
|
178
|
+
// cleanup code
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
3. **Dependency Injection in Tests**
|
|
184
|
+
- Import container: `import { e2eContainer } from '../../configs/inversify.config';`
|
|
185
|
+
- Import types: `import { CLASSES, TYPES } from '../../configs/inversify.types';`
|
|
186
|
+
- Get instances inside suite() function
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
import { e2eContainer } from '../../configs/inversify.config';
|
|
190
|
+
import { CLASSES, TYPES } from '../../configs/inversify.types';
|
|
191
|
+
|
|
192
|
+
suite('Test Suite', function (): void {
|
|
193
|
+
const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
|
|
194
|
+
const testWorkspaceUtil: ITestWorkspaceUtil = e2eContainer.get(TYPES.WorkspaceUtil);
|
|
195
|
+
// ... test implementation
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### TypeScript Requirements
|
|
200
|
+
|
|
201
|
+
1. **Explicit Type Annotations Required**
|
|
202
|
+
- All parameters must have type annotations
|
|
203
|
+
- All property declarations must have type annotations
|
|
204
|
+
- All variable declarations must have type annotations
|
|
205
|
+
- All functions must have explicit return types
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
// Correct
|
|
209
|
+
async function doSomething(param: string, timeout: number): Promise<void> {
|
|
210
|
+
const result: string = await someOperation();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Wrong - missing types
|
|
214
|
+
async function doSomething(param, timeout) {
|
|
215
|
+
const result = await someOperation();
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
2. **Naming Conventions**
|
|
220
|
+
|
|
221
|
+
- Variables: camelCase or UPPER_CASE
|
|
222
|
+
- No leading/trailing underscores
|
|
223
|
+
|
|
224
|
+
3. **String Quotes**
|
|
225
|
+
|
|
226
|
+
- Use single quotes for strings
|
|
227
|
+
|
|
228
|
+
4. **Comments**
|
|
229
|
+
- Comments must start with lowercase (capitalized-comments: never)
|
|
230
|
+
- Mark workarounds with `// todo` and issue number: `// todo commented due to issue crw-1010`
|
|
231
|
+
|
|
232
|
+
### Prettier and ESLint
|
|
233
|
+
|
|
234
|
+
- Pre-commit hooks run automatically via Husky
|
|
235
|
+
- Run `npm run prettier` to fix formatting
|
|
236
|
+
- Run `npm run lint` to fix linting issues
|
|
237
|
+
|
|
238
|
+
## Environment Variables
|
|
239
|
+
|
|
240
|
+
Core variables (defined in `constants/` directory):
|
|
241
|
+
|
|
242
|
+
| Variable | Description |
|
|
243
|
+
| ------------------------------------- | -------------------------------------------- |
|
|
244
|
+
| `TS_SELENIUM_BASE_URL` | Che/DevSpaces dashboard URL |
|
|
245
|
+
| `TS_SELENIUM_OCP_USERNAME` | OpenShift username |
|
|
246
|
+
| `TS_SELENIUM_OCP_PASSWORD` | OpenShift password |
|
|
247
|
+
| `USERSTORY` | Specific test file to run (without .spec.ts) |
|
|
248
|
+
| `TS_PLATFORM` | `openshift` (default) or `kubernetes` |
|
|
249
|
+
| `TS_SELENIUM_FACTORY_GIT_REPO_URL` | Git repo for factory tests |
|
|
250
|
+
| `TS_SELENIUM_VALUE_OPENSHIFT_OAUTH` | Enable OAuth (true/false) |
|
|
251
|
+
| `TS_SELENIUM_LOG_LEVEL` | Logging level (TRACE, DEBUG, INFO, etc.) |
|
|
252
|
+
| `DELETE_WORKSPACE_ON_SUCCESSFUL_TEST` | Delete workspace on success |
|
|
253
|
+
|
|
254
|
+
## Adding New Page Objects
|
|
255
|
+
|
|
256
|
+
1. Create file in appropriate `pageobjects/` subdirectory
|
|
257
|
+
2. Add `@injectable()` decorator
|
|
258
|
+
3. Register in `configs/inversify.config.ts`
|
|
259
|
+
4. Add class identifier in `configs/inversify.types.ts`
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// 1. Create pageobjects/dashboard/NewPage.ts
|
|
263
|
+
@injectable()
|
|
264
|
+
export class NewPage {
|
|
265
|
+
private static readonly ELEMENT_LOCATOR: By = By.id('element');
|
|
266
|
+
|
|
267
|
+
constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
|
|
268
|
+
|
|
269
|
+
async waitForElement(): Promise<void> {
|
|
270
|
+
Logger.debug();
|
|
271
|
+
await this.driverHelper.waitVisibility(NewPage.ELEMENT_LOCATOR);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// 2. Add to configs/inversify.types.ts
|
|
276
|
+
const CLASSES: any = {
|
|
277
|
+
// ... existing classes
|
|
278
|
+
NewPage: 'NewPage'
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// 3. Add to configs/inversify.config.ts
|
|
282
|
+
import { NewPage } from '../pageobjects/dashboard/NewPage';
|
|
283
|
+
e2eContainer.bind<NewPage>(CLASSES.NewPage).to(NewPage);
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Adding New Tests
|
|
287
|
+
|
|
288
|
+
1. Create file in appropriate `specs/` subdirectory
|
|
289
|
+
2. Follow naming convention (*.spec.ts for UI, *API.spec.ts for API)
|
|
290
|
+
3. Use TDD style (suite, test, suiteSetup, suiteTeardown)
|
|
291
|
+
4. Run with `export USERSTORY=<filename-without-extension> && npm run test`
|
|
292
|
+
|
|
293
|
+
## Common Utilities
|
|
294
|
+
|
|
295
|
+
### DriverHelper (utils/DriverHelper.ts)
|
|
296
|
+
|
|
297
|
+
- `waitVisibility(locator, timeout)` - Wait for element to be visible
|
|
298
|
+
- `waitAndClick(locator, timeout)` - Wait and click element
|
|
299
|
+
- `waitAndGetText(locator, timeout)` - Wait and get text
|
|
300
|
+
- `waitDisappearance(locator, timeout)` - Wait for element to disappear
|
|
301
|
+
- `navigateToUrl(url)` - Navigate to URL
|
|
302
|
+
- `wait(ms)` - Wait for specified milliseconds
|
|
303
|
+
|
|
304
|
+
### BrowserTabsUtil (utils/BrowserTabsUtil.ts)
|
|
305
|
+
|
|
306
|
+
- `navigateTo(url)` - Navigate to URL
|
|
307
|
+
- `getCurrentUrl()` - Get current URL
|
|
308
|
+
- `maximize()` - Maximize browser window
|
|
309
|
+
- `closeAllTabsExceptCurrent()` - Close extra tabs
|
|
310
|
+
|
|
311
|
+
### Logger (utils/Logger.ts)
|
|
312
|
+
|
|
313
|
+
- `Logger.debug()` - Log method name (use at start of public methods)
|
|
314
|
+
- `Logger.info(message)` - Log info message
|
|
315
|
+
- `Logger.error(message)` - Log error message
|
|
316
|
+
|
|
317
|
+
## GitHub Actions Maintenance
|
|
318
|
+
|
|
319
|
+
### PR Check Workflow (.github/workflows/pr-check.yml)
|
|
320
|
+
|
|
321
|
+
Triggers on:
|
|
322
|
+
|
|
323
|
+
- Pull requests to main or 7.\*\*.x branches
|
|
324
|
+
- Changes in `tests/e2e/**` or the workflow file
|
|
325
|
+
|
|
326
|
+
Steps performed:
|
|
327
|
+
|
|
328
|
+
1. Prettier check - Fails if formatting issues found
|
|
329
|
+
2. TypeScript compilation - `npm run tsc`
|
|
330
|
+
3. ESLint check - `npm run lint`
|
|
331
|
+
4. Deploy Che on minikube
|
|
332
|
+
5. Run Empty Workspace API test
|
|
333
|
+
6. Build E2E Docker image
|
|
334
|
+
7. Run Empty Workspace UI test
|
|
335
|
+
|
|
336
|
+
When modifying tests:
|
|
337
|
+
|
|
338
|
+
- Ensure `npm run prettier` passes locally
|
|
339
|
+
- Ensure `npm run tsc` compiles without errors
|
|
340
|
+
- Ensure `npm run lint` passes
|
|
341
|
+
- Test locally if possible before pushing
|
|
342
|
+
|
|
343
|
+
## Test Patterns
|
|
344
|
+
|
|
345
|
+
### Workspace Lifecycle Pattern
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
suite('Workspace Test', function (): void {
|
|
349
|
+
const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
|
|
350
|
+
const testWorkspaceUtil: ITestWorkspaceUtil = e2eContainer.get(TYPES.WorkspaceUtil);
|
|
351
|
+
const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
|
|
352
|
+
|
|
353
|
+
suiteSetup('Login', async function (): Promise<void> {
|
|
354
|
+
await loginTests.loginIntoChe();
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test('Create workspace', async function (): Promise<void> {
|
|
358
|
+
await workspaceHandlingTests.createAndStartWorkspace();
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test('Obtain workspace name', async function (): Promise<void> {
|
|
362
|
+
await workspaceHandlingTests.obtainWorkspaceNameFromStartingPage();
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test('Register running workspace', function (): void {
|
|
366
|
+
registerRunningWorkspace(WorkspaceHandlingTests.getWorkspaceName());
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
suiteTeardown('Stop and delete workspace', async function (): Promise<void> {
|
|
370
|
+
await testWorkspaceUtil.stopAndDeleteWorkspaceByName(WorkspaceHandlingTests.getWorkspaceName());
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### API Test Pattern (No Browser)
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
suite('API Test', function (): void {
|
|
379
|
+
const kubernetesCommandLineToolsExecutor: KubernetesCommandLineToolsExecutor = e2eContainer.get(
|
|
380
|
+
CLASSES.KubernetesCommandLineToolsExecutor
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
suiteSetup('Setup', async function (): Promise<void> {
|
|
384
|
+
kubernetesCommandLineToolsExecutor.loginToOcp();
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
test('Execute API operation', function (): void {
|
|
388
|
+
const output: ShellString = kubernetesCommandLineToolsExecutor.applyAndWaitDevWorkspace(yaml);
|
|
389
|
+
expect(output.stdout).contains('condition met');
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
suiteTeardown('Cleanup', function (): void {
|
|
393
|
+
kubernetesCommandLineToolsExecutor.deleteDevWorkspace();
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
## Package Management
|
|
399
|
+
|
|
400
|
+
- Add packages as **dev dependencies**: `npm install --save-dev <package>`
|
|
401
|
+
- After any changes to package.json, regenerate lock file: `npm install`
|
|
402
|
+
- Run `npm ci` for clean install from lock file
|
|
403
|
+
|
|
404
|
+
## Debugging
|
|
405
|
+
|
|
406
|
+
- Set `TS_SELENIUM_LOG_LEVEL=TRACE` for verbose logging
|
|
407
|
+
- Use VNC on port 5920 when running in Docker
|
|
408
|
+
- View test results with `npm run open-allure-dasboard`
|
|
409
|
+
- Screenshots are captured on test failures by CheReporter
|
|
410
|
+
|
|
411
|
+
## Common Issues and Solutions
|
|
412
|
+
|
|
413
|
+
1. **Flaky Tests**: Increase timeout or add explicit waits with `DriverHelper.wait()`
|
|
414
|
+
2. **Element Not Found**: Verify locator with browser dev tools, check for dynamic loading
|
|
415
|
+
3. **Stale Element**: Re-fetch element after page navigation
|
|
416
|
+
4. **Timeout Errors**: Use appropriate timeout constants from `TIMEOUT_CONSTANTS`
|
|
417
|
+
|
|
418
|
+
## Maintenance Guidelines
|
|
419
|
+
|
|
420
|
+
When helping with E2E test development and maintenance:
|
|
421
|
+
|
|
422
|
+
1. **Keep command files up to date** - When test infrastructure changes (new environment variables, test patterns, or execution methods), update the command file `.claude/commands/run-e2e-test.md`.
|
|
423
|
+
|
|
424
|
+
2. **Review test-specific parameters** - When adding or modifying tests that require new environment variables, update the "Test-Specific Parameters" section in the command files.
|
|
425
|
+
|
|
426
|
+
3. **Validate examples** - Ensure code examples and commands in documentation match current implementation patterns.
|
|
427
|
+
|
|
428
|
+
4. **Check for deprecated patterns** - When refactoring, search for outdated patterns across both test code and documentation.
|
|
429
|
+
|
|
430
|
+
5. **Update inversify configuration** - When adding new page objects or utilities, ensure both `inversify.types.ts` and `inversify.config.ts` are updated.
|
|
431
|
+
|
|
432
|
+
## Related Commands
|
|
433
|
+
|
|
434
|
+
### `/run-e2e-test` - Unified E2E Test Runner
|
|
435
|
+
|
|
436
|
+
Run E2E tests against **Eclipse Che** or **Red Hat OpenShift Dev Spaces** using either a **local Chrome browser** or **Podman container**.
|
|
437
|
+
|
|
438
|
+
**Usage:** `/run-e2e-test [URL USERNAME PASSWORD [TESTNAME] [METHOD]]`
|
|
439
|
+
|
|
440
|
+
**Features:**
|
|
441
|
+
|
|
442
|
+
- **Interactive mode**: Run without arguments to be prompted for all parameters
|
|
443
|
+
- **Auto-detect platform**: Determines Eclipse Che vs Dev Spaces from URL
|
|
444
|
+
- **Smart rebuild**: Detects local code changes vs `origin/main` and rebuilds only when needed
|
|
445
|
+
- **Test-specific parameters**: Prompts for additional env vars based on selected test type
|
|
446
|
+
|
|
447
|
+
**Examples:**
|
|
448
|
+
|
|
449
|
+
- `/run-e2e-test` - Interactive mode (recommended)
|
|
450
|
+
- `/run-e2e-test https://devspaces.apps.example.com/ admin password SmokeTest npm`
|
|
451
|
+
- `/run-e2e-test https://che.apps.example.com/ admin password EmptyWorkspace podman`
|
|
452
|
+
|
|
453
|
+
**Run methods:**
|
|
454
|
+
|
|
455
|
+
- `npm` - Local Chrome browser (faster, see browser in real-time)
|
|
456
|
+
- `podman` - Isolated container with VNC support at `localhost:5920`
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
**Available skills:**
|
|
6
|
+
|
|
7
|
+
- `/e2e-test-developer` - Comprehensive E2E test development guidance (code style, patterns, architecture)
|
|
8
|
+
|
|
9
|
+
**Available custom commands:**
|
|
10
|
+
|
|
11
|
+
- `/run-e2e-test` - Run E2E tests against Eclipse Che or Red Hat OpenShift Dev Spaces using local browser or Podman container
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
This is the E2E test suite for Eclipse Che / Red Hat OpenShift Dev Spaces. It uses Selenium WebDriver with Chrome, Mocha (TDD style), and TypeScript to test workspace creation, IDE functionality, and platform integrations.
|
|
16
|
+
|
|
17
|
+
## Quick Reference
|
|
18
|
+
|
|
19
|
+
### Essential Commands
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm ci # Install dependencies
|
|
23
|
+
npm run test # Run all tests
|
|
24
|
+
npm run lint # Fix linting issues
|
|
25
|
+
npm run prettier # Fix formatting
|
|
26
|
+
npm run tsc # Compile TypeScript
|
|
27
|
+
export USERSTORY=TestName && npm run test # Run single test
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Key Files to Read
|
|
31
|
+
|
|
32
|
+
- `CODE_STYLE.md` - **CRITICAL**: Coding standards (read before writing any code)
|
|
33
|
+
- `README.md` - Setup and launch instructions
|
|
34
|
+
- `configs/inversify.config.ts` - Dependency injection container
|
|
35
|
+
- `configs/inversify.types.ts` - Class and type identifiers
|
|
36
|
+
- `constants/TIMEOUT_CONSTANTS.ts` - Timeout values for waits
|
|
37
|
+
|
|
38
|
+
## Code Style Requirements (CRITICAL)
|
|
39
|
+
|
|
40
|
+
**Always read `CODE_STYLE.md` before modifying code.**
|
|
41
|
+
|
|
42
|
+
### Required File Header
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
/** *******************************************************************
|
|
46
|
+
* copyright (c) 2023 Red Hat, Inc.
|
|
47
|
+
*
|
|
48
|
+
* This program and the accompanying materials are made
|
|
49
|
+
* available under the terms of the Eclipse Public License 2.0
|
|
50
|
+
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
51
|
+
*
|
|
52
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
53
|
+
**********************************************************************/
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Page Object Pattern
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
@injectable()
|
|
60
|
+
export class MyPage {
|
|
61
|
+
private static readonly BUTTON: By = By.xpath('//button');
|
|
62
|
+
|
|
63
|
+
constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
|
|
64
|
+
|
|
65
|
+
async clickButton(): Promise<void> {
|
|
66
|
+
Logger.debug();
|
|
67
|
+
await this.driverHelper.waitAndClick(MyPage.BUTTON);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private getDynamicLocator(name: string): By {
|
|
71
|
+
return By.xpath(`//div[text()="${name}"]`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Test Structure (TDD Style - No Arrow Functions)
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
suite('Suite Name', function (): void {
|
|
80
|
+
const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
|
|
81
|
+
|
|
82
|
+
suiteSetup('Setup', async function (): Promise<void> {
|
|
83
|
+
// setup code
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('Test case', async function (): Promise<void> {
|
|
87
|
+
// test code
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
suiteTeardown('Cleanup', async function (): Promise<void> {
|
|
91
|
+
// cleanup code
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Key Rules
|
|
97
|
+
|
|
98
|
+
- `@injectable()` on all page objects and utilities
|
|
99
|
+
- `Logger.debug()` at start of every public method
|
|
100
|
+
- Static locators: `private static readonly NAME: By`
|
|
101
|
+
- Dynamic locators: private methods returning `By`
|
|
102
|
+
- NO arrow functions in Mocha declarations
|
|
103
|
+
- Explicit return types on ALL functions
|
|
104
|
+
- Single quotes for strings
|
|
105
|
+
- Comments start lowercase: `// todo issue crw-1010`
|
|
106
|
+
|
|
107
|
+
## Directory Structure
|
|
108
|
+
|
|
109
|
+
| Directory | Purpose |
|
|
110
|
+
| ---------------- | ----------------------------------------------------- |
|
|
111
|
+
| `specs/` | Test files (api/, factory/, miscellaneous/) |
|
|
112
|
+
| `pageobjects/` | Page Object classes |
|
|
113
|
+
| `utils/` | DriverHelper, Logger, API handlers |
|
|
114
|
+
| `tests-library/` | Reusable helpers (LoginTests, WorkspaceHandlingTests) |
|
|
115
|
+
| `constants/` | Environment variables and timeouts |
|
|
116
|
+
| `configs/` | Inversify DI, Mocha config |
|
|
117
|
+
|
|
118
|
+
## Adding New Components
|
|
119
|
+
|
|
120
|
+
### New Page Object
|
|
121
|
+
|
|
122
|
+
1. Create in `pageobjects/<category>/NewPage.ts`
|
|
123
|
+
2. Add to `inversify.types.ts`: `NewPage: 'NewPage'`
|
|
124
|
+
3. Add to `inversify.config.ts`: `e2eContainer.bind<NewPage>(CLASSES.NewPage).to(NewPage)`
|
|
125
|
+
|
|
126
|
+
### New Test
|
|
127
|
+
|
|
128
|
+
1. Create `specs/<category>/TestName.spec.ts`
|
|
129
|
+
2. Run: `export USERSTORY=TestName && npm run test`
|
|
130
|
+
|
|
131
|
+
## GitHub Actions
|
|
132
|
+
|
|
133
|
+
PR checks run on changes to `tests/e2e/**`:
|
|
134
|
+
|
|
135
|
+
1. Prettier formatting check
|
|
136
|
+
2. TypeScript compilation
|
|
137
|
+
3. ESLint linting
|
|
138
|
+
4. API and UI tests on minikube
|
|
139
|
+
|
|
140
|
+
**Before pushing**: Run `npm run prettier && npm run tsc && npm run lint`
|
|
141
|
+
|
|
142
|
+
## Environment Variables
|
|
143
|
+
|
|
144
|
+
| Variable | Description |
|
|
145
|
+
| -------------------------- | ----------------------------------- |
|
|
146
|
+
| `TS_SELENIUM_BASE_URL` | Che dashboard URL |
|
|
147
|
+
| `TS_SELENIUM_OCP_USERNAME` | OpenShift username |
|
|
148
|
+
| `TS_SELENIUM_OCP_PASSWORD` | OpenShift password |
|
|
149
|
+
| `USERSTORY` | Test file to run (without .spec.ts) |
|
|
150
|
+
| `TS_PLATFORM` | `openshift` or `kubernetes` |
|
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ Note: If there is any modifications in package.json, manually execute the `npm i
|
|
|
55
55
|
|
|
56
56
|
## Debug docker launch
|
|
57
57
|
|
|
58
|
-
The `'eclipse/che-e2e'` docker image has VNC server installed inside. For connecting use `'0.0.0.0:5920'` address.
|
|
58
|
+
The `'quay.io/eclipse/che-e2e'` docker image has VNC server installed inside. For connecting use `'0.0.0.0:5920'` address.
|
|
59
59
|
|
|
60
60
|
## The "Happy Path" scenario launching
|
|
61
61
|
|
|
@@ -17,6 +17,7 @@ export const TIMEOUT_CONSTANTS: {
|
|
|
17
17
|
TS_EXPAND_PROJECT_TREE_ITEM_TIMEOUT: number;
|
|
18
18
|
TS_FIND_EXTENSION_TEST_TIMEOUT: number;
|
|
19
19
|
TS_IDE_LOAD_TIMEOUT: number;
|
|
20
|
+
TS_IDE_START_TIMEOUT: number;
|
|
20
21
|
TS_NOTIFICATION_WAIT_TIMEOUT: number;
|
|
21
22
|
TS_SELENIUM_CLICK_ON_VISIBLE_ITEM: number;
|
|
22
23
|
TS_SELENIUM_DEFAULT_ATTEMPTS: number;
|
|
@@ -49,6 +50,11 @@ export const TIMEOUT_CONSTANTS: {
|
|
|
49
50
|
*/
|
|
50
51
|
TS_IDE_LOAD_TIMEOUT: Number(process.env.TS_IDE_LOAD_TIMEOUT) || 20_000,
|
|
51
52
|
|
|
53
|
+
/**
|
|
54
|
+
* timeout for waiting for IDE to start during workspace startup, "310 000" by default.
|
|
55
|
+
*/
|
|
56
|
+
TS_IDE_START_TIMEOUT: Number(process.env.TS_IDE_START_TIMEOUT) || 310_000,
|
|
57
|
+
|
|
52
58
|
/**
|
|
53
59
|
* timeout in milliseconds waiting for workspace start, "360 000" by default.
|
|
54
60
|
*/
|
|
@@ -28,6 +28,10 @@ exports.TIMEOUT_CONSTANTS = {
|
|
|
28
28
|
* wait between workspace started and IDE ready to be used, "20 000" by default.
|
|
29
29
|
*/
|
|
30
30
|
TS_IDE_LOAD_TIMEOUT: Number(process.env.TS_IDE_LOAD_TIMEOUT) || 20000,
|
|
31
|
+
/**
|
|
32
|
+
* timeout for waiting for IDE to start during workspace startup, "310 000" by default.
|
|
33
|
+
*/
|
|
34
|
+
TS_IDE_START_TIMEOUT: Number(process.env.TS_IDE_START_TIMEOUT) || 310000,
|
|
31
35
|
/**
|
|
32
36
|
* timeout in milliseconds waiting for workspace start, "360 000" by default.
|
|
33
37
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TIMEOUT_CONSTANTS.js","sourceRoot":"","sources":["../../constants/TIMEOUT_CONSTANTS.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;wEAQwE;AAC3D,QAAA,iBAAiB,
|
|
1
|
+
{"version":3,"file":"TIMEOUT_CONSTANTS.js","sourceRoot":"","sources":["../../constants/TIMEOUT_CONSTANTS.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;wEAQwE;AAC3D,QAAA,iBAAiB,GAoB1B;IACH;;OAEG;IACH,4BAA4B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,CAAC;IAEnF;;OAEG;IACH,2BAA2B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,IAAI,IAAI;IAEpF,mHAAmH;IAEnH;;OAEG;IACH,wBAAwB,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,KAAM;IAEhF;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,KAAM;IAEtE;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,MAAO;IAEzE;;OAEG;IACH,mCAAmC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,IAAI,MAAO;IAEvG;;OAEG;IACH,6BAA6B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,IAAI,KAAM;IAE1F;;OAEG;IACH,8BAA8B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,IAAI,KAAM;IAE5F;;OAEG;IACH,+BAA+B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,IAAI,KAAM;IAE9F,sGAAsG;IAEtG;;OAEG;IACH,gCAAgC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,IAAI,IAAK;IAE/F;;OAEG;IACH,+BAA+B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,IAAI,IAAK;IAE7F;;OAEG;IACH,mCAAmC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,IAAI,KAAM;IAEtG,yGAAyG;IAEzG;;OAEG;IACH,mCAAmC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,IAAI,IAAK;IAErG,mGAAmG;IAEnG;;OAEG;IACH,iCAAiC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,KAAM;IAE7F,gGAAgG;IAEhG;;OAEG;IACH,gCAAgC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,IAAI,KAAM;IAEhG;;OAEG;IACH,iCAAiC,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,IAAI,IAAK;IAEjG;;OAEG;IACH,4BAA4B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,KAAM;IAExF,8FAA8F;IAE9F;;OAEG;IACH,6BAA6B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,IAAI,KAAM;IAE1F;;OAEG;IACH,8BAA8B,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,IAAI,KAAM;CAC5F,CAAC"}
|
|
@@ -46,11 +46,23 @@ suite(`Create predefined workspace and check it ${BASE_TEST_CONSTANTS_1.BASE_TES
|
|
|
46
46
|
// generate empty workspace DevFile and create it through oc client under a regular user
|
|
47
47
|
suiteSetup('Login', async function () {
|
|
48
48
|
const devfileContent = 'schemaVersion: 2.2.0\n' + 'metadata:\n' + ` name: ${workspaceName}\n`;
|
|
49
|
+
const majorMinorVersion = BASE_TEST_CONSTANTS_1.BASE_TEST_CONSTANTS.TESTING_APPLICATION_VERSION.split('.').slice(0, 2).join('.');
|
|
50
|
+
const devSpacesEditorImage = `quay.io/redhat-user-workloads/devspaces-tenant/devspaces/code-rhel9:${majorMinorVersion}`;
|
|
49
51
|
kubernetesCommandLineToolsExecutor.loginToOcp(userName);
|
|
50
52
|
devWorkspaceConfigurationHelper = new DevWorkspaceConfigurationHelper_1.DevWorkspaceConfigurationHelper({
|
|
51
53
|
devfileContent
|
|
52
54
|
});
|
|
53
55
|
devfileContext = await devWorkspaceConfigurationHelper.generateDevfileContext();
|
|
56
|
+
// update che-code-injector image to use Dev Spaces VS Code Editor (Dev Spaces only)
|
|
57
|
+
if (BASE_TEST_CONSTANTS_1.BASE_TEST_CONSTANTS.TESTING_APPLICATION_NAME() === 'devspaces') {
|
|
58
|
+
devfileContext.devWorkspaceTemplates.forEach((template) => {
|
|
59
|
+
template.spec?.components?.forEach((component) => {
|
|
60
|
+
if (component.name === 'che-code-injector' && component.container?.image) {
|
|
61
|
+
component.container.image = devSpacesEditorImage;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
54
66
|
const devWorkspaceConfigurationYamlString = devWorkspaceConfigurationHelper.getDevWorkspaceConfigurationYamlAsString(devfileContext);
|
|
55
67
|
kubernetesCommandLineToolsExecutor.applyWithoutNamespace(devWorkspaceConfigurationYamlString);
|
|
56
68
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PredefinedNamespace.spec.js","sourceRoot":"","sources":["../../../specs/miscellaneous/PredefinedNamespace.spec.ts"],"names":[],"mappings":";;AAAA;;;;;;;;wEAQwE;AACxE,qEAA8D;AAC9D,+BAA8B;AAC9B,mEAAwD;AACxD,uFAAoF;AACpF,+CAA4C;AAG5C,6EAA0E;AAC1E,iGAA8F;AAG9F,KAAK,CAAC,4CAA4C,yCAAmB,CAAC,gBAAgB,EAAE,EAAE;IACzF,MAAM,uBAAuB,GAAW,eAAe,CAAC;IACxD,MAAM,aAAa,GAAW,UAAU,CAAC;IACzC,MAAM,aAAa,GAAkB,+BAAY,CAAC,GAAG,CAAC,yBAAO,CAAC,aAAa,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAW,MAAM,CAAC;IAChC,IAAI,+BAAgE,CAAC;IACrE,IAAI,cAA8B,CAAC;IACnC,MAAM,kCAAkC,GAAuC,+BAAY,CAAC,GAAG,CAC9F,yBAAO,CAAC,kCAAkC,CAC1C,CAAC;IAEF,UAAU,CAAC;QACV,0FAA0F;QAC1F,eAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACpC,eAAM,CAAC,KAAK,CACX,kJAAkJ,CAClJ,CAAC;QACF,eAAM,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;QAC/F,kCAAkC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,8BAA8B,GACnC,mBAAmB;YACnB,kBAAkB;YAClB,aAAa;YACb,WAAW,uBAAuB,IAAI;YACtC,aAAa;YACb,kDAAkD;YAClD,yDAAyD;YACzD,kBAAkB;YAClB,oCAAoC,CAAC;QACtC,kCAAkC,CAAC,qBAAqB,CAAC,8BAA8B,CAAC,CAAC;QACzF,MAAM,oBAAoB,GAAW,+CAA+C,uBAAuB,EAAE,CAAC;QAC9G,aAAa,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,wFAAwF;IACxF,UAAU,CAAC,OAAO,EAAE,KAAK;QACxB,MAAM,cAAc,GAAW,wBAAwB,GAAG,aAAa,GAAG,WAAW,aAAa,IAAI,CAAC;QACvG,kCAAkC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACxD,+BAA+B,GAAG,IAAI,iEAA+B,CAAC;YACrE,cAAc;SACd,CAAC,CAAC;QACH,cAAc,GAAG,MAAM,+BAA+B,CAAC,sBAAsB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"PredefinedNamespace.spec.js","sourceRoot":"","sources":["../../../specs/miscellaneous/PredefinedNamespace.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -44,7 +44,7 @@ let ProjectAndFileTests = ProjectAndFileTests_1 = class ProjectAndFileTests {
|
|
|
44
44
|
Logger_1.Logger.debug('waiting for editor.');
|
|
45
45
|
try {
|
|
46
46
|
const start = new Date().getTime();
|
|
47
|
-
await this.driverHelper.waitVisibility(this.cheCodeLocatorLoader.webCheCodeLocators.Workbench.constructor, TIMEOUT_CONSTANTS_1.TIMEOUT_CONSTANTS.
|
|
47
|
+
await this.driverHelper.waitVisibility(this.cheCodeLocatorLoader.webCheCodeLocators.Workbench.constructor, TIMEOUT_CONSTANTS_1.TIMEOUT_CONSTANTS.TS_IDE_START_TIMEOUT);
|
|
48
48
|
const end = new Date().getTime();
|
|
49
49
|
Logger_1.Logger.debug(`editor was opened in ${end - start} seconds.`);
|
|
50
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectAndFileTests.js","sourceRoot":"","sources":["../../tests-library/ProjectAndFileTests.ts"],"names":[],"mappings":";AAAA;;;;;;;;wEAQwE;;;;;;;;;;;;;;;;AAExE,4BAA0B;AAC1B,yCAA+C;AAC/C,wDAAqD;AACrD,gEAAqD;AACrD,4CAAyC;AACzC,sEAAmE;AACnE,kFAA+E;AAC/E,6DAAqG;AACrG,oFAAiF;AACjF,kFAA+E;AAGxE,IAAM,mBAAmB,2BAAzB,MAAM,mBAAmB;IAI/B,YAEkB,YAA0B,EAE1B,oBAA0C,EAE1C,sBAA8C,EAE9C,oBAA0C;QAN1C,iBAAY,GAAZ,YAAY,CAAc;QAE1B,yBAAoB,GAApB,oBAAoB,CAAsB;QAE1C,2BAAsB,GAAtB,sBAAsB,CAAwB;QAE9C,yBAAoB,GAApB,oBAAoB,CAAsB;IACzD,CAAC;IAEJ,KAAK,CAAC,sCAAsC;QAC3C,eAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,KAAK,GAAW,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,CACrC,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,SAAS,CAAC,WAAW,EAClE,qCAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"ProjectAndFileTests.js","sourceRoot":"","sources":["../../tests-library/ProjectAndFileTests.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -54,11 +54,25 @@ suite(`Create predefined workspace and check it ${BASE_TEST_CONSTANTS.TEST_ENVIR
|
|
|
54
54
|
// generate empty workspace DevFile and create it through oc client under a regular user
|
|
55
55
|
suiteSetup('Login', async function (): Promise<void> {
|
|
56
56
|
const devfileContent: string = 'schemaVersion: 2.2.0\n' + 'metadata:\n' + ` name: ${workspaceName}\n`;
|
|
57
|
+
const majorMinorVersion: string = BASE_TEST_CONSTANTS.TESTING_APPLICATION_VERSION.split('.').slice(0, 2).join('.');
|
|
58
|
+
const devSpacesEditorImage: string = `quay.io/redhat-user-workloads/devspaces-tenant/devspaces/code-rhel9:${majorMinorVersion}`;
|
|
57
59
|
kubernetesCommandLineToolsExecutor.loginToOcp(userName);
|
|
58
60
|
devWorkspaceConfigurationHelper = new DevWorkspaceConfigurationHelper({
|
|
59
61
|
devfileContent
|
|
60
62
|
});
|
|
61
63
|
devfileContext = await devWorkspaceConfigurationHelper.generateDevfileContext();
|
|
64
|
+
|
|
65
|
+
// update che-code-injector image to use Dev Spaces VS Code Editor (Dev Spaces only)
|
|
66
|
+
if (BASE_TEST_CONSTANTS.TESTING_APPLICATION_NAME() === 'devspaces') {
|
|
67
|
+
devfileContext.devWorkspaceTemplates.forEach((template): void => {
|
|
68
|
+
template.spec?.components?.forEach((component): void => {
|
|
69
|
+
if (component.name === 'che-code-injector' && component.container?.image) {
|
|
70
|
+
component.container.image = devSpacesEditorImage;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
62
76
|
const devWorkspaceConfigurationYamlString: string =
|
|
63
77
|
devWorkspaceConfigurationHelper.getDevWorkspaceConfigurationYamlAsString(devfileContext);
|
|
64
78
|
kubernetesCommandLineToolsExecutor.applyWithoutNamespace(devWorkspaceConfigurationYamlString);
|
|
@@ -41,7 +41,7 @@ export class ProjectAndFileTests {
|
|
|
41
41
|
const start: number = new Date().getTime();
|
|
42
42
|
await this.driverHelper.waitVisibility(
|
|
43
43
|
this.cheCodeLocatorLoader.webCheCodeLocators.Workbench.constructor,
|
|
44
|
-
TIMEOUT_CONSTANTS.
|
|
44
|
+
TIMEOUT_CONSTANTS.TS_IDE_START_TIMEOUT
|
|
45
45
|
);
|
|
46
46
|
const end: number = new Date().getTime();
|
|
47
47
|
Logger.debug(`editor was opened in ${end - start} seconds.`);
|