From e616ec4409501087a845b76353aef86adb215575 Mon Sep 17 00:00:00 2001 From: George Raduta Date: Thu, 15 Oct 2026 11:49:16 +0200 Subject: [PATCH] Improve reliability of runsperdatapass test --- .../runsPerPeriodOrPass/dataPassesUtilities.js | 13 +++++++++++++ .../runsPerDataPass.overview.test.js | 16 ++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/test/public/runsPerPeriodOrPass/dataPassesUtilities.js b/test/public/runsPerPeriodOrPass/dataPassesUtilities.js index b9b83e29c7..dd45ca7a57 100644 --- a/test/public/runsPerPeriodOrPass/dataPassesUtilities.js +++ b/test/public/runsPerPeriodOrPass/dataPassesUtilities.js @@ -29,8 +29,21 @@ exports.navigateToRunsPerDataPass = async (page, lhcPeriodId, dataPassId, expect await waitForNavigation(page, () => pressElement(page, `#row${lhcPeriodId}-associatedDataPasses a`, true)); expectUrlParams(page, { page: 'data-passes-per-lhc-period-overview', lhcPeriodId }); await page.waitForSelector('th#description'); + + /* + * The runs per data pass model is kept between visits, so the table of the previous visit is displayed until the new runs are + * fetched. Waiting for the runs response ensures the table checked below is the fresh one and will not be re-rendered under the test + */ + const runsResponse = page.waitForResponse( + (response) => { + const { pathname, search } = new URL(response.url()); + return pathname === '/api/runs' && new RegExp(`filter\\[dataPassIds\\]\\[\\d*\\]=${dataPassId}(&|$)`).test(decodeURIComponent(search)); + }, + { timeout: 5000 }, + ); await waitForNavigation(page, () => pressElement(page, `#row${dataPassId}-associatedRuns a`, true)); expectUrlParams(page, { page: 'runs-per-data-pass', dataPassId }, ['pdpBeamType']); + await runsResponse; await waitForTableLength(page, expectedRowsCount); }; diff --git a/test/public/runsPerPeriodOrPass/runsPerDataPass.overview.test.js b/test/public/runsPerPeriodOrPass/runsPerDataPass.overview.test.js index 31aad4c819..400fce924c 100644 --- a/test/public/runsPerPeriodOrPass/runsPerDataPass.overview.test.js +++ b/test/public/runsPerPeriodOrPass/runsPerDataPass.overview.test.js @@ -212,10 +212,9 @@ module.exports = () => { // Navigate to the page to trigger the GAQ requests await navigateToRunsPerDataPass(page, 1, 3, 4); - await page.waitForSelector('table tbody tr'); - // Wait for all GAQ requests to complete - await new Promise((resolve) => setTimeout(resolve, 1000)); + // Wait for the network to settle, so that all GAQ requests (and eventual duplicates) are caught + await page.waitForNetworkIdle({ idleTime: 300, timeout: 5000 }); page.off('request', requestHandler); @@ -285,9 +284,7 @@ module.exports = () => { const amountSelectorId = '#amountSelector'; const amountSelectorButtonSelector = `${amountSelectorId} button`; await pressElement(page, amountSelectorButtonSelector); - - const amountSelectorDropdown = await page.$(`${amountSelectorId} .dropup-menu`); - expect(Boolean(amountSelectorDropdown)).to.be.true; + await page.waitForSelector(`${amountSelectorId} .dropup-menu`); const amountItems5 = `${amountSelectorId} .dropup-menu .menu-item:first-child`; await pressElement(page, amountItems5); @@ -298,7 +295,7 @@ module.exports = () => { await expectInnerText(page, '.dropup button', 'Rows per page: 5 '); // Expect the custom per page input to have red border and text color if wrong value typed - const customPerPageInput = await page.$(`${amountSelectorId} input[type=number]`); + const customPerPageInput = await page.waitForSelector(`${amountSelectorId} input[type=number]`); await customPerPageInput.evaluate((input) => input.focus()); await page.$eval(`${amountSelectorId} input[type=number]`, (el) => { el.value = '1111'; @@ -332,10 +329,9 @@ module.exports = () => { it('can navigate to a run detail page', async () => { await navigateToRunsPerDataPass(page, 1, 3, 4); - await page.waitForSelector('tbody tr'); const expectedRunNumber = await getInnerText(await page.waitForSelector('tbody tr:first-of-type a')); - await waitForNavigation(page, async () => await pressElement(page, 'tbody tr:first-of-type a')); + await waitForNavigation(page, () => pressElement(page, 'tbody tr:first-of-type a', true)); const redirectedUrl = await page.url(); const urlParameters = redirectedUrl.slice(redirectedUrl.indexOf('?') + 1).split('&'); @@ -610,7 +606,7 @@ module.exports = () => { const popoverSelector = await getPopoverSelector(await page.waitForSelector('#actions-dropdown-button .popover-trigger')); await expectInnerText(page, `${popoverSelector} button:nth-child(3)`, 'Unfreeze the data pass'); - await pressElement(page, `${popoverSelector} button:nth-child(3)`); + await pressElement(page, `${popoverSelector} button:nth-child(3)`, true); }); it('should successfully enable QC flag creation when data pass is un-frozen', async () => {