/* global window:false */
/**
* @module leadfoot/Element
*/
var findDisplayed = require('./lib/findDisplayed');
var fs = require('fs');
var strategies = require('./lib/strategies');
var waitForDeleted = require('./lib/waitForDeleted');
var util = require('./lib/util');
/**
* Delegates the HTTP request for a method to the underlying {@link module:leadfoot/Session} object.
*
* @private
* @param {string} method
* @returns {Promise.<any>}
*/
function delegateToSession(method) {
return function (path, requestData, pathParts) {
path = 'element/' + encodeURIComponent(this._elementId) + '/' + path;
return this._session[method](path, requestData, pathParts);
};
}
function noop() {
// At least ios-driver 0.6.6 returns an empty object for methods that are supposed to return no value at all,
// which is not correct
}
/**
* An Element represents a DOM or UI element within the remote environment.
*
* @constructor module:leadfoot/Element
*
* @param {string|module:leadfoot/Element|{ ELEMENT: string }} elementId
* The ID of the element, as provided by the remote.
*
* @param {module:leadfoot/Session} session
* The session that the element belongs to.
*/
function Element(elementId, session) {
this._elementId = elementId.ELEMENT || elementId.elementId || elementId['element-6066-11e4-a52e-4f735466cecf'] ||
elementId;
this._session = session;
}
/**
* @lends module:leadfoot/Element#
*/
Element.prototype = {
constructor: Element,
/**
* The opaque, remote-provided ID of the element.
*
* @member {string} elementId
* @memberOf module:leadfoot/Element#
* @readonly
*/
get elementId() {
return this._elementId;
},
/**
* The session that the element belongs to.
*
* @member {module:leadfoot/Session} session
* @memberOf module:leadfoot/Element#
* @readonly
*/
get session() {
return this._session;
},
_get: delegateToSession('_get'),
_post: delegateToSession('_post'),
toJSON: function () {
return { ELEMENT: this._elementId };
},
/**
* Gets the first element within this element that matches the given query.
*
* @see {@link module:leadfoot/Session#setFindTimeout} to set the amount of time it the remote environment
* should spend waiting for an element that does not exist at the time of the `find` call before timing
* out.
*
* @param {string} using
* The element retrieval strategy to use. See {@link module:leadfoot/Session#find} for options.
*
* @param {string} value
* The strategy-specific value to search for. See {@link module:leadfoot/Session#find} for details.
*
* @returns {Promise.<module:leadfoot/Element>}
*/
find: function (using, value) {
var session = this._session;
if (session.capabilities.isWebDriver) {
var locator = strategies.toW3cLocator(using, value);
using = locator.using;
value = locator.value;
}
if (using.indexOf('link text') !== -1 && this.session.capabilities.brokenWhitespaceNormalization) {
return this.session.execute(/* istanbul ignore next */ this.session._manualFindByLinkText, [
using, value, false, this
]).then(function (element) {
if (!element) {
var error = new Error();
error.name = 'NoSuchElement';
throw error;
}
return new Element(element, session);
});
}
return this._post('element', {
using: using,
value: value
}).then(function (element) {
return new Element(element, session);
}).catch(function (error) {
// At least Firefox 49 + geckodriver returns an UnknownCommand error when unable to find elements.
if (error.name === 'UnknownCommand' && error.message.indexOf('Unable to locate element:') !== -1) {
var newError = new Error();
newError.name = 'NoSuchElement';
newError.message = error.message;
throw newError;
}
});
},
/**
* Gets all elements within this element that match the given query.
*
* @param {string} using
* The element retrieval strategy to use. See {@link module:leadfoot/Session#find} for options.
*
* @param {string} value
* The strategy-specific value to search for. See {@link module:leadfoot/Session#find} for details.
*
* @returns {Promise.<module:leadfoot/Element[]>}
*/
findAll: function (using, value) {
var session = this._session;
if (session.capabilities.isWebDriver) {
var locator = strategies.toW3cLocator(using, value);
using = locator.using;
value = locator.value;
}
if (using.indexOf('link text') !== -1 && this.session.capabilities.brokenWhitespaceNormalization) {
return this.session.execute(/* istanbul ignore next */ this.session._manualFindByLinkText, [
using, value, true, this
]).then(function (elements) {
return elements.map(function (element) {
return new Element(element, session);
});
});
}
return this._post('elements', {
using: using,
value: value
}).then(function (elements) {
return elements.map(function (element) {
return new Element(element, session);
});
});
},
/**
* Clicks the element. This method works on both mouse and touch platforms.
*
* @returns {Promise.<void>}
*/
click: function () {
if (this.session.capabilities.brokenClick) {
return this.session.execute(function (element) {
element.click();
}, [ this ]);
}
var self = this;
return this._post('click').then(function () {
// ios-driver 0.6.6-SNAPSHOT April 2014 and MS Edge Driver 14316 do not wait until the default action for
// a click event occurs before returning
if (self.session.capabilities.touchEnabled || self.session.capabilities.returnsFromClickImmediately) {
return util.sleep(500);
}
});
},
/**
* Submits the element, if it is a form, or the form belonging to the element, if it is a form element.
*
* @returns {Promise.<void>}
*/
submit: function () {
if (this.session.capabilities.brokenSubmitElement) {
return this.session.execute(/* istanbul ignore next */ function (element) {
if (element.submit) {
element.submit();
}
else if (element.type === 'submit' && element.click) {
element.click();
}
}, [ this ]);
}
return this._post('submit').then(noop);
},
/**
* Gets the visible text within the element. `<br>` elements are converted to line breaks in the returned
* text, and whitespace is normalised per the usual XML/HTML whitespace normalisation rules.
*
* @returns {Promise.<string>}
*/
getVisibleText: function () {
var result = this._get('text');
if (this.session.capabilities.brokenWhitespaceNormalization) {
var self = this;
return result.then(function (text) {
return self.session._normalizeWhitespace(text);
});
}
return result;
},
/**
* Types into the element. This method works the same as the {@link module:leadfoot/Session#pressKeys} method
* except that any modifier keys are automatically released at the end of the command. This method should be used
* instead of {@link module:leadfoot/Session#pressKeys} to type filenames into file upload fields.
*
* Since 1.5, if the WebDriver server supports remote file uploads, and you type a path to a file on your local
* computer, that file will be transparently uploaded to the remote server and the remote filename will be typed
* instead. If you do not want to upload local files, use {@link module:leadfoot/Session#pressKeys} instead.
*
* @param {string|string[]} value
* The text to type in the remote environment. See {@link module:leadfoot/Session#pressKeys} for more information.
*
* @returns {Promise.<void>}
*/
type: function (value) {
function getPostData(arrayValue) {
if (self.session.capabilities.isWebDriver) {
return { value: arrayValue.join('').split('') };
}
return { value: arrayValue };
}
var self = this;
if (!Array.isArray(value)) {
value = [ value ];
}
if (this.session.capabilities.remoteFiles) {
var filename = value.join('');
// Check to see if the input is a filename; if so, upload the file and then post it's remote name into the
// field
try {
if (fs.statSync(filename).isFile()) {
return this.session._uploadFile(filename).then(function(uploadedFilename) {
return self._post('value', getPostData([ uploadedFilename ])).then(noop);
});
}
}
catch (error) {
// ignore
}
}
// If the input isn't a filename, just post the value directly
return this._post('value', getPostData(value)).then(noop);
},
/**
* Gets the tag name of the element. For HTML documents, the value is always lowercase.
*
* @returns {Promise.<string>}
*/
getTagName: function () {
var self = this;
return this._get('name').then(function (name) {
if (self.session.capabilities.brokenHtmlTagName) {
return self.session.execute(
'return document.body && document.body.tagName === document.body.tagName.toUpperCase();'
).then(function (isHtml) {
return isHtml ? name.toLowerCase() : name;
});
}
return name;
});
},
/**
* Clears the value of a form element.
*
* @returns {Promise.<void>}
*/
clearValue: function () {
return this._post('clear').then(noop);
},
/**
* Returns whether or not a form element is currently selected (for drop-down options and radio buttons), or
* whether or not the element is currently checked (for checkboxes).
*
* @returns {Promise.<boolean>}
*/
isSelected: function () {
return this._get('selected');
},
/**
* Returns whether or not a form element can be interacted with.
*
* @returns {Promise.<boolean>}
*/
isEnabled: function () {
return this._get('enabled');
},
/**
* Gets a property or attribute of the element according to the WebDriver specification algorithm. Use of this
* method is not recommended; instead, use {@link module:leadfoot/Element#getAttribute} to retrieve DOM attributes
* and {@link module:leadfoot/Element#getProperty} to retrieve DOM properties.
*
* This method uses the following algorithm on the server to determine what value to return:
*
* 1. If `name` is 'style', returns the `style.cssText` property of the element.
* 2. If the attribute exists and is a boolean attribute, returns 'true' if the attribute is true, or null
* otherwise.
* 3. If the element is an `<option>` element and `name` is 'value', returns the `value` attribute if it exists,
* otherwise returns the visible text content of the option.
* 4. If the element is a checkbox or radio button and `name` is 'selected', returns 'true' if the element is
* checked, or null otherwise.
* 5. If the returned value is expected to be a URL (e.g. element is `<a>` and attribute is `href`), returns the
* fully resolved URL from the `href`/`src` property of the element, not the attribute.
* 6. If `name` is 'class', returns the `className` property of the element.
* 7. If `name` is 'readonly', returns 'true' if the `readOnly` property is true, or null otherwise.
* 8. If `name` corresponds to a property of the element, and the property is not an Object, return the property
* value coerced to a string.
* 9. If `name` corresponds to an attribute of the element, return the attribute value.
*
* @param {string} name The property or attribute name.
* @returns {Promise.<string>} The value of the attribute as a string, or `null` if no such property or
* attribute exists.
*/
getSpecAttribute: function (name) {
var self = this;
return this._get('attribute/$0', null, [ name ]).then(function (value) {
if (self.session.capabilities.brokenNullGetSpecAttribute && (value === '' || value === undefined)) {
return self.session.execute(/* istanbul ignore next */ function (element, name) {
return element.hasAttribute(name);
}, [ self, name ]).then(function (hasAttribute) {
return hasAttribute ? value : null;
});
}
return value;
}).then(function (value) {
// At least ios-driver 0.6.6-SNAPSHOT violates draft spec and returns boolean attributes as
// booleans instead of the string "true" or null
if (typeof value === 'boolean') {
value = value ? 'true' : null;
}
return value;
});
},
/**
* Gets an attribute of the element.
*
* @see Element#getProperty to retrieve an element property.
* @param {string} name The name of the attribute.
* @returns {Promise.<string>} The value of the attribute, or `null` if no such attribute exists.
*/
getAttribute: function (name) {
return this.session.execute('return arguments[0].getAttribute(arguments[1]);', [ this, name ]);
},
/**
* Gets a property of the element.
*
* @see Element#getAttribute to retrieve an element attribute.
* @param {string} name The name of the property.
* @returns {Promise.<any>} The value of the property.
*/
getProperty: function (name) {
return this.session.execute('return arguments[0][arguments[1]];', [ this, name ]);
},
/**
* Determines if this element is equal to another element.
*
* @param {module:leadfoot/Element} other
* @returns {Promise.<boolean>}
*/
equals: function (other) {
var elementId = other.elementId || other;
var self = this;
return this._get('equals/$0', null, [ elementId ]).catch(function (error) {
// At least Selendroid 0.9.0 does not support this command;
// At least ios-driver 0.6.6-SNAPSHOT April 2014 fails
if (error.name === 'UnknownCommand' ||
(error.name === 'UnknownError' && error.message.indexOf('bug.For input string:') > -1)
) {
return self.session.execute('return arguments[0] === arguments[1];', [ self, other ]);
}
throw error;
});
},
/**
* Returns whether or not the element would be visible to an actual user. This means that the following types
* of elements are considered to be not displayed:
*
* 1. Elements with `display: none`
* 2. Elements with `visibility: hidden`
* 3. Elements positioned outside of the viewport that cannot be scrolled into view
* 4. Elements with `opacity: 0`
* 5. Elements with no `offsetWidth` or `offsetHeight`
*
* @returns {Promise.<boolean>}
*/
isDisplayed: function () {
var self = this;
return this._get('displayed').then(function (isDisplayed) {
if (isDisplayed && (
self.session.capabilities.brokenElementDisplayedOpacity ||
self.session.capabilities.brokenElementDisplayedOffscreen
)) {
return self.session.execute(/* istanbul ignore next */ function (element) {
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
do {
if (window.getComputedStyle(element, null).opacity === '0') {
return false;
}
var bbox = element.getBoundingClientRect();
if (bbox.right + scrollX <= 0 || bbox.bottom + scrollY <= 0) {
return false;
}
}
while ((element = element.parentNode) && element.nodeType === 1);
return true;
}, [ self ]);
}
return isDisplayed;
});
},
/**
* Gets the position of the element relative to the top-left corner of the document, taking into account
* scrolling and CSS transformations (if they are supported).
*
* @returns {Promise.<{ x: number, y: number }>}
*/
getPosition: function () {
if (this.session.capabilities.brokenElementPosition) {
/* jshint browser:true */
return this.session.execute(/* istanbul ignore next */ function (element) {
var bbox = element.getBoundingClientRect();
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
return { x: scrollX + bbox.left, y: scrollY + bbox.top };
}, [ this ]);
}
return this._get('location').then(function (position) {
// At least FirefoxDriver 2.41.0 incorrectly returns an object with additional `class` and `hCode`
// properties
return { x: position.x, y: position.y };
});
},
/**
* Gets the size of the element, taking into account CSS transformations (if they are supported).
*
* @returns {Promise.<{ width: number, height: number }>}
*/
getSize: function () {
function getUsingExecute() {
return self.session.execute(/* istanbul ignore next */ function (element) {
var bbox = element.getBoundingClientRect();
return { width: bbox.right - bbox.left, height: bbox.bottom - bbox.top };
}, [ self ]);
}
var self = this;
if (this.session.capabilities.brokenCssTransformedSize) {
return getUsingExecute();
}
return this._get('size').catch(function (error) {
// At least ios-driver 0.6.0-SNAPSHOT April 2014 does not support this command
if (error.name === 'UnknownCommand') {
return getUsingExecute();
}
throw error;
}).then(function (dimensions) {
// At least ChromeDriver 2.9 incorrectly returns an object with an additional `toString` property
return { width: dimensions.width, height: dimensions.height };
});
},
/**
* Gets a CSS computed property value for the element.
*
* @param {string} propertyName
* The CSS property to retrieve. This argument must be hyphenated, *not* camel-case.
*
* @returns {Promise.<string>}
*/
getComputedStyle: function (propertyName) {
function manualGetStyle() {
return self.session.execute(/* istanbul ignore next */ function (element, propertyName) {
return window.getComputedStyle(element, null)[propertyName];
}, [ self, propertyName ]);
}
var self = this;
var promise;
if (this.session.capabilities.brokenComputedStyles) {
promise = manualGetStyle();
}
else {
promise = this._get('css/$0', null, [ propertyName ]).catch(function (error) {
// At least Selendroid 0.9.0 does not support this command
if (error.name === 'UnknownCommand') {
return manualGetStyle();
}
// At least ChromeDriver 2.9 incorrectly returns an error for property names it does not understand
else if (error.name === 'UnknownError' && error.message.indexOf('failed to parse value') > -1) {
return '';
}
throw error;
});
}
return promise.then(function (value) {
// At least ChromeDriver 2.9 and Selendroid 0.9.0 returns colour values as rgb instead of rgba
if (value) {
value = value.replace(/(.*\b)rgb\((\d+,\s*\d+,\s*\d+)\)(.*)/g, function (_, prefix, rgb, suffix) {
return prefix + 'rgba(' + rgb + ', 1)' + suffix;
});
}
// For consistency with Firefox, missing values are always returned as empty strings
return value != null ? value : '';
});
}
};
/**
* Gets the first element inside this element matching the given CSS class name.
*
* @method findByClassName
* @memberOf module:leadfoot/Element#
* @param {string} className The CSS class name to search for.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first element inside this element matching the given CSS selector.
*
* @method findByCssSelector
* @memberOf module:leadfoot/Element#
* @param {string} selector The CSS selector to search for.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first element inside this element matching the given ID.
*
* @method findById
* @memberOf module:leadfoot/Element#
* @param {string} id The ID of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first element inside this element matching the given name attribute.
*
* @method findByName
* @memberOf module:leadfoot/Element#
* @param {string} name The name of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first element inside this element matching the given case-insensitive link text.
*
* @method findByLinkText
* @memberOf module:leadfoot/Element#
* @param {string} text The link text of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first element inside this element partially matching the given case-insensitive link text.
*
* @method findByPartialLinkText
* @memberOf module:leadfoot/Element#
* @param {string} text The partial link text of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first element inside this element matching the given HTML tag name.
*
* @method findByTagName
* @memberOf module:leadfoot/Element#
* @param {string} tagName The tag name of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first element inside this element matching the given XPath selector.
*
* @method findByXpath
* @memberOf module:leadfoot/Element#
* @param {string} path The XPath selector to search for.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets all elements inside this element matching the given CSS class name.
*
* @method findAllByClassName
* @memberOf module:leadfoot/Element#
* @param {string} className The CSS class name to search for.
* @returns {Promise.<module:leadfoot/Element[]>}
*/
/**
* Gets all elements inside this element matching the given CSS selector.
*
* @method findAllByCssSelector
* @memberOf module:leadfoot/Element#
* @param {string} selector The CSS selector to search for.
* @returns {Promise.<module:leadfoot/Element[]>}
*/
/**
* Gets all elements inside this element matching the given name attribute.
*
* @method findAllByName
* @memberOf module:leadfoot/Element#
* @param {string} name The name of the element.
* @returns {Promise.<module:leadfoot/Element[]>}
*/
/**
* Gets all elements inside this element matching the given case-insensitive link text.
*
* @method findAllByLinkText
* @memberOf module:leadfoot/Element#
* @param {string} text The link text of the element.
* @returns {Promise.<module:leadfoot/Element[]>}
*/
/**
* Gets all elements inside this element partially matching the given case-insensitive link text.
*
* @method findAllByPartialLinkText
* @memberOf module:leadfoot/Element#
* @param {string} text The partial link text of the element.
* @returns {Promise.<module:leadfoot/Element[]>}
*/
/**
* Gets all elements inside this element matching the given HTML tag name.
*
* @method findAllByTagName
* @memberOf module:leadfoot/Element#
* @param {string} tagName The tag name of the element.
* @returns {Promise.<module:leadfoot/Element[]>}
*/
/**
* Gets all elements inside this element matching the given XPath selector.
*
* @method findAllByXpath
* @memberOf module:leadfoot/Element#
* @param {string} path The XPath selector to search for.
* @returns {Promise.<module:leadfoot/Element[]>}
*/
strategies.applyTo(Element.prototype);
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given query. This is inherently slower than {@link module:leadfoot/Element#find}, so should only be
* used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayed
* @memberOf module:leadfoot/Element#
* @since 1.6
*
* @param {string} using
* The element retrieval strategy to use. See {@link module:leadfoot/Session#find} for options.
*
* @param {string} value
* The strategy-specific value to search for. See {@link module:leadfoot/Session#find} for details.
*
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given CSS class name. This is inherently slower than {@link module:leadfoot/Element#find}, so should
* only be used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayedByClassName
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} className The CSS class name to search for.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given CSS selector. This is inherently slower than {@link module:leadfoot/Element#find}, so should
* only be used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayedByCssSelector
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} selector The CSS selector to search for.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given ID. This is inherently slower than {@link module:leadfoot/Element#find}, so should
* only be used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayedById
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} id The ID of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given name attribute. This is inherently slower than {@link module:leadfoot/Element#find}, so should
* only be used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayedByName
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} name The name of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given case-insensitive link text. This is inherently slower than {@link module:leadfoot/Element#find},
* so should only be used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayedByLinkText
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} text The link text of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* partially matching the given case-insensitive link text. This is inherently slower than
* {@link module:leadfoot/Element#find}, so should only be used in cases where the visibility of an element cannot be
* ensured in advance.
*
* @method findDisplayedByPartialLinkText
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} text The partial link text of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given HTML tag name. This is inherently slower than {@link module:leadfoot/Element#find}, so should
* only be used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayedByTagName
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} tagName The tag name of the element.
* @returns {Promise.<module:leadfoot/Element>}
*/
/**
* Gets the first {@link module:leadfoot/Element#isDisplayed displayed} element inside this element
* matching the given XPath selector. This is inherently slower than {@link module:leadfoot/Element#find}, so should
* only be used in cases where the visibility of an element cannot be ensured in advance.
*
* @method findDisplayedByXpath
* @memberOf module:leadfoot/Element#
* @since 1.6
* @param {string} path The XPath selector to search for.
* @returns {Promise.<module:leadfoot/Element>}
*/
findDisplayed.applyTo(Element.prototype);
/**
* Waits for all elements inside this element that match the given query to be destroyed.
*
* @method waitForDeleted
* @memberOf module:leadfoot/Element#
*
* @param {string} using
* The element retrieval strategy to use. See {@link module:leadfoot/Session#find} for options.
*
* @param {string} value
* The strategy-specific value to search for. See {@link module:leadfoot/Session#find} for details.
*
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element matching the given CSS class name to be destroyed.
*
* @method waitForDeletedByClassName
* @memberOf module:leadfoot/Element#
* @param {string} className The CSS class name to search for.
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element matching the given CSS selector to be destroyed.
*
* @method waitForDeletedByCssSelector
* @memberOf module:leadfoot/Element#
* @param {string} selector The CSS selector to search for.
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element matching the given ID to be destroyed.
*
* @method waitForDeletedById
* @memberOf module:leadfoot/Element#
* @param {string} id The ID of the element.
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element matching the given name attribute to be destroyed.
*
* @method waitForDeletedByName
* @memberOf module:leadfoot/Element#
* @param {string} name The name of the element.
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element matching the given case-insensitive link text to be destroyed.
*
* @method waitForDeletedByLinkText
* @memberOf module:leadfoot/Element#
* @param {string} text The link text of the element.
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element partially matching the given case-insensitive link text to be
* destroyed.
*
* @method waitForDeletedByPartialLinkText
* @memberOf module:leadfoot/Element#
* @param {string} text The partial link text of the element.
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element matching the given HTML tag name to be destroyed.
*
* @method waitForDeletedByTagName
* @memberOf module:leadfoot/Element#
* @param {string} tagName The tag name of the element.
* @returns {Promise.<void>}
*/
/**
* Waits for all elements inside this element matching the given XPath selector to be destroyed.
*
* @method waitForDeletedByXpath
* @memberOf module:leadfoot/Element#
* @param {string} path The XPath selector to search for.
* @returns {Promise.<void>}
*/
waitForDeleted.applyTo(Element.prototype);
module.exports = Element;