From 196ce662da0b8140cdd4d566394dd04c325fc7f0 Mon Sep 17 00:00:00 2001 From: George Raduta Date: Fri, 31 Jul 2026 09:27:25 +0200 Subject: [PATCH 1/3] FIx node detached with multiple attempts instead --- test/public/defaults.js | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/test/public/defaults.js b/test/public/defaults.js index 2c4504443d..d226c85c51 100644 --- a/test/public/defaults.js +++ b/test/public/defaults.js @@ -276,26 +276,33 @@ exports.waitForNavigation = waitForNavigation; * @returns {Promise} Whether the element was clickable or not. */ module.exports.pressElement = async (page, selector, jsClick = false) => { - await page.waitForFunction( - (sel, isJsClick) => { - const element = document.querySelector(sel); + const maxAttempts = 3; + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + await page.waitForFunction( + (sel) => Boolean(document.querySelector(sel)), + {}, + selector + ); - if (!element) { - return false; - } - // Moving the click to outside the function causes it to fail for unknown reasons - if (isJsClick) { - element.click(); + try { + if (jsClick) { + await page.$eval(selector, (element) => { + element.click(); + }); + } else { + await page.waitForSelector(selector, { visible: true }); + await page.click(selector); } + return; + } catch (error) { + const errorMessage = String(error?.message ?? ''); + const isRetryable = errorMessage.includes('detached from document') + || errorMessage.includes('Node is detached from document'); - return true; - }, - {}, - selector, jsClick - ); - - if (!jsClick) { - await page.click(selector); + if (!isRetryable || attempt === maxAttempts) { + throw error; + } + } } }; From 5b568cd85c2d8972f22ab93826d964a350c7813c Mon Sep 17 00:00:00 2001 From: George Raduta Date: Fri, 31 Jul 2026 12:41:55 +0200 Subject: [PATCH 2/3] Use element handler --- test/public/defaults.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/public/defaults.js b/test/public/defaults.js index d226c85c51..442febb0a8 100644 --- a/test/public/defaults.js +++ b/test/public/defaults.js @@ -290,14 +290,18 @@ module.exports.pressElement = async (page, selector, jsClick = false) => { element.click(); }); } else { - await page.waitForSelector(selector, { visible: true }); - await page.click(selector); + const elementHandle = await page.waitForSelector(selector, { visible: true }); + await elementHandle.click(); + await elementHandle.dispose(); } return; } catch (error) { const errorMessage = String(error?.message ?? ''); const isRetryable = errorMessage.includes('detached from document') - || errorMessage.includes('Node is detached from document'); + || errorMessage.includes('Node is detached from document') + || errorMessage.includes('Node is either not clickable or not an Element') + || errorMessage.includes('not visible') + || errorMessage.includes('No node found for selector'); if (!isRetryable || attempt === maxAttempts) { throw error; From 86fd04eb064c5f81cf46f3b611d318a9adb567e1 Mon Sep 17 00:00:00 2001 From: George Raduta Date: Fri, 31 Jul 2026 12:54:33 +0200 Subject: [PATCH 3/3] Add sort reset in tests --- lib/public/components/common/table/SortModel.js | 13 +++++++++++++ lib/public/models/OverviewModel.js | 1 + test/public/defaults.js | 10 ++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/public/components/common/table/SortModel.js b/lib/public/components/common/table/SortModel.js index a58e087820..198c05e1d0 100644 --- a/lib/public/components/common/table/SortModel.js +++ b/lib/public/components/common/table/SortModel.js @@ -165,4 +165,17 @@ export class SortModel extends Observable { get visualChange$() { return this._visualChange$; } + + /** + * Reset the sorting state to its defaults + * + * @return {void} + */ + reset() { + this._appliedDirection = this.defaultOrder; + this._appliedOn = null; + this._previewOn = null; + this.notify(); + this._visualChange$.notify(); + } } diff --git a/lib/public/models/OverviewModel.js b/lib/public/models/OverviewModel.js index 73334c204b..502aa606e8 100644 --- a/lib/public/models/OverviewModel.js +++ b/lib/public/models/OverviewModel.js @@ -99,6 +99,7 @@ export class OverviewPageModel extends Observable { */ reset() { this._item$.setCurrent(RemoteData.notAsked()); + this._sortModel.reset(); this._pagination.reset(); this._warnings.clear(); } diff --git a/test/public/defaults.js b/test/public/defaults.js index 442febb0a8..c9d276b1cc 100644 --- a/test/public/defaults.js +++ b/test/public/defaults.js @@ -286,9 +286,11 @@ module.exports.pressElement = async (page, selector, jsClick = false) => { try { if (jsClick) { - await page.$eval(selector, (element) => { + const elementHandle = await page.waitForSelector(selector); + await elementHandle.evaluate((element) => { element.click(); }); + await elementHandle.dispose(); } else { const elementHandle = await page.waitForSelector(selector, { visible: true }); await elementHandle.click(); @@ -872,15 +874,15 @@ module.exports.testTableSortingByColumn = async (page, columnId) => { // Sort in ASCENDING manner await this.pressElement(page, `th#${columnId}`, true); - this.expectColumnValues(page, columnId, [...notOrderData].sort()); + await this.expectColumnValues(page, columnId, [...notOrderData].sort()); // Sort in DESCENDING manner await this.pressElement(page, `th#${columnId}`, true); - this.expectColumnValues(page, columnId, [...notOrderData].sort().reverse()); + await this.expectColumnValues(page, columnId, [...notOrderData].sort().reverse()); // Revoke sorting await this.pressElement(page, `th#${columnId}`, true); - this.expectColumnValues(page, columnId, notOrderData); + await this.expectColumnValues(page, columnId, notOrderData); }; /**