Skip to content

Commit 35c6c95

Browse files
Added capability to have customLocator attribute arrays; Updated chai-as-promised to v7; Fixed codecept.workers test; Fixed linting in codecept.playwright test; Fixed locator_test to.be.thrown call (#3348)
1 parent a5bf4aa commit 35c6c95

File tree

6 files changed

+128
-15
lines changed

6 files changed

+128
-15
lines changed

docs/plugins.md

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
---
2-
permalink: plugins
3-
sidebarDepth:
4-
sidebar: auto
5-
title: Plugins
6-
---
7-
81
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
92

103
## allure
@@ -512,6 +505,46 @@ I.seeElement('=user'); // matches => [data-qa=user]
512505
I.click('=sign-up'); // matches => [data-qa=sign-up]
513506
```
514507
508+
Using `data-qa` OR `data-test` attribute with `=` prefix:
509+
510+
```js
511+
// in codecept.conf.js
512+
plugins: {
513+
customLocator: {
514+
enabled: true,
515+
prefix: '=',
516+
attribute: ['data-qa', 'data-test'],
517+
strategy: 'xpath'
518+
}
519+
}
520+
```
521+
522+
In a test:
523+
524+
```js
525+
I.seeElement('=user'); // matches => //*[@data-qa=user or @data-test=user]
526+
I.click('=sign-up'); // matches => //*[data-qa=sign-up or @data-test=sign-up]
527+
```
528+
529+
```js
530+
// in codecept.conf.js
531+
plugins: {
532+
customLocator: {
533+
enabled: true,
534+
prefix: '=',
535+
attribute: ['data-qa', 'data-test'],
536+
strategy: 'css'
537+
}
538+
}
539+
```
540+
541+
In a test:
542+
543+
```js
544+
I.seeElement('=user'); // matches => [data-qa=user],[data-test=user]
545+
I.click('=sign-up'); // matches => [data-qa=sign-up],[data-test=sign-up]
546+
```
547+
515548
### Parameters
516549
517550
- `config`

lib/plugin/customLocator.js

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,70 @@ const defaultConfig = {
7070
* I.seeElement('=user'); // matches => [data-qa=user]
7171
* I.click('=sign-up'); // matches => [data-qa=sign-up]
7272
* ```
73+
*
74+
* Using `data-qa` OR `data-test` attribute with `=` prefix:
75+
*
76+
* ```js
77+
* // in codecept.conf.js
78+
* plugins: {
79+
* customLocator: {
80+
* enabled: true,
81+
* prefix: '=',
82+
* attribute: ['data-qa', 'data-test'],
83+
* strategy: 'xpath'
84+
* }
85+
* }
86+
* ```
87+
*
88+
* In a test:
89+
*
90+
* ```js
91+
* I.seeElement('=user'); // matches => //*[@data-qa=user or @data-test=user]
92+
* I.click('=sign-up'); // matches => //*[data-qa=sign-up or @data-test=sign-up]
93+
* ```
94+
*
95+
* ```js
96+
* // in codecept.conf.js
97+
* plugins: {
98+
* customLocator: {
99+
* enabled: true,
100+
* prefix: '=',
101+
* attribute: ['data-qa', 'data-test'],
102+
* strategy: 'css'
103+
* }
104+
* }
105+
* ```
106+
*
107+
* In a test:
108+
*
109+
* ```js
110+
* I.seeElement('=user'); // matches => [data-qa=user],[data-test=user]
111+
* I.click('=sign-up'); // matches => [data-qa=sign-up],[data-test=sign-up]
112+
* ```
73113
*/
74114
module.exports = (config) => {
75-
config = Object.assign(defaultConfig, config);
115+
config = { ...defaultConfig, ...config };
76116

77117
Locator.addFilter((value, locatorObj) => {
78118
if (typeof value !== 'string') return;
79119
if (!value.startsWith(config.prefix)) return;
80120

121+
if (!['String', 'Array'].includes(config.attribute.constructor.name)) return;
122+
81123
const val = value.substr(config.prefix.length);
82124

83125
if (config.strategy.toLowerCase() === 'xpath') {
84-
locatorObj.value = `.//*[@${config.attribute}=${xpathLocator.literal(val)}]`;
126+
locatorObj.value = `.//*[${
127+
[].concat(config.attribute)
128+
.map((attr) => `@${attr}=${xpathLocator.literal(val)}`)
129+
.join(' or ')}]`;
85130
locatorObj.type = 'xpath';
86131
}
87132

88133
if (config.strategy.toLowerCase() === 'css') {
89-
locatorObj.value = `[${config.attribute}=${val}]`;
134+
locatorObj.value = [].concat(config.attribute)
135+
.map((attr) => `[${attr}=${val}]`)
136+
.join(',');
90137
locatorObj.type = 'css';
91138
}
92139

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
"uuid": "^8.3.2"
9191
},
9292
"devDependencies": {
93-
"@codeceptjs/detox-helper": "^1.0.2",
93+
"@codeceptjs/detox-helper": "^1.0.2",
9494
"@codeceptjs/mock-request": "^0.3.1",
9595
"@faker-js/faker": "^5.5.3",
9696
"@pollyjs/adapter-puppeteer": "^5.1.0",
@@ -101,7 +101,7 @@
101101
"@wdio/selenium-standalone-service": "^5.16.10",
102102
"@wdio/utils": "^5.23.0",
103103
"apollo-server-express": "^2.25.3",
104-
"chai-as-promised": "^5.2.0",
104+
"chai-as-promised": "^7.1.1",
105105
"chai-subset": "^1.6.0",
106106
"contributor-faces": "^1.0.3",
107107
"documentation": "^12.3.0",

test/data/sandbox/codecept.workers-custom-output-folder-name.conf.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ exports.config = {
99
},
1010
},
1111
include: {},
12-
bootstrap: {},
12+
// eslint-disable-next-line no-empty-function
13+
async bootstrap() {},
1314
mocha: {},
1415
name: 'sandbox',
1516
};

test/unit/locator_test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,13 @@ describe('Locator', () => {
202202
it('should throw an error when xpath with round brackets is nested', () => {
203203
expect(() => {
204204
Locator.build('tr').find('(./td)[@id="id"]');
205-
}, /round brackets/).to.be.thrown;
205+
}).to.throw('round brackets');
206206
});
207207

208208
it('should throw an error when locator with specific position is nested', () => {
209209
expect(() => {
210210
Locator.build('tr').withChild(Locator.build('td').first());
211-
}, /round brackets/).to.be.thrown;
211+
}).to.throw('round brackets');
212212
});
213213

214214
it('should not select element by deep nested siblings', () => {

test/unit/plugin/customLocator_test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,36 @@ describe('customLocator', () => {
5353
expect(l.isCSS()).to.be.true;
5454
expect(l.simplify()).to.eql('[data-test=user]');
5555
});
56+
57+
it('add a custom locator with array $ -> data-qa, data-qa-id', () => {
58+
customLocatorPlugin({
59+
prefix: '$',
60+
attribute: ['data-qa', 'data-qa-id'],
61+
showActual: true,
62+
});
63+
const l = new Locator('$user-id');
64+
expect(l.isXPath()).to.be.true;
65+
expect(l.toXPath()).to.eql('.//*[@data-qa=\'user-id\' or @data-qa-id=\'user-id\']');
66+
expect(l.toString()).to.eql('.//*[@data-qa=\'user-id\' or @data-qa-id=\'user-id\']');
67+
});
68+
69+
it('add a custom locator array with CSS', () => {
70+
customLocatorPlugin({
71+
prefix: '$',
72+
attribute: ['data-test', 'data-test-id'],
73+
strategy: 'css',
74+
});
75+
const l = new Locator('$user');
76+
expect(l.isCSS()).to.be.true;
77+
expect(l.simplify()).to.eql('[data-test=user],[data-test-id=user]');
78+
});
79+
80+
it('should return initial locator value when it does not start with specified prefix', () => {
81+
customLocatorPlugin({
82+
prefix: '$',
83+
attribute: 'data-test',
84+
});
85+
const l = new Locator('=user');
86+
expect(l.simplify()).to.eql('=user');
87+
});
5688
});

0 commit comments

Comments
 (0)