Skip to content

Commit 7790354

Browse files
feat(locator): add withAttrEndsWith, withAttrStartsWith, withAttrContains (#4334)
* Adding methods to locator.js - withAttrEndsWith, withAttrStartsWith, withAttrContains * merge with main branch and added tests --------- Co-authored-by: kobenguyent <[email protected]>
1 parent 96b53d8 commit 7790354

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

lib/locator.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,49 @@ class Locator {
299299
return new Locator({ xpath });
300300
}
301301

302+
/**
303+
* Adds condition: attribute value starts with text
304+
* (analog of XPATH: [starts-with(@attr,'startValue')] or CSS [attr^='startValue']
305+
* Example: I.click(locate('a').withAttrStartsWith('href', 'https://')));
306+
* Works with any attribute: class, href etc.
307+
* @param {string} attrName
308+
* @param {string} startsWith
309+
* @returns {Locator}
310+
*/
311+
withAttrStartsWith(attrName, startsWith) {
312+
const xpath = sprintf('%s[%s]', this.toXPath(), `starts-with(@${attrName}, "${startsWith}")`);
313+
return new Locator({ xpath });
314+
}
315+
316+
/**
317+
* Adds condition: attribute value ends with text
318+
* (analog of XPATH: [ends-with(@attr,'endValue')] or CSS [attr$='endValue']
319+
* Example: I.click(locate('a').withAttrEndsWith('href', '.com')));
320+
* Works with any attribute: class, href etc.
321+
* @param {string} attrName
322+
* @param {string} endsWith
323+
* @returns {Locator}
324+
*/
325+
withAttrEndsWith(attrName, endsWith) {
326+
const xpath = sprintf('%s[%s]', this.toXPath(), `substring(@${attrName}, string-length(@${attrName}) - string-length("${endsWith}") + 1) = "${endsWith}"`,
327+
);
328+
return new Locator({ xpath });
329+
}
330+
331+
/**
332+
* Adds condition: attribute value contains text
333+
* (analog of XPATH: [contains(@attr,'partOfAttribute')] or CSS [attr*='partOfAttribute']
334+
* Example: I.click(locate('a').withAttrContains('href', 'google')));
335+
* Works with any attribute: class, href etc.
336+
* @param {string} attrName
337+
* @param {string} partOfAttrValue
338+
* @returns {Locator}
339+
*/
340+
withAttrContains(attrName, partOfAttrValue) {
341+
const xpath = sprintf('%s[%s]', this.toXPath(), `contains(@${attrName}, "${partOfAttrValue}")`);
342+
return new Locator({ xpath });
343+
}
344+
302345
/**
303346
* @param {String} text
304347
* @returns {Locator}

test/unit/locator_test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,4 +455,22 @@ describe('Locator', () => {
455455
const nodes = xpath.select(l.toXPath(), doc)
456456
expect(nodes).to.have.length(0, l.toXPath())
457457
})
458+
459+
it('should find element with attribute value starts with text', () => {
460+
const l = Locator.build('a').withAttrStartsWith('class', 'ps-menu-button')
461+
const nodes = xpath.select(l.toXPath(), doc)
462+
expect(nodes).to.have.length(10, l.toXPath())
463+
})
464+
465+
it('should find element with attribute value ends with text', () => {
466+
const l = Locator.build('a').withAttrEndsWith('class', 'ps-menu-button')
467+
const nodes = xpath.select(l.toXPath(), doc)
468+
expect(nodes).to.have.length(9, l.toXPath())
469+
})
470+
471+
it('should find element with attribute value contains text', () => {
472+
const l = Locator.build('a').withAttrEndsWith('class', 'active')
473+
const nodes = xpath.select(l.toXPath(), doc)
474+
expect(nodes).to.have.length(1, l.toXPath())
475+
})
458476
})

0 commit comments

Comments
 (0)