From ab6058e6b6bd8e93da037db790345d29c0f3295a Mon Sep 17 00:00:00 2001 From: Adel Bensaad Date: Thu, 2 May 2024 16:23:51 +0100 Subject: [PATCH 1/3] chore: optimize Cypress recordings with conditional triggers chore: enhance parallel test execution setup in CI chore: trigger tests chore: split e2e testing into separate workflows for GitHub Actions and Cypress Cloud chore: fix workflow needs typo chore: adjust e2e workflow triggers for accurate routing chore: commit to trigger tests fix --- .github/workflows/dhis2-verify-app.yml | 19 +++++++++++--- README.md | 11 +++++++- cypress/support/generateTestMatrix.js | 35 ++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 cypress/support/generateTestMatrix.js diff --git a/.github/workflows/dhis2-verify-app.yml b/.github/workflows/dhis2-verify-app.yml index 9c3a8a6475..43e9a5f15b 100644 --- a/.github/workflows/dhis2-verify-app.yml +++ b/.github/workflows/dhis2-verify-app.yml @@ -2,7 +2,7 @@ name: 'dhis2: verify (app)' on: pull_request: - types: ['opened', 'edited', 'reopened', 'synchronize'] + types: ['opened', 'labeled', 'reopened', 'synchronize'] push: branches: - 'master' @@ -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: @@ -83,8 +93,11 @@ jobs: call-workflow-e2e-prod: if: "!contains(github.event.head_commit.message, '[skip ci]')" - needs: [build, lint, test] - uses: dhis2/workflows/.github/workflows/analytics-e2e-tests-prod.yml@master + needs: [build, lint, test, setup-matrix] + uses: dhis2/workflows/.github/workflows/analytics-e2e-tests-prod.yml@update-cypress-setup + 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 }} diff --git a/README.md b/README.md index 5f0b7cc1f7..33e7c2f5a5 100644 --- a/README.md +++ b/README.md @@ -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 { diff --git a/cypress/support/generateTestMatrix.js b/cypress/support/generateTestMatrix.js new file mode 100644 index 0000000000..8cbfd3df8e --- /dev/null +++ b/cypress/support/generateTestMatrix.js @@ -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 = 3) => { + 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)) From d338fe5aa9da9e418e3fa52f54f3d8146560276e Mon Sep 17 00:00:00 2001 From: Adel Bensaad Date: Wed, 29 May 2024 08:40:37 +0100 Subject: [PATCH 2/3] chore: parallelise specs across 5 machines Save over 3 minutes by parallelizing specs across 5 machines Reduce run time by up to 75%. --- cypress/support/generateTestMatrix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/support/generateTestMatrix.js b/cypress/support/generateTestMatrix.js index 8cbfd3df8e..e2ece39c9f 100644 --- a/cypress/support/generateTestMatrix.js +++ b/cypress/support/generateTestMatrix.js @@ -15,7 +15,7 @@ const getAllFiles = (dirPath, arrayOfFiles = []) => { return arrayOfFiles } -const createGroups = (files, numberOfGroups = 3) => { +const createGroups = (files, numberOfGroups = 5) => { const groups = [] for (let i = 0; i < numberOfGroups; i++) { groups.push([]) From 3c828e2d8d141114a03cfa861b1ae5029de11d7f Mon Sep 17 00:00:00 2001 From: Adel Bensaad Date: Tue, 4 Jun 2024 13:09:47 +0100 Subject: [PATCH 3/3] chore: use workflows/analytics-e2e-tests-prod.yml@master --- .github/workflows/dhis2-verify-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dhis2-verify-app.yml b/.github/workflows/dhis2-verify-app.yml index 43e9a5f15b..095425bd91 100644 --- a/.github/workflows/dhis2-verify-app.yml +++ b/.github/workflows/dhis2-verify-app.yml @@ -94,7 +94,7 @@ jobs: call-workflow-e2e-prod: if: "!contains(github.event.head_commit.message, '[skip ci]')" needs: [build, lint, test, setup-matrix] - uses: dhis2/workflows/.github/workflows/analytics-e2e-tests-prod.yml@update-cypress-setup + 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 }}