UNPKG

leadfoot

Version:

Leadfoot. A JavaScript client library that brings cross-platform consistency to the Selenium WebDriver API.

945 lines (847 loc) 30.9 kB
/* 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; var capabilities = session.capabilities; if (capabilities.isWebDriver) { var locator = strategies.toW3cLocator(using, value); using = locator.using; value = locator.value; } if (using.indexOf('link text') !== -1 && ( capabilities.brokenWhitespaceNormalization || capabilities.brokenLinkTextLocator )) { return session.execute(/* istanbul ignore next */ 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; error = newError; } throw error; }); }, /** * 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; var capabilities = session.capabilities; if (capabilities.isWebDriver) { var locator = strategies.toW3cLocator(using, value); using = locator.using; value = locator.value; } if (using.indexOf('link text') !== -1 && ( capabilities.brokenWhitespaceNormalization || capabilities.brokenLinkTextLocator )) { return session.execute(/* istanbul ignore next */ 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) { var capabilities = self.session.capabilities; if (capabilities.isWebDriver || capabilities.valueParameterCalledText) { if (capabilities.valueParameterCalledText) { // The WebDriver version of `/value` requires the value // property to be named `text` and to contain a string. return { text: arrayValue.join('') }; } else { // Browsers that support WebDriver but use the `value` // property require it to be a flat array of characters. return { value: arrayValue.join('').split('') }; } } return { value: arrayValue }; } function handleError(error) { if (error.detail.error === 'invalid argument' && !self.session.capabilities.valueParameterCalledText) { self.session.capabilities.valueParameterCalledText = true; return self.type(value); } throw error; } 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(handleError); }); } } catch (error) { // ignore } } // If the input isn't a filename, just post the value directly return this._post('value', getPostData(value)).then(noop).catch(handleError); }, /** * 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;