diff --git a/test/public/defaults.js b/test/public/defaults.js index d841c4bc05..0523d8462b 100644 --- a/test/public/defaults.js +++ b/test/public/defaults.js @@ -275,12 +275,26 @@ exports.waitForNavigation = waitForNavigation; * @returns {Promise} Whether the element was clickable or not. */ module.exports.pressElement = async (page, selector, jsClick = false) => { - const elementHandler = await page.waitForSelector(selector); + await page.waitForFunction( + (sel, isJsClick) => { + const element = document.querySelector(sel); + + if (!element) { + return false; + } + // Moving the click to outside the function causes it to fail for unknown reasons + if (isJsClick) { + element.click(); + } - if (jsClick) { - await elementHandler.evaluate((element) => element.click()); - } else { - await elementHandler.click(selector); + return true; + }, + {}, + selector, jsClick + ); + + if (!jsClick) { + await page.click(selector); } }; @@ -855,10 +869,10 @@ module.exports.testTableSortingByColumn = async (page, columnId) => { * @return {Promise} resolve once data was successfully validated */ module.exports.validateTableData = async (page, validators) => { - await page.waitForSelector('table tbody'); for (const [columnId, validator] of validators) { + await page.waitForSelector(`table tbody .column-${columnId}`); + const columnData = await getColumnCellsInnerTexts(page, columnId); - expect(columnData, `Too few values for column ${columnId} or there is no such column`).to.be.length.greaterThan(0); expect( columnData.every((cellData) => validator(cellData)), `Invalid data in column ${columnId}: (${columnData})`, @@ -977,3 +991,14 @@ module.exports.resetFilters = async (page) => { { timeout: 5000 }, ); }; + +/** + * Fuction that waits for a button to become active + * @param {puppeteer.page} page page handler + * @param {string} selector Css selector for the button. + */ +module.exports.waitForButtonToBecomeActive = async (page, selector) => await page.waitForFunction((sel) => { + const button = document.querySelector(sel); + return button && !button.disabled; + }, {}, selector); + diff --git a/test/public/runs/overview.test.js b/test/public/runs/overview.test.js index 807b821ffc..3b7cb97da4 100644 --- a/test/public/runs/overview.test.js +++ b/test/public/runs/overview.test.js @@ -40,6 +40,7 @@ const { getColumnCellsInnerTexts, resetFilters, openFilteringPanel, + waitForButtonToBecomeActive, } = require('../defaults.js'); const { RUN_QUALITIES, RunQualities } = require('../../../lib/domain/enums/RunQualities.js'); const { resetDatabaseContent } = require('../../utilities/resetDatabaseContent.js'); @@ -885,6 +886,7 @@ module.exports = () => { let exportModal = await page.$('#export-data-modal'); expect(exportModal).to.be.null; + await waitForButtonToBecomeActive(page, EXPORT_RUNS_TRIGGER_SELECTOR); await page.$eval(EXPORT_RUNS_TRIGGER_SELECTOR, (button) => button.click()); await page.waitForSelector('#export-data-modal', { timeout: 5000 }); exportModal = await page.$('#export-data-modal'); @@ -893,6 +895,7 @@ module.exports = () => { }); it('should successfully display information when export will be truncated', async () => { + await waitForButtonToBecomeActive(page, EXPORT_RUNS_TRIGGER_SELECTOR); await pressElement(page, EXPORT_RUNS_TRIGGER_SELECTOR, true); const truncatedExportWarning = await page.waitForSelector('#export-data-modal #truncated-export-warning'); @@ -912,6 +915,7 @@ module.exports = () => { }); it('should successfully export filtered runs', async () => { + await waitForButtonToBecomeActive(page, EXPORT_RUNS_TRIGGER_SELECTOR); const targetFileName = 'data.json'; // First export diff --git a/test/public/runs/runsPerDataPass.overview.test.js b/test/public/runs/runsPerDataPass.overview.test.js index 0a6b3df7af..f887ab9fae 100644 --- a/test/public/runs/runsPerDataPass.overview.test.js +++ b/test/public/runs/runsPerDataPass.overview.test.js @@ -665,8 +665,8 @@ module.exports = () => { // Press again actions dropdown to re-trigger render await pressElement(page, '#actions-dropdown-button .popover-trigger', true); setConfirmationDialogToBeAccepted(page); - await pressElement(page, `${popoverSelector} button:nth-child(4)`, true); const oldTable = await page.waitForSelector('table').then((table) => table.evaluate((t) => t.innerHTML)); + await pressElement(page, `${popoverSelector} button:nth-child(4)`, true); await pressElement(page, '#actions-dropdown-button .popover-trigger', true); await waitForTableLength(page, 3, undefined, oldTable); // Processing of data might take a bit of time, but then expect QC flag button to be there diff --git a/test/public/runs/runsPerLhcPeriod.overview.test.js b/test/public/runs/runsPerLhcPeriod.overview.test.js index 75b5eb978c..273baca07d 100644 --- a/test/public/runs/runsPerLhcPeriod.overview.test.js +++ b/test/public/runs/runsPerLhcPeriod.overview.test.js @@ -32,6 +32,7 @@ const { expectColumnValues, openFilteringPanel, resetFilters, + waitForButtonToBecomeActive } = require('../defaults.js'); const { RUN_QUALITIES, RunQualities } = require('../../../lib/domain/enums/RunQualities.js'); const { resetDatabaseContent } = require('../../utilities/resetDatabaseContent.js'); @@ -75,6 +76,7 @@ module.exports = () => { after(async () => { [page, browser] = await defaultAfter(page, browser); }); + const EXPORT_RUNS_TRIGGER_SELECTOR = '#export-data-trigger'; it('loads the page successfully', async () => { const response = await goToPage(page, 'runs-per-lhc-period', { queryParameters: { lhcPeriodId: 1 } }); @@ -204,7 +206,6 @@ module.exports = () => { await waitForTableLength(page, 4); }); - const EXPORT_RUNS_TRIGGER_SELECTOR = '#export-data-trigger'; it('should successfully export all runs per lhc Period', async () => { await page.evaluate(() => { @@ -213,7 +214,7 @@ module.exports = () => { }); const targetFileName = 'data.json'; - + await waitForButtonToBecomeActive(page, EXPORT_RUNS_TRIGGER_SELECTOR); // First export await pressElement(page, EXPORT_RUNS_TRIGGER_SELECTOR, true); await page.waitForSelector('select.form-control', { timeout: 200 }); @@ -286,9 +287,9 @@ module.exports = () => { await navigateToRunsPerLhcPeriod(page, 1, 4); const targetFileName = 'data.csv'; - + await waitForButtonToBecomeActive(page, EXPORT_RUNS_TRIGGER_SELECTOR); // Export - await pressElement(page, '#export-data-trigger'); + await pressElement(page, EXPORT_RUNS_TRIGGER_SELECTOR); await page.waitForSelector('#export-data-modal'); await page.waitForSelector('#send:disabled'); await page.waitForSelector('.form-control'); diff --git a/test/public/runs/runsPerSimulationPass.overview.test.js b/test/public/runs/runsPerSimulationPass.overview.test.js index 112d6b5b7d..e6748ffb94 100644 --- a/test/public/runs/runsPerSimulationPass.overview.test.js +++ b/test/public/runs/runsPerSimulationPass.overview.test.js @@ -31,6 +31,7 @@ const { testTableSortingByColumn, waitForTableLength, expectColumnValues, + waitForButtonToBecomeActive, } = require('../defaults.js'); const { expect } = chai; @@ -74,6 +75,8 @@ module.exports = () => { [page, browser] = await defaultAfter(page, browser); }); + const EXPORT_RUNS_TRIGGER_SELECTOR = '#export-data-trigger'; + it('loads the page successfully', async () => { const response = await goToPage(page, 'runs-per-simulation-pass', { queryParameters: { simulationPassId: 2 } }); @@ -235,11 +238,10 @@ module.exports = () => { it('should successfully export runs', async () => { await navigateToRunsPerSimulationPass(page, 1, 2, 3); - const EXPORT_RUNS_TRIGGER_SELECTOR = '#export-data-trigger'; - const targetFileName = 'data.json'; // Export + await waitForButtonToBecomeActive(page, EXPORT_RUNS_TRIGGER_SELECTOR); await pressElement(page, EXPORT_RUNS_TRIGGER_SELECTOR); await page.waitForSelector('#export-data-modal'); await page.waitForSelector('#send:disabled'); @@ -270,7 +272,8 @@ module.exports = () => { const targetFileName = 'data.csv'; // Export - await pressElement(page, '#export-data-trigger'); + await waitForButtonToBecomeActive(page, EXPORT_RUNS_TRIGGER_SELECTOR); + await pressElement(page, EXPORT_RUNS_TRIGGER_SELECTOR); await page.waitForSelector('#export-data-modal'); await page.waitForSelector('#send:disabled'); await page.waitForSelector('.form-control');