From 18124acebbed66d120c3fe1702fc44f1df70d1af Mon Sep 17 00:00:00 2001 From: Jaromir Obr Date: Tue, 2 Jan 2024 12:51:43 +0100 Subject: [PATCH 1/3] Add a locator builder method withTextEquals() --- docs/locators.md | 10 +++++++++- lib/locator.js | 12 ++++++++++++ test/unit/locator_test.js | 10 ++++++++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/docs/locators.md b/docs/locators.md index 439ec6f75..c09252038 100644 --- a/docs/locators.md +++ b/docs/locators.md @@ -163,12 +163,20 @@ locate('form').withDescendant('select'); #### withText -Finds element containing a text +Find an element containing a text ```js locate('span').withText('Warning'); ``` +#### withTextEquals + +Find an element with exact text + +```js +locate('button').withText('Add'); +``` + #### first Get first element: diff --git a/lib/locator.js b/lib/locator.js index ab7db428e..b29206b22 100644 --- a/lib/locator.js +++ b/lib/locator.js @@ -243,6 +243,7 @@ class Locator { } /** + * Find an element containing a text * @param {string} text * @returns {Locator} */ @@ -252,6 +253,17 @@ class Locator { return new Locator({ xpath }); } + /** + * Find an element with exact text + * @param {string} text + * @returns {Locator} + */ + withTextEquals(text) { + text = xpathLocator.literal(text); + const xpath = sprintf('%s[%s]', this.toXPath(), `.= ${text}`); + return new Locator({ xpath }); + } + /** * @param {Object.} attributes * @returns {Locator} diff --git a/test/unit/locator_test.js b/test/unit/locator_test.js index 640c6222d..ad805db3c 100644 --- a/test/unit/locator_test.js +++ b/test/unit/locator_test.js @@ -6,7 +6,7 @@ const Locator = require('../../lib/locator'); let doc; const xml = ` - Hey + Hey boy

@@ -144,12 +144,18 @@ describe('Locator', () => { expect(nodes).to.have.length(1); }); - it('should build locator to match element by text', () => { + it('should build locator to match element containing a text', () => { const l = Locator.build('span').withText('Hey'); const nodes = xpath.select(l.toXPath(), doc); expect(nodes).to.have.length(1); }); + it('should build locator to match element by exact text', () => { + const l = Locator.build('span').withTextEquals('Hey boy'); + const nodes = xpath.select(l.toXPath(), doc); + expect(nodes).to.have.length(1); + }); + it('should build locator to match element by position', () => { const l = Locator.build('#fieldset-buttons') .find('//tr') From bfed9713836707058251a45290cedc355d1949be Mon Sep 17 00:00:00 2001 From: Jaromir Obr Date: Tue, 2 Jan 2024 13:58:44 +0100 Subject: [PATCH 2/3] Fixed docs --- docs/locators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/locators.md b/docs/locators.md index c09252038..b7e4ae906 100644 --- a/docs/locators.md +++ b/docs/locators.md @@ -174,7 +174,7 @@ locate('span').withText('Warning'); Find an element with exact text ```js -locate('button').withText('Add'); +locate('button').withTextEquals('Add'); ``` #### first From d662a09ce1a73bac4570fba8f11828b458fbd0de Mon Sep 17 00:00:00 2001 From: Jaromir Obr Date: Wed, 3 Jan 2024 08:54:26 +0100 Subject: [PATCH 3/3] Add a locator builder method withTextEquals() #4100 Refactored withText() and withTextEquals() to use csstoxpath --- lib/locator.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/locator.js b/lib/locator.js index 13abdd23e..a50e13958 100644 --- a/lib/locator.js +++ b/lib/locator.js @@ -158,11 +158,12 @@ class Locator { } /** + * @param {string} [pseudoSelector] CSS to XPath extension pseudo: https://www.npmjs.com/package/csstoxpath?activeTab=explore#extension-pseudos * @returns {string} */ - toXPath() { + toXPath(pseudoSelector = '') { if (this.isXPath()) return this.value; - if (this.isCSS()) return cssToXPath(this.value); + if (this.isCSS()) return cssToXPath(`${this.value}${pseudoSelector}`); throw new Error('Can\'t be converted to XPath'); } @@ -249,7 +250,7 @@ class Locator { */ withText(text) { text = xpathLocator.literal(text); - const xpath = sprintf('%s[%s]', this.toXPath(), `contains(., ${text})`); + const xpath = this.toXPath(`:text-contains-case(${text})`); return new Locator({ xpath }); } @@ -260,7 +261,7 @@ class Locator { */ withTextEquals(text) { text = xpathLocator.literal(text); - const xpath = sprintf('%s[%s]', this.toXPath(), `.= ${text}`); + const xpath = this.toXPath(`:text-case(${text})`); return new Locator({ xpath }); }