Skip to content

Commit d8eef6f

Browse files
authored
Merge pull request #4588 from manosnoam/cy_retry
Add CY_RETRY option for Cypress test retry configuration
2 parents 0d4a6e7 + 64809bd commit d8eef6f

File tree

4 files changed

+111
-13
lines changed

4 files changed

+111
-13
lines changed

docs/testing.md

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,72 @@ npm run cypress:open:record
222222
npm run cypress:run:record
223223
```
224224

225+
### Cypress Environment Variables
226+
227+
Cypress uses several environment variables to control test behavior and configuration. These can be set in your shell or passed directly to the Cypress commands.
228+
229+
#### CY_TEST_CONFIG
230+
- **Purpose**: Path to test configuration YAML file
231+
- **Values**: File path to YAML configuration (e.g., `./test-variables.yml`)
232+
- **Effect**: Loads test variables and configuration from a YAML file
233+
- **Usage**: `export CY_TEST_CONFIG='PATH_TO_YOUR_TEST_VARIABLES'`
234+
- **Required**: Yes, for e2e tests
235+
236+
#### CY_MOCK
237+
- **Purpose**: Enables mocked test mode
238+
- **Values**: `1` (enabled) or `0`/unset (disabled)
239+
- **Effect**:
240+
- Runs tests from `cypress/tests/mocked/` directory instead of `cypress/tests/e2e/`
241+
- Changes results directory to `results/mocked/`
242+
- Disables test retries by default
243+
- Loads different environment files (`.env.cypress.mock`)
244+
- **Usage**: `CY_MOCK=1 npm run cypress:run`
245+
246+
#### CY_RETRY
247+
- **Purpose**: Controls test retry behavior
248+
- **Values**: Number of retries (e.g., `0`, `1`, `2`)
249+
- **Default**: `2` retries for e2e tests, `0` for mocked tests
250+
- **Effect**: Sets the number of additional attempts a test will retry if it fails
251+
- **Usage**: `CY_RETRY=0 npm run cypress:run` (no retries)
252+
253+
#### CY_RECORD
254+
- **Purpose**: Enables snapshot recording mode
255+
- **Values**: `1` (enabled) or `0`/unset (disabled)
256+
- **Effect**: Records network responses for snapshot testing
257+
- **Usage**: `CY_RECORD=1 npm run cypress:run`
258+
259+
#### CY_WATCH
260+
- **Purpose**: Controls file watching behavior
261+
- **Values**: `false` to disable, any other value to enable
262+
- **Effect**: Enables/disables watching for file changes during test execution
263+
- **Usage**: `CY_WATCH=false npm run cypress:open`
264+
265+
#### CY_WS_PORT
266+
- **Purpose**: Sets the WebSocket server port for mocked tests
267+
- **Values**: Port number (e.g., `9002`)
268+
- **Default**: Used in mocked test scripts
269+
- **Effect**: Configures the WebSocket server port for real-time communication in mocked tests
270+
- **Usage**: Set automatically in npm scripts like `cypress:run:mock`
271+
272+
#### CY_COVERAGE
273+
- **Purpose**: Enables code coverage collection
274+
- **Values**: `true` (enabled) or `false`/unset (disabled)
275+
- **Effect**: Enables code coverage reporting during test execution
276+
- **Usage**: `CY_COVERAGE=true npm run cypress:run`
277+
278+
#### CY_RESULTS_DIR
279+
- **Purpose**: Sets the directory for test results
280+
- **Values**: Directory path (e.g., `results`, `custom-results`)
281+
- **Default**: `results`
282+
- **Effect**: Changes where test results (screenshots, videos, reports) are stored
283+
- **Usage**: `CY_RESULTS_DIR=custom-results npm run cypress:run`
284+
285+
#### CY_TEST_TIMEOUT_SECONDS
286+
- **Purpose**: Sets global test timeout
287+
- **Values**: Number of seconds
288+
- **Effect**: Configures the global timeout for all tests
289+
- **Usage**: `CY_TEST_TIMEOUT_SECONDS=300 npm run cypress:run`
290+
225291
### Page Objects
226292

227293
Page Objects are TypeScript objects / classes used to encapsulate all the selectors and functions related to a particular page or UI element. The functions exposed by a page object use the following prefixes:
@@ -290,7 +356,7 @@ cy.wsK8s('DELETED', ProjectModel, <project resource>);
290356

291357
Always start a new test with a `visit` to the page being tested.
292358

293-
Use variants of `intercept` to mock network requests.
359+
Use variants of `intercept` to mock network requests.
294360

295361
When a UI action results in a network request, the test must wait to ensure the request was issued:
296362
```ts

frontend/src/__tests__/cypress/cypress.config.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,32 @@ export default defineConfig({
7272
: `cypress/tests/e2e/**/*.cy.ts`,
7373
experimentalInteractiveRunEvents: true,
7474
setupNodeEvents(on, config) {
75+
// Dynamically merge all CY_ variables from both process.env and --env sources, with --env taking precedence
76+
// This allows setting CY_ variables via shell environment (CY_RETRY=1) or Cypress --env flag (--env CY_RETRY=1)
77+
// Update the existing env variable with merged values
78+
Object.assign(env, {
79+
...Object.fromEntries(
80+
Object.keys(config.env)
81+
.filter((key) => key.startsWith('CY_'))
82+
.map((key) => [key, config.env[key]]),
83+
),
84+
WS_PORT: (config.env.CY_WS_PORT ?? env.CY_WS_PORT ?? '9002').toString(),
85+
});
86+
87+
// Create config with merged environment variables
88+
// config.env (--env vars) takes precedence over process.env (shell env vars)
89+
const configWithEnv = {
90+
...config,
91+
env: {
92+
...env,
93+
...config.env,
94+
},
95+
};
96+
7597
registerCypressGrep(config);
7698
cypressHighResolution(on, config);
7799
coverage(on, config);
78-
setupWebsockets(on, config);
100+
setupWebsockets(on, configWithEnv);
79101

80102
on('task', {
81103
readJSON(filePath: string) {
@@ -148,10 +170,19 @@ export default defineConfig({
148170
await mergeFiles(outputFile, inputFiles);
149171
});
150172

151-
// Apply retries only for tests in the "e2e" folder
173+
// Apply retries only for tests in the "e2e" folder. 2 retries by default, after a test failure.
174+
// Set CY_RETRY=N env var for the number of retries (CY_RETRY=0 means no retries).
175+
const retryConfig =
176+
env.CY_RETRY !== undefined
177+
? { runMode: Math.max(0, parseInt(env.CY_RETRY) || 0), openMode: 0 }
178+
: !env.CY_MOCK && !env.CY_RECORD
179+
? { runMode: 2, openMode: 0 }
180+
: config.retries;
181+
152182
return {
153183
...config,
154-
retries: !env.CY_MOCK && !env.CY_RECORD ? { runMode: 2, openMode: 0 } : config.retries,
184+
retries: retryConfig,
185+
env,
155186
};
156187
},
157188
},

frontend/src/__tests__/cypress/cypress/support/e2e.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,23 +105,21 @@ Cypress.Keyboard.defaults({
105105
keystrokeDelay: 0,
106106
});
107107

108-
// Handle ChunkLoadError - ignore these errors as they are usually due to code splitting issues during development
108+
// Uncaught exceptions handler
109109
Cypress.on('uncaught:exception', (err) => {
110-
// Returning false here prevents Cypress from failing the test
110+
// Handle ChunkLoadError - ignore these errors as they are usually due to code splitting issues during development
111111
if (err.name === 'ChunkLoadError') {
112112
// eslint-disable-next-line no-console
113113
console.warn('ChunkLoadError caught and ignored:', err.message);
114114
return false;
115115
}
116-
// Let other errors fail the test as expected
117-
return true;
118-
});
119116

120-
// Ignore 'Unexpected token <' errors from webpack-dev-server fallback in E2E tests
121-
Cypress.on('uncaught:exception', (err) => {
117+
// Ignore 'Unexpected token <' errors from webpack-dev-server fallback in E2E tests
122118
if (err.message.includes("Unexpected token '<'")) {
123119
return false;
124120
}
121+
122+
// Let all other errors (including timeout errors) fail the test as expected
125123
return true;
126124
});
127125

frontend/src/__tests__/cypress/cypress/tests/e2e/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ npm run cypress:run \
143143
- `@Maintain`: Skip tests that require maintenance
144144
- `@NonConcurrent`: Skip tests that cannot run concurrently (to prevent resource conflicts)
145145

146+
## Environment Variables
147+
148+
For comprehensive documentation of all Cypress environment variables, see the [Cypress Environment Variables section in the main testing documentation](/docs/testing.md#cypress-environment-variables).
149+
146150
## Writing Tests
147151

148152
e2e tests should focus on user journeys through the application, validating that features work as intended from the user's perspective.
@@ -198,7 +202,7 @@ Tests are parameterized using tags and applied to the 'it' block:
198202
* `Workbenches/Pipelines etc.`: Functional Area
199203
* `Destructive`: Tests that have the potential to break other tests (changing configuration etc.) 
200204
* `Bug`: Tests that are currently failing due to a Product Bug
201-
* `Maintain`: Tests that are currently failing and require maintenance
205+
* `Maintain`: Tests that are currently failing and require maintenance
202206
* `NonConcurrent`: Tests that cannot run concurrently (to prevent resource conflicts)
203207

204208
**Usage in tests:**
@@ -271,4 +275,3 @@ unset CY_TEST_CONFIG
271275
[Dashboard documentation]: docs/README.md
272276
[contributing guidelines]: CONTRIBUTING.md
273277
[issue]: https://github.com/opendatahub-io/odh-dashboard/issues/new/choose
274-
[definition of ready]: docs/definition-of-ready.md

0 commit comments

Comments
 (0)