Skip to content

Commit

Permalink
chore: optimize Cypress recordings with conditional triggers (#3043)
Browse files Browse the repository at this point in the history
Implements DHIS2-17374

Conditional Recording Triggers:
Implemented conditional recording triggers via commit messages
and GitHub labels to ensure that Cypress tests are only recorded when necessary.

Parallel Execution Strategies: Refined parallel execution strategies to improve efficiency and
resolve test redundancies in GitHub Actions.
Debugging Enhancements: Added detailed debugging outputs to help track the dynamic values of
the test environment variables and ensure correct parameter passing in the workflow.

Manual Grouping of Tests:
In GitHub Actions, without specified test groups, all tests would run
in every parallel container, leading to unnecessary repetition. By organizing tests into
predefined groups, each group runs only once. This prevents redundancy and expedites the testing
process.

Why Not Rely on Cypress's Automatic Balancing? While Cypress automatically assigns tests to
machines to balance workload (more on Cypress load balancing), GitHub Actions requires explicit
distribution of tasks. This manual grouping ensures efficient resource usage and prevents multiple
executions of the same tests across different runners.

Benefits:
This approach allows precise control over test distribution, enhancing predictability
and efficiency. It reduces total execution time and operational costs by ensuring each test is run
precisely once across the available infrastructure.

This method optimises our use of GitHub Actions, ensuring a faster, cost-effective,
and efficient testing process.

Update Documentation:
Updated the documentation to reflect the changes and ensure clarity
on the new CI/CD processes.

Expected Outcomes:
Reduced Cypress Cloud Credit Usage: By optimising the conditions under which tests are recorded
and uploaded to Cypress Cloud, we anticipate a significant reduction in credit usage.

Increased CI Efficiency: With better management of parallel execution and conditional testing, the
CI process should be more efficient, leading to quicker test cycles.
  • Loading branch information
adeldhis2 authored Jun 4, 2024
1 parent 3ee3a83 commit 15dc8d9
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
17 changes: 15 additions & 2 deletions .github/workflows/dhis2-verify-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: 'dhis2: verify (app)'

on:
pull_request:
types: ['opened', 'edited', 'reopened', 'synchronize']
types: ['opened', 'labeled', 'reopened', 'synchronize']
push:
branches:
- 'master'
Expand All @@ -21,6 +21,16 @@ env:
D2_VERBOSE: true

jobs:
setup-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.specs }}
steps:
- uses: actions/checkout@v3
- name: Generate test matrix
id: set-matrix
run: echo "::set-output name=specs::$(node cypress/support/generateTestMatrix.js)"

build:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -83,8 +93,11 @@ jobs:

call-workflow-e2e-prod:
if: "!contains(github.event.head_commit.message, '[skip ci]')"
needs: [build, lint, test]
needs: [build, lint, test, setup-matrix]
uses: dhis2/workflows/.github/workflows/analytics-e2e-tests-prod.yml@master
with:
should_record: ${{ contains(github.event.head_commit.message, '[e2e record]') || contains(join(github.event.pull_request.labels.*.name), 'e2e record')}}
spec-group: ${{ needs.setup-matrix.outputs.matrix }}
secrets:
username: ${{ secrets.CYPRESS_DHIS2_USERNAME }}
password: ${{ secrets.CYPRESS_DHIS2_PASSWORD }}
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,16 @@ $ yarn coverage

#### e2e tests

Cypress is used for e2e browser tests. This automatically runs on CI for PRs, the result can be seen on the [Cypress dashboard](https://dashboard.cypress.io/projects/sojh88/). To run the tests locally, define the following in a local `cypress.env.json` file, e.g.:
Cypress is used for e2e browser tests. This automatically runs on CI for PRs, the result can be seen on the [Cypress Cloud](https://dashboard.cypress.io/projects/sojh88/).

To record tests in Cypress Cloud, you can use one of the following methods based on your needs:

- **Commit Message**: Include `[e2e record]` in your commit messages to activate recording.
- **GitHub Labels**: Apply the `e2e record` label to your pull request to trigger recording.

This setup helps in managing Cypress Cloud credits more efficiently, ensuring recordings are only made when explicitly required.

To run the tests locally, define the following in a local `cypress.env.json` file, e.g.:

```sh
{
Expand Down
35 changes: 35 additions & 0 deletions cypress/support/generateTestMatrix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const fs = require('fs')
const path = require('path')

const getAllFiles = (dirPath, arrayOfFiles = []) => {
const files = fs.readdirSync(dirPath)

files.forEach((file) => {
if (fs.statSync(path.join(dirPath, file)).isDirectory()) {
arrayOfFiles = getAllFiles(path.join(dirPath, file), arrayOfFiles)
} else if (path.extname(file) === '.js') {
arrayOfFiles.push(path.join(dirPath, file))
}
})

return arrayOfFiles
}

const createGroups = (files, numberOfGroups = 5) => {
const groups = []
for (let i = 0; i < numberOfGroups; i++) {
groups.push([])
}

files.forEach((file, index) => {
groups[index % numberOfGroups].push(file)
})

return groups.map((group, index) => ({ id: index + 1, tests: group }))
}

const cypressSpecsPath = './cypress/integration'
const specs = getAllFiles(cypressSpecsPath)
const groupedSpecs = createGroups(specs)

console.log(JSON.stringify(groupedSpecs))

0 comments on commit 15dc8d9

Please sign in to comment.