Skip to content

Commit 873e1cd

Browse files
yratanovro0gr
authored andcommitted
Introduce new dom finders
implements #463
1 parent cbe9e65 commit 873e1cd

24 files changed

Lines changed: 586 additions & 81 deletions

File tree

addon-test-support/-private/helpers.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,20 @@ export function every(jqArray, cb) {
166166
return A(arr).every((element) => cb($(element)));
167167
}
168168

169-
export function map(jqArray, cb, options = {}) {
170-
let arr = jqArray.get();
171-
172-
const values = A(arr).map(element => cb($(element)));
173-
174-
return options.multiple ? values : values[0];
169+
/**
170+
* @private
171+
*
172+
* Check if all options are in whitelist
173+
*
174+
*/
175+
export function filterWhitelistedOption(options, whitelist) {
176+
const result = {};
177+
for (let [key, value] of Object.entries(options)) {
178+
if(whitelist.includes(key)) {
179+
result[key] = value;
180+
}
181+
}
182+
return result;
175183
}
176184

177185
/**

addon-test-support/extend/find-element-with-assert.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getExecutionContext } from '../-private/execution_context';
2+
import { deprecate } from '@ember/application/deprecations';
23

34
/**
45
* @public
@@ -36,5 +37,10 @@ import { getExecutionContext } from '../-private/execution_context';
3637
* @throws Will throw an error if multiple elements are matched by selector and multiple option is not set
3738
*/
3839
export function findElementWithAssert(pageObjectNode, targetSelector, options = {}) {
40+
deprecate('findElementWithAssert is deprecated, please use findOne or findMany instead', false, {
41+
id: 'ember-cli-page-object.old-finders',
42+
until: '2.0.0',
43+
url: 'https://ember-cli-page-object.js.org/docs/v1.16.x/deprecations/#old-finders'
44+
});
3945
return getExecutionContext(pageObjectNode).findWithAssert(targetSelector, options);
4046
}

addon-test-support/extend/find-element.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getExecutionContext } from '../-private/execution_context';
2+
import { deprecate } from '@ember/application/deprecations';
23

34
/**
45
* @public
@@ -34,5 +35,11 @@ import { getExecutionContext } from '../-private/execution_context';
3435
* @throws Will throw an error if multiple elements are matched by selector and multiple option is not set
3536
*/
3637
export function findElement(pageObjectNode, targetSelector, options = {}) {
38+
deprecate('findElement is deprecated, please use findOne or findMany instead', false, {
39+
id: 'ember-cli-page-object.old-finders',
40+
until: '2.0.0',
41+
url: 'https://ember-cli-page-object.js.org/docs/v1.16.x/deprecations/#old-finders'
42+
});
43+
3744
return getExecutionContext(pageObjectNode).find(targetSelector, options);
3845
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { getExecutionContext } from '../-private/execution_context';
2+
import { filterWhitelistedOption } from '../-private/helpers';
3+
/**
4+
* @public
5+
*
6+
* Returns array of elements
7+
*
8+
* @example
9+
*
10+
* import { findMany } from '../extend';
11+
*
12+
* export default function count(selector, options = {}) {
13+
* return {
14+
* isDescriptor: true,
15+
*
16+
* get() {
17+
* return findMany(this, selector, options).length;
18+
* }
19+
* };
20+
* }
21+
*
22+
* @param {Ceibo} pageObjectNode - Node of the tree
23+
* @param {string} targetSelector - Specific CSS selector
24+
* @param {Object} options - Additional options
25+
* @param {boolean} options.resetScope - Do not use inherited scope
26+
* @param {string} options.contains - Filter by using :contains('foo') pseudo-class
27+
* @param {string} options.scope
28+
* @param {number} options.at - Filter by index using :eq(x) pseudo-class
29+
* @param {boolean} options.last - Filter by using :last pseudo-class
30+
* @param {boolean} options.visible - Filter by using :visible pseudo-class
31+
* @param {string} options.testContainer - Context where to search elements in the DOM
32+
* @return {Array} of Element
33+
*/
34+
export function findMany(pageObjectNode, targetSelector, options = {}) {
35+
const filteredOptions = filterWhitelistedOption(options, [
36+
'resetScope', 'visible', 'testContainer', 'contains', 'scope', 'at', 'last'
37+
]);
38+
const opts = Object.assign({}, filteredOptions, { multiple: true });
39+
return getExecutionContext(pageObjectNode).find(targetSelector, opts).get();
40+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { getExecutionContext } from '../-private/execution_context';
2+
import { filterWhitelistedOption } from "../-private/helpers";
3+
4+
/**
5+
* @public
6+
*
7+
* Returns a element
8+
*
9+
* @example
10+
*
11+
* import { findOne } from 'ember-cli-page-object';
12+
*
13+
* export default function isDisabled(selector, options = {}) {
14+
* return {
15+
* isDescriptor: true,
16+
*
17+
* get() {
18+
* return findOne(this, selector, options).disabled;
19+
* }
20+
* };
21+
* }
22+
*
23+
* @param {Ceibo} pageObjectNode - Node of the tree
24+
* @param {string} targetSelector - Specific CSS selector
25+
* @param {Object} options - Additional options
26+
* @param {boolean} options.resetScope - Do not use inherited scope
27+
* @param {string} options.contains - Filter by using :contains('foo') pseudo-class
28+
* @param {string} options.scope
29+
* @param {number} options.at - Filter by index using :eq(x) pseudo-class
30+
* @param {boolean} options.last - Filter by using :last pseudo-class
31+
* @param {boolean} options.visible - Filter by using :visible pseudo-class
32+
* @param {string} options.testContainer - Context where to search elements in the DOM
33+
* @param {string} options.pageObjectKey - Used in the error message when the element is not found
34+
* @return {Element}
35+
*
36+
* @throws If no elements found
37+
* @throws If more than one element found
38+
*/
39+
export function findOne(pageObjectNode, targetSelector, options = {}) {
40+
const filteredOptions = filterWhitelistedOption(options, [
41+
'resetScope', 'visible', 'testContainer', 'contains', 'at', 'last', 'scope', 'pageObjectKey'
42+
]);
43+
const opts = Object.assign({}, filteredOptions, { multiple: false });
44+
return getExecutionContext(pageObjectNode).findWithAssert(targetSelector, opts).get(0);
45+
}

addon-test-support/extend/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export { findElement } from './find-element';
22
export { findElementWithAssert } from './find-element-with-assert';
3+
export { findOne } from './find-one';
4+
export { findMany } from './find-many';
35
export { buildSelector, getContext, fullScope } from '../-private/helpers';
46
import {
57
register as registerExecutionContext

addon-test-support/properties/attribute.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { assign, map } from '../-private/helpers';
2-
import { findElementWithAssert } from '../extend';
1+
import { assign } from '../-private/helpers';
2+
import { findMany, findOne } from '../extend';
33

44
/**
55
* @public
@@ -82,9 +82,11 @@ export function attribute(attributeName, selector, userOptions = {}) {
8282
get(key) {
8383
let options = assign({ pageObjectKey: key }, userOptions);
8484

85-
let elements = findElementWithAssert(this, selector, options);
86-
87-
return map(elements, element => element.attr(attributeName), options);
85+
if (options.multiple) {
86+
return findMany(this, selector, options).map(element => element.getAttribute(attributeName), options);
87+
} else {
88+
return findOne(this, selector, options).getAttribute(attributeName);
89+
}
8890
}
8991
};
9092
}

addon-test-support/properties/contains.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { assign, every } from '../-private/helpers';
2-
import { findElementWithAssert } from '../extend';
1+
import { assign } from '../-private/helpers';
2+
import { findMany, findOne } from '../extend';
3+
import { A } from '@ember/array';
34

45
/**
56
* Returns a boolean representing whether an element or a set of elements contains the specified text.
@@ -97,11 +98,9 @@ export function contains(selector, userOptions = {}) {
9798
return function(textToSearch) {
9899
let options = assign({ pageObjectKey: `${key}("${textToSearch}")` }, userOptions);
99100

100-
let elements = findElementWithAssert(this, selector, options);
101+
let elements = options.multiple ? findMany(this, selector, options) : [findOne(this, selector, options)];
101102

102-
return every(elements, function(element) {
103-
return element.text().indexOf(textToSearch) >= 0;
104-
});
103+
return A(elements).every((element) => element.innerText.indexOf(textToSearch) >= 0);
105104
};
106105
}
107106
};

addon-test-support/properties/count.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { assign } from '../-private/helpers';
2-
import { findElement } from '../extend';
2+
import { findMany } from '../extend';
33

44
/**
55
* @public
@@ -90,7 +90,7 @@ export function count(selector, userOptions = {}) {
9090

9191
options = assign(options, { multiple: true });
9292

93-
return findElement(this, selector, options).length;
93+
return findMany(this, selector, options).length;
9494
}
9595
};
9696
}

addon-test-support/properties/has-class.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { assign, every } from '../-private/helpers';
2-
import { findElementWithAssert } from '../extend'
1+
import { assign } from '../-private/helpers';
2+
import { findOne, findMany } from '../extend';
3+
import { A } from '@ember/array';
34

45
/**
56
* Validates if an element or a set of elements have a given CSS class.
@@ -99,11 +100,9 @@ export function hasClass(cssClass, selector, userOptions = {}) {
99100
get(key) {
100101
let options = assign({ pageObjectKey: key }, userOptions);
101102

102-
let elements = findElementWithAssert(this, selector, options);
103+
let elements = options.multiple ? findMany(this, selector, options) : [findOne(this, selector, options)];
103104

104-
return every(elements, function(element) {
105-
return element.hasClass(cssClass);
106-
});
105+
return A(elements).every((element) => element.classList.contains(cssClass));
107106
}
108107
};
109108
}

0 commit comments

Comments
 (0)