diff --git a/.github/workflows/dhis2-preview-pr.yml b/.github/workflows/dhis2-preview-pr.yml index 27a52daf87..e5bf971cce 100644 --- a/.github/workflows/dhis2-preview-pr.yml +++ b/.github/workflows/dhis2-preview-pr.yml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 14.x + node-version: 18.x - uses: c-hive/gha-yarn-cache@v1 - run: yarn install --frozen-lockfile diff --git a/cypress.config.js b/cypress.config.js index 6ce2dc5d61..12810c2f08 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -1,3 +1,4 @@ +const fs = require('fs') const { chromeAllowXSiteCookies } = require('@dhis2/cypress-plugins') const { defineConfig } = require('cypress') const { @@ -8,6 +9,28 @@ async function setupNodeEvents(on, config) { chromeAllowXSiteCookies(on, config) excludeByVersionTags(on, config) + // Delete videos for passing tests + on('after:spec', (spec, results) => { + try { + if (results && results.video) { + // Do we have failures for any retry attempts? + const failures = results.tests.some((test) => + test.attempts.some((attempt) => attempt.state === 'failed') + ) + if (!failures) { + // delete the video if the spec passed and no tests retried + fs.unlinkSync(results.video) + } + } + } catch (error) { + if (error.code === 'ENOENT') { + console.log('Video already deleted') + } else { + throw error + } + } + }) + if (!config.env.dhis2InstanceVersion) { throw new Error( 'dhis2InstanceVersion is missing. Check the README for more information.' @@ -59,10 +82,6 @@ module.exports = defineConfig({ testIsolation: false, // Record video video: true, - /* Only compress and upload videos for failures. - * This will save execution time and reduce the risk - * out-of-memory issues on the CI machine */ - videoUploadOnPasses: false, // Enabled to reduce the risk of out-of-memory issues experimentalMemoryManagement: true, // Set to a low number to reduce the risk of out-of-memory issues diff --git a/cypress/integration/dimensions/data.cy.js b/cypress/integration/dimensions/data.cy.js index 90c245e4c9..98932758fa 100644 --- a/cypress/integration/dimensions/data.cy.js +++ b/cypress/integration/dimensions/data.cy.js @@ -48,159 +48,162 @@ const PAGE_SIZE = 50 const DATA_ITEMS_URL = '**/dataItems*' describe('Data dimension', () => { - describe('initial state', () => { - it('navigates to the start page', () => { - goToStartPage() - }) - it('opens the data dimension modal', () => { - cy.intercept('GET', DATA_ITEMS_URL).as('request') - openDimension(DIMENSION_ID_DATA) - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.eq(PAGE_SIZE) - }) - expectDataDimensionModalToBeVisible() - }) - it('modal has a title', () => { - expectDimensionModalToContain('Data') - }) - it('no items are selected', () => { - expectNoDataItemsToBeSelected() - }) - it("data type is 'All'", () => { - expectDataTypeToBe('All') - }) - it('group select is not visible', () => { - expectGroupSelectToNotBeVisible() + it('has correct initial state', () => { + // navigates to the start page + goToStartPage() + + // opens the data dimension modal + cy.intercept('GET', DATA_ITEMS_URL).as('request') + openDimension(DIMENSION_ID_DATA) + cy.wait('@request').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.eq(PAGE_SIZE) }) + expectDataDimensionModalToBeVisible() + + // modal has a title + expectDimensionModalToContain('Data') + + // no items are selected + expectNoDataItemsToBeSelected() + + // data type is 'All' + expectDataTypeToBe('All') + + // group select is not visible + expectGroupSelectToNotBeVisible() + + // an item can be selected by double click const firstPageItemName = TEST_INDICATORS[0].name - it('an item can be selected by double click', () => { - selectItemByDoubleClick(firstPageItemName) - expectItemToBeSelected(firstPageItemName) - }) - it('an item can be unselected by double click', () => { - unselectItemByDoubleClick(firstPageItemName) - expectNoDataItemsToBeSelected() - }) - it('an item can be selected by button', () => { - selectItemByButton(firstPageItemName) - expectItemToBeSelected(firstPageItemName) - }) - it('an item can be unselected by button', () => { - unselectItemByButton(firstPageItemName) - expectNoDataItemsToBeSelected() - }) + selectItemByDoubleClick(firstPageItemName) + expectItemToBeSelected(firstPageItemName) + + // an item can be unselected by double click + unselectItemByDoubleClick(firstPageItemName) + expectNoDataItemsToBeSelected() + + // an item can be selected by button + selectItemByButton(firstPageItemName) + expectItemToBeSelected(firstPageItemName) + + // an item can be unselected by button + unselectItemByButton(firstPageItemName) + expectNoDataItemsToBeSelected() }) - describe('selecting all and fetching more', () => { + it('can select all and fetch more', () => { + goToStartPage() + openDimension(DIMENSION_ID_DATA) + expectDataDimensionModalToBeVisible() + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + const secondPageItemName = 'BCG doses' - it('all items can be selected', () => { - cy.intercept('GET', DATA_ITEMS_URL).as('request') - selectAllItemsByButton() - expectSelectedItemsAmountToBeLeast(PAGE_SIZE) - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=2') - expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.eq(PAGE_SIZE) - }) - expectSourceToNotBeLoading() + // all items can be selected + cy.intercept('GET', DATA_ITEMS_URL).as('request') + selectAllItemsByButton() + expectSelectedItemsAmountToBeLeast(PAGE_SIZE) + cy.wait('@request').then(({ request, response }) => { + expect(request.url).to.contain('page=2') + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.eq(PAGE_SIZE) }) - it('more items are fetched', () => { - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) - expectItemToBeSelectable(secondPageItemName) - }) - it('all items can be unselected', () => { - unselectAllItemsByButton() - expectNoDataItemsToBeSelected() - }) - it('more items are fetched when scrolling down', () => { - cy.intercept('GET', DATA_ITEMS_URL).as('request') - scrollSourceToBottom() - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=3') - expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.eq(PAGE_SIZE) - }) - expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE * 3) + expectSourceToNotBeLoading() + + // more items are fetched + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + expectItemToBeSelectable(secondPageItemName) + + // all items can be unselected + unselectAllItemsByButton() + expectNoDataItemsToBeSelected() + + // more items are fetched when scrolling down + cy.intercept('GET', DATA_ITEMS_URL).as('request') + scrollSourceToBottom() + cy.wait('@request').then(({ request, response }) => { + expect(request.url).to.contain('page=3') + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.eq(PAGE_SIZE) }) + expectSourceToNotBeLoading() + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE * 3) }) - describe('global search', () => { + it('can use global search', () => { + goToStartPage() + openDimension(DIMENSION_ID_DATA) + expectDataDimensionModalToBeVisible() + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + const testSearchTerm = 'Dispenser' // Use a data element for the third step to work - it('receives a search term', () => { - cy.intercept('GET', DATA_ITEMS_URL).as('request') - inputSearchTerm(testSearchTerm) - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(request.url).to.contain(testSearchTerm) - expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.eq(1) - }) - expectSourceToNotBeLoading() + // receives a search term + cy.intercept('GET', DATA_ITEMS_URL).as('request') + inputSearchTerm(testSearchTerm) + cy.wait('@request').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(request.url).to.contain(testSearchTerm) + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.eq(1) }) + expectSourceToNotBeLoading() + // TODO: Test that the search is only called once, i.e. debounce works - it('search result is displayed', () => { - expectSelectableDataItemsAmountToBe(1) - expectItemToBeSelectable(testSearchTerm) + // search result is displayed + expectSelectableDataItemsAmountToBe(1) + expectItemToBeSelectable(testSearchTerm) + + // search result is maintained when switching data type + cy.intercept('GET', '**/dataElements*').as('dataElements') + switchDataTypeTo('Data elements') + cy.wait('@dataElements').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) + expect(response.body.dataElements.length).to.be.eq(1) }) - it('search result is maintained when switching data type', () => { - cy.intercept('GET', '**/dataElements*').as('dataElements') - switchDataTypeTo('Data elements') - cy.wait('@dataElements').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - expect(response.body.dataElements.length).to.be.eq(1) - }) - expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBe(1) - expectItemToBeSelectable(testSearchTerm) - clearSearchTerm() - cy.wait('@dataElements').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - expect(response.body.dataElements.length).to.be.eq(PAGE_SIZE) - }) - expectSourceToNotBeLoading() - cy.intercept('GET', DATA_ITEMS_URL).as('dataItems') - switchDataTypeToAll() - cy.wait('@dataItems').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.eq(PAGE_SIZE) - }) - expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + expectSourceToNotBeLoading() + expectSelectableDataItemsAmountToBe(1) + expectItemToBeSelectable(testSearchTerm) + clearSearchTerm() + cy.wait('@dataElements').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) + expect(response.body.dataElements.length).to.be.eq(PAGE_SIZE) }) - it('search displays a correct error message', () => { - const testSearchTermWithNoMatch = 'nomatch' - cy.intercept('GET', DATA_ITEMS_URL).as('request') - inputSearchTerm(testSearchTermWithNoMatch) - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(request.url).to.contain(testSearchTermWithNoMatch) - expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.eq(0) - }) - expectSourceToNotBeLoading() - expectEmptySourceMessageToBe( - `Nothing found for "${testSearchTermWithNoMatch}"` - ) + expectSourceToNotBeLoading() + cy.intercept('GET', DATA_ITEMS_URL).as('dataItems') + switchDataTypeToAll() + cy.wait('@dataItems').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.eq(PAGE_SIZE) }) - it('search result can be cleared', () => { - cy.intercept('GET', DATA_ITEMS_URL).as('request') - clearSearchTerm() - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.be.eq(PAGE_SIZE) - }) - expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + expectSourceToNotBeLoading() + + // search displays a correct error message + const testSearchTermWithNoMatch = 'nomatch' + cy.intercept('GET', DATA_ITEMS_URL).as('requestNoMatch') + inputSearchTerm(testSearchTermWithNoMatch) + cy.wait('@requestNoMatch').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(request.url).to.contain(testSearchTermWithNoMatch) + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.eq(0) }) - it('modal is closed', () => { - clickDimensionModalHideButton() - expectDimensionModalToNotBeVisible() + expectSourceToNotBeLoading() + expectEmptySourceMessageToBe( + `Nothing found for "${testSearchTermWithNoMatch}"` + ) + + // search result can be cleared + cy.intercept('GET', DATA_ITEMS_URL).as('requestClear') + clearSearchTerm() + cy.wait('@requestClear').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.be.eq(PAGE_SIZE) }) + expectSourceToNotBeLoading() + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) }) const testDataTypes = [ { @@ -272,89 +275,92 @@ describe('Data dimension', () => { }, ] testDataTypes.forEach((testDataType) => { - describe(`${testDataType.name}`, () => { - it('opens the data dimension modal', () => { - openDimension(DIMENSION_ID_DATA) - expectDataDimensionModalToBeVisible() + it(`displays ${testDataType.name} correctly`, () => { + // opens the data dimension modal + goToStartPage() + openDimension(DIMENSION_ID_DATA) + expectDataDimensionModalToBeVisible() + + // switches to type + cy.log(`type: ${testDataType.name}`) + cy.intercept('GET', testDataType.endpoint.requestUrl).as('request') + switchDataTypeTo(testDataType.name) + cy.wait('@request').then(({ response }) => { + expect(response.statusCode).to.eq(200) + expect( + response.body[testDataType.endpoint.responseBody].length + ).to.be.least(1) }) - it(`switches to ${testDataType.name}`, () => { + expectSourceToNotBeLoading() + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + + // group select is visible + expectGroupSelectToBeVisible() + expectGroupSelectToBe(testDataType.defaultGroup.name) + + if (testDataType.endpoint.hasMultiplePages) { + // more items are fetched when scrolling down cy.intercept('GET', testDataType.endpoint.requestUrl).as( 'request' ) - switchDataTypeTo(testDataType.name) - cy.wait('@request').then(({ response }) => { + scrollSourceToBottom() + cy.wait('@request').then(({ request, response }) => { + expect(request.url).to.contain('page=2') expect(response.statusCode).to.eq(200) expect( response.body[testDataType.endpoint.responseBody].length ).to.be.least(1) }) expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) - }) - it('group select is visible', () => { - expectGroupSelectToBeVisible() - expectGroupSelectToBe(testDataType.defaultGroup.name) - }) - if (testDataType.endpoint.hasMultiplePages) { - it('more items are fetched when scrolling down', () => { - cy.intercept('GET', testDataType.endpoint.requestUrl).as( - 'request' - ) - scrollSourceToBottom() - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=2') - expect(response.statusCode).to.eq(200) - expect( - response.body[testDataType.endpoint.responseBody] - .length - ).to.be.least(1) - }) - expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE + 1) - }) + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE + 1) } - it('an item can be selected', () => { - expectDataItemsToBeInSource([testDataType.testItem.name]) - selectItemByDoubleClick(testDataType.testItem.name) - expectItemToBeSelected(testDataType.testItem.name) - }) - it(`group can be changed to "${testDataType.testGroup.name}"`, () => { - cy.intercept('GET', testDataType.endpoint.requestUrl).as( - 'request' - ) - switchGroupTo(testDataType.testGroup.name) - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - }) - expectSourceToNotBeLoading() - expectGroupSelectToBe(testDataType.testGroup.name) - expectSelectableDataItemsAmountToBe( - testDataType.testGroup.itemAmount - ) - expectItemToBeSelected(testDataType.testItem.name) - }) - it('the first item can be selected', () => { - selectFirstDataItem() - expectSelectedItemsAmountToBe(2) - expectSelectableDataItemsAmountToBe( - testDataType.testGroup.itemAmount - 1 - ) + // an item can be selected + expectDataItemsToBeInSource([testDataType.testItem.name]) + selectItemByDoubleClick(testDataType.testItem.name) + expectItemToBeSelected(testDataType.testItem.name) + + // group can be changed + cy.log(`group: ${testDataType.testGroup.name}`) + cy.intercept('GET', testDataType.endpoint.requestUrl).as( + 'requestWithGroup' + ) + switchGroupTo(testDataType.testGroup.name) + cy.wait('@requestWithGroup').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) }) + expectSourceToNotBeLoading() + expectGroupSelectToBe(testDataType.testGroup.name) + cy.getBySel('data-dimension-transfer-sourceoptions').trigger( + 'mouseover' + ) // seems to trigger Cypress to refretch the list and update the result so it's no longer stale + expectSelectableDataItemsAmountToBe( + testDataType.testGroup.itemAmount + ) + expectItemToBeSelected(testDataType.testItem.name) + + // the first item can be selected + selectFirstDataItem() + expectSelectedItemsAmountToBe(2) + expectSelectableDataItemsAmountToBe( + testDataType.testGroup.itemAmount - 1 + ) + if (['Data elements', 'Data sets'].includes(testDataType.name)) { - it('sub group select is visible', () => { - expectSubGroupSelectToBeVisible() - expectSubGroupSelectToBe(testDataType.defaultSubGroup.name) - }) + // sub group select is visible + expectSubGroupSelectToBeVisible() + expectSubGroupSelectToBe(testDataType.defaultSubGroup.name) - it(`sub group can be changed to "${testDataType.testSubGroup.name}"`, () => { - cy.intercept( - 'GET', - testDataType.testSubGroup.endpoint?.requestUrl || - testDataType.endpoint.requestUrl - ).as('request') - switchSubGroupTo(testDataType.testSubGroup.name) - cy.wait('@request').then(({ request, response }) => { + // sub group can be changed + cy.log(`sub group: ${testDataType.testSubGroup.name}`) + cy.intercept( + 'GET', + testDataType.testSubGroup.endpoint?.requestUrl || + testDataType.endpoint.requestUrl + ).as('requestWithSubGroup') + switchSubGroupTo(testDataType.testSubGroup.name) + cy.wait('@requestWithSubGroup').then( + ({ request, response }) => { expect(request.url).to.contain('page=1') expect(response.statusCode).to.eq(200) expect( @@ -364,92 +370,94 @@ describe('Data dimension', () => { testDataType.endpoint.responseBody ].length ).to.be.eq(testDataType.testSubGroup.itemAmount) - }) - expectSourceToNotBeLoading() - expectSubGroupSelectToBe(testDataType.testSubGroup.name) - expectSelectableDataItemsAmountToBe( - testDataType.testSubGroup.itemAmount - ) - expectItemToBeSelected(testDataType.testItem.name) - }) - it(`sub group can be changed back to "${testDataType.defaultSubGroup.name}"`, () => { - cy.intercept('GET', testDataType.endpoint.requestUrl).as( - 'request' - ) - switchSubGroupTo(testDataType.defaultSubGroup.name) - cy.wait('@request').then(({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - }) - expectSourceToNotBeLoading() - expectSubGroupSelectToBe(testDataType.defaultSubGroup.name) - expectSelectableDataItemsAmountToBe( - testDataType.testGroup.itemAmount - 1 - ) - expectItemToBeSelected(testDataType.testItem.name) - }) - } - it('search displays a correct error message', () => { - const testSearchTermWithNoMatch = 'nomatch' + } + ) + expectSourceToNotBeLoading() + expectSubGroupSelectToBe(testDataType.testSubGroup.name) + expectSelectableDataItemsAmountToBe( + testDataType.testSubGroup.itemAmount + ) + expectItemToBeSelected(testDataType.testItem.name) + + // sub group can be changed back to default + cy.log( + `default sub group: ${testDataType.defaultSubGroup.name}` + ) cy.intercept('GET', testDataType.endpoint.requestUrl).as( 'request' ) - inputSearchTerm(testSearchTermWithNoMatch) + switchSubGroupTo(testDataType.defaultSubGroup.name) cy.wait('@request').then(({ request, response }) => { expect(request.url).to.contain('page=1') - expect(request.url).to.contain(testSearchTermWithNoMatch) expect(response.statusCode).to.eq(200) - expect( - response.body[testDataType.endpoint.responseBody].length - ).to.eq(0) }) expectSourceToNotBeLoading() - expectEmptySourceMessageToBe( - `No ${testDataType.name.toLowerCase()} found for "${testSearchTermWithNoMatch}"` - ) - }) - it('selection and filter can be reset', () => { - unselectAllItemsByButton() - expectNoDataItemsToBeSelected() - cy.intercept('GET', testDataType.endpoint.requestUrl).as( - testDataType.endpoint.requestUrl - ) - clearSearchTerm() - cy.wait(`@${testDataType.endpoint.requestUrl}`).then( - ({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - } - ) - expectSourceToNotBeLoading() + expectSubGroupSelectToBe(testDataType.defaultSubGroup.name) expectSelectableDataItemsAmountToBe( - testDataType.testGroup.itemAmount - ) - switchGroupToAll() - cy.wait(`@${testDataType.endpoint.requestUrl}`).then( - ({ request, response }) => { - expect(request.url).to.contain('page=1') - expect(response.statusCode).to.eq(200) - } + testDataType.testGroup.itemAmount - 1 ) - expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) - if (testDataType.endpoint.requestUrl !== DATA_ITEMS_URL) { - cy.intercept('GET', DATA_ITEMS_URL).as('**/dataItems*') + expectItemToBeSelected(testDataType.testItem.name) + } + // search displays a correct error message + const testSearchTermWithNoMatch = 'nomatch' + cy.intercept('GET', testDataType.endpoint.requestUrl).as( + 'requestNoMatch' + ) + inputSearchTerm(testSearchTermWithNoMatch) + cy.wait('@requestNoMatch').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(request.url).to.contain(testSearchTermWithNoMatch) + expect(response.statusCode).to.eq(200) + expect( + response.body[testDataType.endpoint.responseBody].length + ).to.eq(0) + }) + expectSourceToNotBeLoading() + expectEmptySourceMessageToBe( + `No ${testDataType.name.toLowerCase()} found for "${testSearchTermWithNoMatch}"` + ) + + // selection and filter can be reset + unselectAllItemsByButton() + expectNoDataItemsToBeSelected() + cy.intercept('GET', testDataType.endpoint.requestUrl).as( + testDataType.endpoint.requestUrl + ) + clearSearchTerm() + cy.wait(`@${testDataType.endpoint.requestUrl}`).then( + ({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) } - switchDataTypeToAll() - cy.wait('@**/dataItems*').then(({ request, response }) => { + ) + expectSourceToNotBeLoading() + expectSelectableDataItemsAmountToBe( + testDataType.testGroup.itemAmount + ) + switchGroupToAll() + cy.wait(`@${testDataType.endpoint.requestUrl}`).then( + ({ request, response }) => { expect(request.url).to.contain('page=1') expect(response.statusCode).to.eq(200) - expect(response.body.dataItems.length).to.eq(PAGE_SIZE) - }) - expectSourceToNotBeLoading() - expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) - }) - it('modal is closed', () => { - clickDimensionModalHideButton() - expectDimensionModalToNotBeVisible() + } + ) + expectSourceToNotBeLoading() + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + if (testDataType.endpoint.requestUrl !== DATA_ITEMS_URL) { + cy.intercept('GET', DATA_ITEMS_URL).as('**/dataItems*') + } + switchDataTypeToAll() + cy.wait('@**/dataItems*').then(({ request, response }) => { + expect(request.url).to.contain('page=1') + expect(response.statusCode).to.eq(200) + expect(response.body.dataItems.length).to.eq(PAGE_SIZE) }) + expectSourceToNotBeLoading() + expectSelectableDataItemsAmountToBeLeast(PAGE_SIZE) + + // modal is closed + clickDimensionModalHideButton() + expectDimensionModalToNotBeVisible() }) }) }) diff --git a/cypress/integration/options/fontStyles.cy.js b/cypress/integration/options/fontStyles.cy.js index 2cbee29b55..366f519265 100644 --- a/cypress/integration/options/fontStyles.cy.js +++ b/cypress/integration/options/fontStyles.cy.js @@ -168,7 +168,6 @@ describe('Options - Font styles', () => { const TEST_SUBTITLE_TEXT = 'S' it('has default value', () => { - expectChartSubtitleToBeVisible() expectWindowConfigSubtitleToBeValue(CONFIG_DEFAULT_SUBTITLE) }) it('opens Options -> Style', () => { diff --git a/package.json b/package.json index 93959761c3..4226931bb1 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@dhis2/cypress-plugins": "^10.0.2", "@reportportal/agent-js-cypress": "git+https://github.com/dhis2/agent-js-cypress.git#develop", "@reportportal/agent-js-jest": "^5.0.6", - "cypress": "^12.16.0", + "cypress": "^13.6.1", "cypress-tags": "^1.1.2", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.7", diff --git a/yarn.lock b/yarn.lock index f36c919257..ac4840ccc5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1416,10 +1416,10 @@ through2 "^2.0.0" watchify "^4.0.0" -"@cypress/request@^2.88.10": - version "2.88.11" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.11.tgz#5a4c7399bc2d7e7ed56e92ce5acb620c8b187047" - integrity sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w== +"@cypress/request@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@cypress/request/-/request-3.0.1.tgz#72d7d5425236a2413bd3d8bb66d02d9dc3168960" + integrity sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -1434,9 +1434,9 @@ json-stringify-safe "~5.0.1" mime-types "~2.1.19" performance-now "^2.1.0" - qs "~6.10.3" + qs "6.10.4" safe-buffer "^5.1.2" - tough-cookie "~2.5.0" + tough-cookie "^4.1.3" tunnel-agent "^0.6.0" uuid "^8.3.2" @@ -2985,19 +2985,7 @@ "@reportportal/client-javascript" "^5.0.12" strip-ansi "^6.0.1" -"@reportportal/client-javascript@^5.0.12": - version "5.0.12" - resolved "https://registry.yarnpkg.com/@reportportal/client-javascript/-/client-javascript-5.0.12.tgz#b6d9254014545ca56599c05105854ea814561f1e" - integrity sha512-ECLvuDLV7KyKs0wG9Sis3ZqHOq9VMg3fywm1VDegd5HGDKC1hoXxFKfz6ngPY8FZ5O1nt1UJvgEs47shtPHQCg== - dependencies: - axios "^0.27.2" - axios-retry "^3.4.0" - glob "^7.2.3" - ini "^2.0.0" - uniqid "^5.4.0" - uuid "^9.0.0" - -"@reportportal/client-javascript@^5.0.14": +"@reportportal/client-javascript@^5.0.12", "@reportportal/client-javascript@^5.0.14": version "5.0.14" resolved "https://registry.yarnpkg.com/@reportportal/client-javascript/-/client-javascript-5.0.14.tgz#48a40f2f33129d74bb7e451aaf25d44742e26fcc" integrity sha512-4ge9ddOB1rFlzqI6j43qCw0cyjQOloiPChA1EFyF3dcV2BXHzGbh8S3SNhwxibvlQtV6piU8e0W9CLN4UWXvSA== @@ -3432,10 +3420,12 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== -"@types/node@*", "@types/node@^14.14.31": - version "14.18.32" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.32.tgz#8074f7106731f1a12ba993fe8bad86ee73905014" - integrity sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow== +"@types/node@*", "@types/node@^18.17.5": + version "18.19.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.3.tgz#e4723c4cb385641d61b983f6fe0b716abd5f8fc0" + integrity sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg== + dependencies: + undici-types "~5.26.4" "@types/parse-json@^4.0.0": version "4.0.0" @@ -6220,14 +6210,14 @@ cypress-tags@^1.1.2: boolean-parser "0.0.2" through "^2.3.8" -cypress@^12.16.0: - version "12.16.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.16.0.tgz#d0dcd0725a96497f4c60cf54742242259847924c" - integrity sha512-mwv1YNe48hm0LVaPgofEhGCtLwNIQEjmj2dJXnAkY1b4n/NE9OtgPph4TyS+tOtYp5CKtRmDvBzWseUXQTjbTg== +cypress@^13.6.1: + version "13.6.1" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-13.6.1.tgz#c5f714f08551666ed3ac1fa95718eabb23a416df" + integrity sha512-k1Wl5PQcA/4UoTffYKKaxA0FJKwg8yenYNYRzLt11CUR0Kln+h7Udne6mdU1cUIdXBDTVZWtmiUjzqGs7/pEpw== dependencies: - "@cypress/request" "^2.88.10" + "@cypress/request" "^3.0.0" "@cypress/xvfb" "^1.2.4" - "@types/node" "^14.14.31" + "@types/node" "^18.17.5" "@types/sinonjs__fake-timers" "8.1.1" "@types/sizzle" "^2.3.2" arch "^2.2.0" @@ -6260,9 +6250,10 @@ cypress@^12.16.0: minimist "^1.2.8" ospath "^1.2.2" pretty-bytes "^5.6.0" + process "^0.11.10" proxy-from-env "1.0.0" request-progress "^3.0.0" - semver "^7.3.2" + semver "^7.5.3" supports-color "^8.1.1" tmp "~0.2.1" untildify "^4.0.0" @@ -12866,7 +12857,7 @@ process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process@~0.11.0: +process@^0.11.10, process@~0.11.0: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== @@ -13003,10 +12994,10 @@ qs@6.10.3: dependencies: side-channel "^1.0.4" -qs@~6.10.3: - version "6.10.5" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4" - integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ== +qs@6.10.4: + version "6.10.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.4.tgz#6a3003755add91c0ec9eacdc5f878b034e73f9e7" + integrity sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g== dependencies: side-channel "^1.0.4" @@ -13035,6 +13026,11 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" @@ -14070,10 +14066,10 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@^7.2.1, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -15263,14 +15259,15 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== +tough-cookie@^4.0.0, tough-cookie@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" - universalify "^0.1.2" + universalify "^0.2.0" + url-parse "^1.5.3" tr46@^1.0.1: version "1.0.1" @@ -15469,6 +15466,11 @@ undeclared-identifiers@^1.1.2: simple-concat "^1.0.0" xtend "^4.0.1" +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -15529,11 +15531,16 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" -universalify@^0.1.0, universalify@^0.1.2: +universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" @@ -15620,6 +15627,14 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + url@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"