diff --git a/docs/locators.md b/docs/locators.md index 439ec6f75..b7e4ae906 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').withTextEquals('Add'); +``` + #### first Get first element: diff --git a/lib/locator.js b/lib/locator.js index e5b5917d7..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'); } @@ -243,12 +244,24 @@ class Locator { } /** + * Find an element containing a text * @param {string} text * @returns {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 }); + } + + /** + * Find an element with exact text + * @param {string} text + * @returns {Locator} + */ + withTextEquals(text) { + text = xpathLocator.literal(text); + const xpath = this.toXPath(`:text-case(${text})`); return new Locator({ xpath }); } diff --git a/test/unit/locator_test.js b/test/unit/locator_test.js index ae09ccda3..baf4b28b0 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@@ -157,12 +157,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')