From 33c88e71e5f9efd2bea59302b5386ef83f7a3374 Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Wed, 27 Mar 2024 10:14:48 +0100 Subject: [PATCH 1/2] fix: waitNumberOfVisibleElements always failed when passing num as 0 --- lib/helper/Playwright.js | 23 ++++++++--------------- lib/helper/Puppeteer.js | 1 - test/helper/Playwright_test.js | 5 +++++ test/helper/Puppeteer_test.js | 20 ++++++++++++-------- test/helper/WebDriver_devtools_test.js | 5 +++++ 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 15f2aab0a..38f6f412d 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -2472,28 +2472,21 @@ class Playwright extends Helper { async waitNumberOfVisibleElements(locator, num, sec) { const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout; locator = new Locator(locator, 'css'); - await this.context; - let waiter; - const context = await this._getContext(); - if (locator.isCSS()) { + + try { + const context = await this._getContext(); const visibleFn = function ([locator, num]) { const els = document.querySelectorAll(locator); if (!els || els.length === 0) { - return false; + return num === 0; } return Array.prototype.filter.call(els, el => el.offsetParent !== null).length === num; }; - waiter = context.waitForFunction(visibleFn, [locator.value, num], { timeout: waitTimeout }); - } else { - const visibleFn = function ([locator, $XPath, num]) { - eval($XPath); // eslint-disable-line no-eval - return $XPath(null, locator).filter(el => el.offsetParent !== null).length === num; - }; - waiter = context.waitForFunction(visibleFn, [locator.value, $XPath.toString(), num], { timeout: waitTimeout }); + + await context.waitForFunction(visibleFn, [locator.value, num], { timeout: waitTimeout }); + } catch (error) { + throw new Error(`The number of elements (${locator.toString()}) is not ${num} after ${waitTimeout / 1000} sec\n${error.message}`); } - return waiter.catch((err) => { - throw new Error(`The number of elements (${locator.toString()}) is not ${num} after ${waitTimeout / 1000} sec\n${err.message}`); - }); } /** diff --git a/lib/helper/Puppeteer.js b/lib/helper/Puppeteer.js index 8ee9e0561..2bb8edac8 100644 --- a/lib/helper/Puppeteer.js +++ b/lib/helper/Puppeteer.js @@ -2090,7 +2090,6 @@ class Puppeteer extends Helper { async waitNumberOfVisibleElements(locator, num, sec) { const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout; locator = new Locator(locator, 'css'); - await this.context; let waiter; const context = await this._getContext(); if (locator.isCSS()) { diff --git a/test/helper/Playwright_test.js b/test/helper/Playwright_test.js index f2680b9b8..ce33e210d 100644 --- a/test/helper/Playwright_test.js +++ b/test/helper/Playwright_test.js @@ -249,6 +249,11 @@ describe('Playwright', function () { .then(() => I.waitNumberOfVisibleElements('.title', 2, 3)) .then(() => I.see('Hello')) .then(() => I.see('World'))); + + it('should wait for 0 number of visible elements', async () => { + await I.amOnPage('/form/wait_invisible'); + await I.waitNumberOfVisibleElements('#step_1', 0); + }); }); describe('#moveCursorTo', () => { diff --git a/test/helper/Puppeteer_test.js b/test/helper/Puppeteer_test.js index c23e906dc..a22187e7f 100644 --- a/test/helper/Puppeteer_test.js +++ b/test/helper/Puppeteer_test.js @@ -193,15 +193,14 @@ describe('Puppeteer', function () { }); describe('#waitNumberOfVisibleElements', () => { - it('should wait for a specified number of elements on the page', () => I.amOnPage('/info') - .then(() => I.waitNumberOfVisibleElements('//div[@id = "grab-multiple"]//a', 3)) - .then(() => I.waitNumberOfVisibleElements('//div[@id = "grab-multiple"]//a', 2, 0.1)) - .then(() => { - throw Error('It should never get this far'); - }) - .catch((e) => { + it('should wait for a specified number of elements on the page', async () => { + try { + await I.amOnPage('/info'); + await I.waitNumberOfVisibleElements('//div[@id = "grab-multiple"]//a', 3); + } catch (e) { e.message.should.include('The number of elements (//div[@id = "grab-multiple"]//a) is not 2 after 0.1 sec'); - })); + } + }); it('should wait for a specified number of elements on the page using a css selector', () => I.amOnPage('/info') .then(() => I.waitNumberOfVisibleElements('#grab-multiple > a', 3)) @@ -217,6 +216,11 @@ describe('Puppeteer', function () { .then(() => I.waitNumberOfVisibleElements('.title', 2, 3)) .then(() => I.see('Hello')) .then(() => I.see('World'))); + + it('should wait for 0 number of visible elements', async () => { + await I.amOnPage('/form/wait_invisible'); + await I.waitNumberOfVisibleElements('#step_1', 0); + }); }); describe('#moveCursorTo', () => { diff --git a/test/helper/WebDriver_devtools_test.js b/test/helper/WebDriver_devtools_test.js index b0b4329bb..92298f406 100644 --- a/test/helper/WebDriver_devtools_test.js +++ b/test/helper/WebDriver_devtools_test.js @@ -532,6 +532,11 @@ describe('WebDriver - Devtools Protocol', function () { .then(() => wd.see('Hello')) .then(() => wd.see('World')); }); + + it('should wait for 0 number of visible elements', async () => { + await wd.amOnPage('/form/wait_invisible'); + await wd.waitNumberOfVisibleElements('#step_1', 0); + }); }); describe('#waitForVisible', () => { From c6a593a6ae6497e4de275e67bfc992ef0c1aba5e Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Thu, 28 Mar 2024 07:14:32 +0100 Subject: [PATCH 2/2] fix: failed UT --- lib/helper/Playwright.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/helper/Playwright.js b/lib/helper/Playwright.js index 38f6f412d..b2aeb9d15 100644 --- a/lib/helper/Playwright.js +++ b/lib/helper/Playwright.js @@ -2473,20 +2473,27 @@ class Playwright extends Helper { const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout; locator = new Locator(locator, 'css'); - try { - const context = await this._getContext(); + let waiter; + const context = await this._getContext(); + if (locator.isCSS()) { const visibleFn = function ([locator, num]) { const els = document.querySelectorAll(locator); if (!els || els.length === 0) { - return num === 0; + return false; } return Array.prototype.filter.call(els, el => el.offsetParent !== null).length === num; }; - - await context.waitForFunction(visibleFn, [locator.value, num], { timeout: waitTimeout }); - } catch (error) { - throw new Error(`The number of elements (${locator.toString()}) is not ${num} after ${waitTimeout / 1000} sec\n${error.message}`); + waiter = context.waitForFunction(visibleFn, [locator.value, num], { timeout: waitTimeout }); + } else { + const visibleFn = function ([locator, $XPath, num]) { + eval($XPath); // eslint-disable-line no-eval + return $XPath(null, locator).filter(el => el.offsetParent !== null).length === num; + }; + waiter = context.waitForFunction(visibleFn, [locator.value, $XPath.toString(), num], { timeout: waitTimeout }); } + return waiter.catch((err) => { + throw new Error(`The number of elements (${locator.toString()}) is not ${num} after ${waitTimeout / 1000} sec\n${err.message}`); + }); } /**