Skip to content

Commit

Permalink
some docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ro0gr committed Jan 21, 2024
1 parent 252f5b1 commit 7e4e1fc
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 2 deletions.
73 changes: 73 additions & 0 deletions addon/src/-private/query/locator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,23 @@ import { isVisible, containsText } from '../element';
import { QuerySelector } from './selector';
import JQueryQuerySelector from './selectors/jquery';

/**
* Locator is responsible for finding elements in the DOM.
* It uses a QuerySelector implementation which is resolved
* by the selector argument being passed in to find elements
* and then filter them.
*/
export default class Locator {
/**
* @param {QuerySelector|String|Object} selector
* @param {Object} filters Filters to apply to the selector results
* @param {Boolean} filters.visible
* @param {String} filters.contains
* @param {Number} filters.at
* @param {Boolean} filters.last
*
* @constructor
*/
constructor(selector, filters) {
if (selector instanceof QuerySelector) {
this.selector = selector;
Expand All @@ -15,8 +31,18 @@ export default class Locator {
this.filters = filters;
}

/**
* Returns a list of elements that match the selector.
* It also filters elements found by the filters passed in the constructor.
*
* @param {Element} container Element to search within
*
* @returns {Array<Element>} List of elements
*/
query(container) {
const elements = this.selector.query(container);

// filter elements
if (!this.filters) {
return elements;
}
Expand Down Expand Up @@ -45,6 +71,11 @@ export default class Locator {
).filter(Boolean);
}

/**
* Returns a string representation of the selector. Useful for the test reporter.
*
* @returns {String}
*/
toString() {
const { filters, selector } = this;
if (!filters) {
Expand Down Expand Up @@ -73,6 +104,13 @@ export default class Locator {
return `${selector}:${modifiers.join(':')}`;
}

/**
* Answers if the current locator can merge with another locator.
*
* @param {Locator} locator
*
* @returns {Boolean}
*/
canConcat(locator) {
if (this.filters) {
return false;
Expand All @@ -81,6 +119,41 @@ export default class Locator {
return this.selector.canConcat(locator.selector);
}

/**
* Returns a new locator that is the result of merging the current locator
* with the passed locator.
*
* It is only possible if the current locator does not have any filters.
*
* @example
*
* ```html
* <div class="modal">
* <input class="project-name">
* </div>
*
* const modal = create({
* scope: '.modal',
* projectName: {
* scope: '.project-name',
* }
* });
* ```
*
* ```js
* await modal.projectName.fillIn('Project Name');
* ```
*
* will result in a single query:
*
* `.modal .project-name`
*
* instead of doing two consequent queries, one for each scope.
*
* @param {Locator} locator
*
* @returns {Locator} A new locator
*/
concat(locator) {
return new Locator(this.selector.concat(locator.selector), locator.filters);
}
Expand Down
39 changes: 37 additions & 2 deletions addon/src/-private/query/selector.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,56 @@
/**
* Base class for all selectors.
* A selector is responsible for finding elements in the DOM.
* It is used by the Locator class.
*
* @param {String} selector
*/
export class QuerySelector {
constructor(selector) {
this.selector = selector;
}

query() {
/**
* Returns a list of elements that match the selector.
*
* @param {Element} containerElement Element to search within
*
* @returns {Array<Element>} List of elements
*/
query(/* containerElement */) {
throw new Error('`query` method is not implemented');
}

/**
* Returns a string representation of the selector. Useful for the test reporter.
*
* @returns {String}
*/
toString() {
return this.selector.toString();
}

// eslint-disable-next-line no-unused-vars
/**
* Answers if the current selector type can merge with another selector.
* This allows reducing the number of queries done by the parent Locator
* by combining multiple selectors into one.
*
* @param {QuerySelector} selector
*
* @returns {Boolean}
*/
canConcat(/* selector */) {
return false;
}

/**
* Returns a new selector that is the result of merging the current selector
* with the passed selector.
*
* @param {QuerySelector} selector
*
* @returns {QuerySelector} A new selector
*/
concat(/* selector */) {
throw new Error('`concat` method is not implemented');
}
Expand Down

0 comments on commit 7e4e1fc

Please sign in to comment.