-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add cypress config and tests [TECH-464] (#1228)
Included in this commit: * cypress configuration based on current DHIS2 convention (cli-utils-cypress initialized the configuration) * tests for viewing dashboard (can be run against actual DHIS2 instance or stubbed fixtures - useful for CI) * tests for creating and deleting dashboard (can only be run against an actual DHIS2 instance) * fixtures for non-mutating tests (viewing dashboard) * github action to run non-mutating tests on CI when creating and updating PRs, and on push to master * README updated with info on how to set up and run the tests * linting forced a function name change for a deprecated react lifecycle method (componentWillReceiveProps to UNSAFE_componentWillReceiveProps). Doesn't affect functionality.
- Loading branch information
1 parent
5f8d9e1
commit 7b66359
Showing
49 changed files
with
3,365 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
const { config } = require('@dhis2/cli-style') | ||
|
||
module.exports = { | ||
extends: [config.eslintReact], | ||
extends: [config.eslintReact, 'plugin:cypress/recommended'], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: 'dhis2: test (cypress)' | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
|
||
env: | ||
SERVER_START_CMD: 'yarn cypress:start' | ||
SERVER_URL: 'http://localhost:3000' | ||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} | ||
CYPRESS_TAGS: '@nonmutating' | ||
cypress_dhis2_base_url: 'http://localhost:8080' | ||
cypress_dhis2_api_stub_mode: 'STUB' | ||
REACT_APP_DHIS2_BASE_URL: 'http://localhost:8080' | ||
|
||
jobs: | ||
e2e: | ||
runs-on: ubuntu-latest | ||
if: "!contains(github.event.head_commit.message, '[skip ci]')" | ||
strategy: | ||
matrix: | ||
containers: [1, 2, 3] | ||
|
||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
|
||
- name: Tests | ||
uses: cypress-io/github-action@v2 | ||
with: | ||
record: true | ||
parallel: true | ||
start: ${{ env.SERVER_START_CMD }} | ||
wait-on: ${{ env.SERVER_URL }} | ||
wait-on-timeout: 60 | ||
group: 'e2e' | ||
env: | ||
CI: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/node_modules/* | ||
/i18n/* | ||
/public/* | ||
/public/* | ||
/cypress/fixtures |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module.exports = { | ||
nonGlobalStepDefinitions: true, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"baseUrl": "http://localhost:3000", | ||
"video": true, | ||
"projectId": "5fk191", | ||
"testFiles": "**/*.feature" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/** | ||
* See | ||
* | ||
* * https://github.com/cypress-io/cypress/issues/95 | ||
* * https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/stubbing-spying__window-fetch | ||
* * https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/stubbing-spying__window-fetch/cypress/integration/polyfill-fetch-from-tests-spec.js | ||
* | ||
* for an explanation why this is currently necessary... | ||
*/ | ||
/* global define */ | ||
!(function(e, n) { | ||
'object' == typeof exports && 'undefined' != typeof module | ||
? (module.exports = n()) | ||
: 'function' == typeof define && define.amd | ||
? define(n) | ||
: (e.unfetch = n()) | ||
})(this, function() { | ||
return function(e, n) { | ||
return ( | ||
(n = n || {}), | ||
new Promise(function(t, o) { | ||
var r = new XMLHttpRequest(), | ||
s = [], | ||
u = [], | ||
i = {}, | ||
f = function() { | ||
return { | ||
ok: 2 == ((r.status / 100) | 0), | ||
statusText: r.statusText, | ||
status: r.status, | ||
url: r.responseURL, | ||
text: function() { | ||
return Promise.resolve(r.responseText) | ||
}, | ||
json: function() { | ||
return Promise.resolve( | ||
JSON.parse(r.responseText) | ||
) | ||
}, | ||
blob: function() { | ||
return Promise.resolve(new Blob([r.response])) | ||
}, | ||
clone: f, | ||
headers: { | ||
keys: function() { | ||
return s | ||
}, | ||
entries: function() { | ||
return u | ||
}, | ||
get: function(e) { | ||
return i[e.toLowerCase()] | ||
}, | ||
has: function(e) { | ||
return e.toLowerCase() in i | ||
}, | ||
}, | ||
} | ||
} | ||
for (var a in (r.open(n.method || 'get', e, !0), | ||
(r.onload = function() { | ||
r | ||
.getAllResponseHeaders() | ||
.replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, function( | ||
e, | ||
n, | ||
t | ||
) { | ||
s.push((n = n.toLowerCase())), | ||
u.push([n, t]), | ||
(i[n] = i[n] ? i[n] + ',' + t : t) | ||
}), | ||
t(f()) | ||
}), | ||
(r.onerror = o), | ||
(r.withCredentials = 'include' == n.credentials), | ||
n.headers)) | ||
r.setRequestHeader(a, n.headers[a]) | ||
r.send(n.body || null) | ||
}) | ||
) | ||
} | ||
}) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
Feature: Creating and deleting dashboard | ||
|
||
@mutating | ||
Scenario: I create a new dashboard | ||
Given I choose to create new dashboard | ||
And dashboard title is added | ||
And dashboard items are added | ||
And escape key is pressed | ||
And dashboard is saved | ||
Then dashboard displays in view mode | ||
And the saved dashboard should be displayed | ||
|
||
@mutating | ||
Scenario: I cancel a delete dashboard action | ||
Given I open existing dashboard | ||
When I choose to edit dashboard | ||
And I choose to delete dashboard | ||
And I cancel delete | ||
Then the dashboard displays in edit mode | ||
|
||
@mutating | ||
Scenario: I delete a dashboard | ||
Given I open existing dashboard | ||
When I choose to edit dashboard | ||
And I choose to delete dashboard | ||
And I confirm delete | ||
Then dashboard displays in view mode | ||
And the dashboard is deleted and first starred dashboard displayed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps' | ||
|
||
// the length of the root route of the app (after the slash): #/ | ||
const ROOT_ROUTE_LENGTH = 0 | ||
// the length of UIDs (after the slash): '#/nghVC4wtyzi' | ||
const UID_LENGTH = 11 | ||
|
||
const TEST_DASHBOARD_TITLE = new Date().toUTCString() | ||
|
||
const ROUTE_EDIT = 'edit' | ||
const ROUTE_NEW = 'new' | ||
const ROUTE_PRINTLAYOUT = 'printlayout' | ||
const ROUTE_PRINTOIPP = 'printoipp' | ||
const nonViewRoutes = [ | ||
ROUTE_NEW, | ||
ROUTE_EDIT, | ||
ROUTE_PRINTLAYOUT, | ||
ROUTE_PRINTOIPP, | ||
] | ||
|
||
const getRouteFromHash = hash => { | ||
const lastSlashIdx = hash.lastIndexOf('/') | ||
return hash.slice(lastSlashIdx + 1) | ||
} | ||
|
||
const toggleShowMoreButton = () => { | ||
cy.get('[data-test="dhis2-dashboard-showmore-button"]').click() | ||
} | ||
|
||
beforeEach(() => { | ||
cy.visit('/') | ||
}) | ||
|
||
Given('I choose to create new dashboard', () => { | ||
cy.get('[data-test="dhis2-dashboard-link-new-dashboard"]').click() | ||
}) | ||
|
||
When('dashboard title is added', () => { | ||
cy.get('[data-test="dhis2-dashboard-dashboard-title-input"]').type( | ||
TEST_DASHBOARD_TITLE | ||
) | ||
}) | ||
|
||
When('dashboard items are added', () => { | ||
cy.get('[data-test="dhis2-dashboard-item-search"]').click() | ||
cy.get( | ||
'[data-test="dhis2-dashboard-menu-item-ANC: 1 and 3 coverage Yearly"]' | ||
).click() | ||
}) | ||
|
||
When('escape key is pressed', () => { | ||
cy.get('body').trigger('keydown', { key: 'Escape' }) | ||
cy.get('[data-test="dhis2-dashboard-item-menu]').should('not.be.visible') | ||
}) | ||
|
||
When('dashboard is saved', () => { | ||
cy.get('[data-test="dhis2-dashboard-save-dashboard-button"]').click() | ||
}) | ||
|
||
Then('the saved dashboard should be displayed', () => { | ||
cy.get('[data-test="dhis2-dashboard-view-dashboard-title"]').contains( | ||
TEST_DASHBOARD_TITLE | ||
) | ||
}) | ||
|
||
Then('dashboard displays in view mode', () => { | ||
cy.location().should(loc => { | ||
const currentRoute = getRouteFromHash(loc.hash) | ||
|
||
expect(nonViewRoutes).not.to.include(currentRoute) | ||
expect([ROOT_ROUTE_LENGTH, UID_LENGTH]).to.include(currentRoute.length) | ||
}) | ||
}) | ||
|
||
Given('I open existing dashboard', () => { | ||
toggleShowMoreButton() | ||
cy.get('[data-test="dhis2-dashboard-dashboard-chip"]') | ||
.contains(TEST_DASHBOARD_TITLE) | ||
.click() | ||
}) | ||
|
||
When('I choose to edit dashboard', () => { | ||
cy.get('[data-test="dhis2-dashboard-link-edit-dashboard"]').click() | ||
}) | ||
|
||
When('I choose to delete dashboard', () => { | ||
cy.get('[data-test="dhis2-dashboard-delete-dashboard-button"]').click() | ||
}) | ||
|
||
When('I confirm delete', () => { | ||
cy.get('[data-test="dhis2-dashboard-confirm-delete-dashboard"]').click() | ||
}) | ||
|
||
When('I cancel delete', () => { | ||
cy.get('[data-test="dhis2-dashboard-cancel-delete-dashboard"]').click() | ||
}) | ||
|
||
Then('the dashboard displays in edit mode', () => { | ||
cy.get('[data-test="dhis2-dashboard-dashboard-title-input"]').should( | ||
'exist' | ||
) | ||
|
||
cy.location().should(loc => { | ||
expect(getRouteFromHash(loc.hash)).to.eq(ROUTE_EDIT) | ||
}) | ||
}) | ||
|
||
Then('the dashboard is deleted and first starred dashboard displayed', () => { | ||
toggleShowMoreButton() | ||
cy.get('[data-test="dhis2-dashboard-dashboard-chip"]') | ||
.contains(TEST_DASHBOARD_TITLE) | ||
.should('not.exist') | ||
|
||
cy.get('[data-test="dhis2-dashboard-view-dashboard-title"]') | ||
.should('exist') | ||
.should('not.be.empty') | ||
}) |
Oops, something went wrong.