From 4f359d35afb23cc8462223cea31e4c2eef9dabc4 Mon Sep 17 00:00:00 2001 From: DavertMik Date: Mon, 6 Jan 2025 14:30:49 +0200 Subject: [PATCH 1/3] fixed regression in waitfortext --- lib/helper/Playwright.js | 59 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 6eeb8098b..26b5850fc 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -2687,6 +2687,9 @@ class Playwright extends Helper { if ((this.context && this.context.constructor.name === 'FrameLocator') || this.context) { return this.context } + if (this.frame) { + return this.frame + } return this.page } @@ -2751,26 +2754,21 @@ class Playwright extends Helper { async waitForText(text, sec = null, context = null) { const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout const errorMessage = `Text "${text}" was not found on page after ${waitTimeout / 1000} sec.` - let waiter const contextObject = await this._getContext() if (context) { const locator = new Locator(context, 'css') - if (!locator.isXPath()) { - try { - await contextObject + try { + if (!locator.isXPath()) { + return contextObject .locator(`${locator.isCustom() ? `${locator.type}=${locator.value}` : locator.simplify()} >> text=${text}`) .first() .waitFor({ timeout: waitTimeout, state: 'visible' }) - } catch (e) { - throw new Error(`${errorMessage}\n${e.message}`) } - } - if (locator.isXPath()) { - try { - await contextObject.waitForFunction( + if (locator.isXPath()) { + return contextObject.waitForFunction( ([locator, text, $XPath]) => { eval($XPath) // eslint-disable-line no-eval const el = $XPath(null, locator) @@ -2780,27 +2778,32 @@ class Playwright extends Helper { [locator.value, text, $XPath.toString()], { timeout: waitTimeout }, ) - } catch (e) { - throw new Error(`${errorMessage}\n${e.message}`) } + } catch (e) { + throw new Error(`${errorMessage}\n${e.message}`) } - } else { - // we have this as https://github.com/microsoft/playwright/issues/26829 is not yet implemented - - const _contextObject = this.frame ? this.frame : contextObject - let count = 0 - do { - waiter = await _contextObject - .locator(`:has-text(${JSON.stringify(text)})`) - .first() - .isVisible() - if (waiter) break - await this.wait(1) - count += 1000 - } while (count <= waitTimeout) - - if (!waiter) throw new Error(`${errorMessage}`) } + + const timeoutGap = waitTimeout + 1000 + + // We add basic timeout to make sure we don't wait forever + // We apply 2 strategies here: wait for text as innert text on page (wide strategy) - older + // or we use native Playwright matcher to wait for text in element (narrow strategy) - newer + // If a user waits for text on a page they are mostly expect it to be there, so wide strategy can be helpful even PW strategy is available + return Promise.race([ + new Promise((_, reject) => { + setTimeout(() => reject(errorMessage), waitTimeout) + }), + contextObject.waitForFunction(text => document.body && document.body.innerText.indexOf(text) > -1, text, { timeout: timeoutGap }), + promiseRetry( + async () => + contextObject + .locator(`:has-text(${JSON.stringify(text)})`) + .first() + .isVisible(), + { retries: timeoutGap / 500, minTimeout: 500, factor: 1 }, + ), + ]) } /** From 6c8875847dd756461bbb3618616129df93b5947e Mon Sep 17 00:00:00 2001 From: DavertMik Date: Tue, 7 Jan 2025 00:29:51 +0200 Subject: [PATCH 2/3] fixed wait test for wait for text --- lib/helper/Playwright.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 26b5850fc..e0bce8a84 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -2794,7 +2794,7 @@ class Playwright extends Helper { new Promise((_, reject) => { setTimeout(() => reject(errorMessage), waitTimeout) }), - contextObject.waitForFunction(text => document.body && document.body.innerText.indexOf(text) > -1, text, { timeout: timeoutGap }), + this.page.waitForFunction(text => document.body && document.body.innerText.indexOf(text) > -1, text, { timeout: timeoutGap }), promiseRetry( async () => contextObject From 292a7882900c6c7eb4a1d7e59c401faa01f1dbbd Mon Sep 17 00:00:00 2001 From: DavertMik Date: Tue, 7 Jan 2025 03:49:38 +0200 Subject: [PATCH 3/3] fixed retries for PW waitForText test --- lib/helper/Playwright.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index e0bce8a84..3ab51c7f0 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -2796,12 +2796,14 @@ class Playwright extends Helper { }), this.page.waitForFunction(text => document.body && document.body.innerText.indexOf(text) > -1, text, { timeout: timeoutGap }), promiseRetry( - async () => - contextObject + async retry => { + const textPresent = await contextObject .locator(`:has-text(${JSON.stringify(text)})`) .first() - .isVisible(), - { retries: timeoutGap / 500, minTimeout: 500, factor: 1 }, + .isVisible() + if (!textPresent) retry(errorMessage) + }, + { retries: 1000, minTimeout: 500, maxTimeout: 500, factor: 1 }, ), ]) }