diff --git a/.github/workflows/e2e-smoke.yml b/.github/workflows/e2e-smoke.yml new file mode 100644 index 000000000..1640ef379 --- /dev/null +++ b/.github/workflows/e2e-smoke.yml @@ -0,0 +1,117 @@ +name: 'e2e-smoke' + +# Requirements: +# +# - Customize environment variables: +# BASE_URL_INSTANCES: Set the base url for the instances, e.g. https://test.e2e.dhis2.org +# NAME_PATTERN_PROD_INSTANCES: Set the name pattern for your instances. {version} will be replaced by "[majorVersion].[minorVersion]" +# +# - Other optional customizations: +# containers: Set the matrix containers array for the e2e-prod job. The number of parallel Cypress instances running for each backend version will equal the array length. +# +# - Set status check as required: +# We recommend setting "e2e-tests-success" as a required step in your workflow. + +on: + workflow_call: + inputs: + should_record: + required: false + type: boolean + default: false + secrets: + username: + required: true + password: + required: true + +env: + BASE_URL_INSTANCES: https://test.e2e.dhis2.org + NAME_PATTERN_PROD_INSTANCES: 'analytics-{version}' + +concurrency: + group: e2e-smoke-${{ github.workflow}}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + compute-prod-versions: + runs-on: ubuntu-latest + outputs: + versions: ${{ steps.prod-versions.outputs.versions }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Output prod version urls + id: prod-versions + uses: dhis2/action-supported-legacy-versions@v1 + with: + instance-url-latest: https://test.e2e.dhis2.org/analytics-dev # can be removed if maxDHIS2Version has been specified + username: ${{ secrets.username }} + password: ${{ secrets.password }} + + e2e-smoke-tests: + needs: compute-prod-versions + runs-on: ubuntu-latest + env: + CI_BUILD_ID: ${{ github.sha }}-${{ github.workflow }}-${{ github.event_name }} + BRANCH_NAME: ${{ github.head_ref || github.ref_name }} + PR_TITLE: ${{ github.event.pull_request.title }} + DHIS2_VERSION: ${{ matrix.versions }} + strategy: + fail-fast: false + matrix: + versions: ${{ fromJSON(needs.compute-prod-versions.outputs.versions) }} + containers: [1] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18.x + - uses: browser-actions/setup-chrome@v1 + with: + chrome-version: stable + - run: | + echo "BROWSER_PATH=$(which chrome)" >> $GITHUB_ENV + - name: Compute prod instance url + id: instance-url + run: | + url=${BASE_URL_INSTANCES%/}/${NAME_PATTERN_PROD_INSTANCES/"{version}"/$version} + echo "url=$url" >> $GITHUB_OUTPUT + echo "url: $url" + env: + version: ${{ matrix.versions }} + + - name: Run e2e smoke tests + uses: cypress-io/github-action@v5 + with: + spec: cypress/integration/smoke.cy.js + start: yarn d2-app-scripts start + wait-on: 'http://localhost:3000' + wait-on-timeout: 300 + record: false + parallel: false + browser: chrome + env: + CI: true + BROWSER: none + CYPRESS_RECORD_KEY: ${{ secrets.recordkey }} + CYPRESS_dhis2BaseUrl: ${{ steps.instance-url.outputs.url }} + CYPRESS_dhis2InstanceVersion: ${{matrix.versions}} + CYPRESS_dhis2Username: ${{ secrets.username }} + CYPRESS_dhis2Password: ${{ secrets.password }} + CYPRESS_networkMode: live + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + e2e-smoke-success: + needs: e2e-smoke-tests + if: ${{ success() || failure() }} + runs-on: ubuntu-latest + steps: + - run: if [ $result != 'success' ]; then exit 1; fi; + env: + result: ${{ needs.e2e-smoke-tests.result }} diff --git a/.github/workflows/verify-pr.yml b/.github/workflows/verify-pr.yml index f96ebd35a..42f61d26c 100644 --- a/.github/workflows/verify-pr.yml +++ b/.github/workflows/verify-pr.yml @@ -80,9 +80,19 @@ jobs: - name: Test run: yarn d2-app-scripts test - call-workflow-e2e-prod: + call-workflow-e2e-smoke: if: "!contains(github.event.head_commit.message, '[skip ci]')" needs: [build, lint, test, setup-matrix] + uses: ./.github/workflows/e2e-smoke.yml + with: + should_record: false + secrets: + username: ${{ secrets.CYPRESS_DHIS2_USERNAME }} + password: ${{ secrets.CYPRESS_DHIS2_PASSWORD }} + + call-workflow-e2e-prod: + if: "!contains(github.event.head_commit.message, '[skip ci]')" + needs: [call-workflow-e2e-smoke] uses: dhis2/workflows/.github/workflows/analytics-e2e-tests-prod.yml@feat/support-hardcoded-dev-version with: should_record: ${{ contains(github.event.head_commit.message, '[e2e record]') || contains(join(github.event.pull_request.labels.*.name), 'e2e record')}} diff --git a/cypress/integration/smoke.cy.js b/cypress/integration/smoke.cy.js index 005b0975e..421a7279b 100644 --- a/cypress/integration/smoke.cy.js +++ b/cypress/integration/smoke.cy.js @@ -4,17 +4,52 @@ import { goToStartPage } from '../helpers/startScreen.js' import { EXTENDED_TIMEOUT } from '../support/util.js' describe('Smoke Test', () => { - it('loads', () => { + it('app loads with correct system and user settings', () => { + cy.intercept('**userSettings**').as('userSettings') + cy.intercept('**systemSettings**').as('systemSettings') + goToStartPage() + cy.log('Check user settings') + cy.wait('@userSettings').then((interception) => { + cy.log('userSettings', interception.response.body) + expect(interception.response.body.keyUiLocale).to.equal('en') + expect( + interception.response.body.keyAnalysisDisplayProperty + ).to.equal('name') + }) + cy.log('Check system settings') + cy.wait('@systemSettings').then((interception) => { + cy.log('systemsettings', interception.response.body) + expect( + interception.response.body.keyAnalysisRelativePeriod + ).to.equal('LAST_12_MONTHS') + expect( + interception.response.body.keyAnalysisDigitGroupSeparator + ).to.equal('SPACE') + }) + + cy.log('Check app is loaded') cy.contains('Getting started', EXTENDED_TIMEOUT).should('be.visible') cy.title().should('equal', 'Line Listing | DHIS2') }) it('loads with visualization id', () => { + cy.intercept('**/api/*/analytics/**').as('getAnalytics') goToAO(TEST_AO.id) + cy.wait('@getAnalytics').then((interception) => { + expect(interception.response.statusCode).to.equal(200) + expect(interception.response.body.rows).to.be.an('array') + }) + cy.getBySel('titlebar', EXTENDED_TIMEOUT) .should('be.visible') .and('contain', TEST_AO.name) + + cy.getBySel('line-list-table') + .findBySel('table-body') + .find('tr') + .its('length') + .should('be.gte', 0) }) })