Skip to content

Commit b8b0e33

Browse files
miraokobenguyent
andauthored
Add a locator builder method withTextEquals() (#4100)
* Add a locator builder method withTextEquals() * Fixed docs * Add a locator builder method withTextEquals() #4100 Refactored withText() and withTextEquals() to use csstoxpath --------- Co-authored-by: kobenguyent <[email protected]>
1 parent 0d2ef39 commit b8b0e33

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

docs/locators.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,20 @@ locate('form').withDescendant('select');
163163

164164
#### withText
165165

166-
Finds element containing a text
166+
Find an element containing a text
167167

168168
```js
169169
locate('span').withText('Warning');
170170
```
171171

172+
#### withTextEquals
173+
174+
Find an element with exact text
175+
176+
```js
177+
locate('button').withTextEquals('Add');
178+
```
179+
172180
#### first
173181

174182
Get first element:

lib/locator.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,12 @@ class Locator {
158158
}
159159

160160
/**
161+
* @param {string} [pseudoSelector] CSS to XPath extension pseudo: https://www.npmjs.com/package/csstoxpath?activeTab=explore#extension-pseudos
161162
* @returns {string}
162163
*/
163-
toXPath() {
164+
toXPath(pseudoSelector = '') {
164165
if (this.isXPath()) return this.value;
165-
if (this.isCSS()) return cssToXPath(this.value);
166+
if (this.isCSS()) return cssToXPath(`${this.value}${pseudoSelector}`);
166167

167168
throw new Error('Can\'t be converted to XPath');
168169
}
@@ -243,12 +244,24 @@ class Locator {
243244
}
244245

245246
/**
247+
* Find an element containing a text
246248
* @param {string} text
247249
* @returns {Locator}
248250
*/
249251
withText(text) {
250252
text = xpathLocator.literal(text);
251-
const xpath = sprintf('%s[%s]', this.toXPath(), `contains(., ${text})`);
253+
const xpath = this.toXPath(`:text-contains-case(${text})`);
254+
return new Locator({ xpath });
255+
}
256+
257+
/**
258+
* Find an element with exact text
259+
* @param {string} text
260+
* @returns {Locator}
261+
*/
262+
withTextEquals(text) {
263+
text = xpathLocator.literal(text);
264+
const xpath = this.toXPath(`:text-case(${text})`);
252265
return new Locator({ xpath });
253266
}
254267

test/unit/locator_test.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const Locator = require('../../lib/locator');
66

77
let doc;
88
const xml = `<body>
9-
<span>Hey</span>
9+
<span>Hey boy</span>
1010
<p>
1111
<span></span>
1212
<div></div>
@@ -157,12 +157,18 @@ describe('Locator', () => {
157157
expect(nodes).to.have.length(1);
158158
});
159159

160-
it('should build locator to match element by text', () => {
160+
it('should build locator to match element containing a text', () => {
161161
const l = Locator.build('span').withText('Hey');
162162
const nodes = xpath.select(l.toXPath(), doc);
163163
expect(nodes).to.have.length(1);
164164
});
165165

166+
it('should build locator to match element by exact text', () => {
167+
const l = Locator.build('span').withTextEquals('Hey boy');
168+
const nodes = xpath.select(l.toXPath(), doc);
169+
expect(nodes).to.have.length(1);
170+
});
171+
166172
it('should build locator to match element by position', () => {
167173
const l = Locator.build('#fieldset-buttons')
168174
.find('//tr')

0 commit comments

Comments
 (0)