Current Dev State

This commit is contained in:
Tim Lorsbach
2025-06-23 20:13:54 +02:00
parent b4f9bb277d
commit ded50edaa2
22617 changed files with 4345095 additions and 174 deletions

View File

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
* The `$$` command is a short way to call the [`elements`](/api/protocol/elements.html) command in order
* to fetch multiple elements on the page. It returns an array with element results that will have an
* extended prototype to call action commands without passing in a selector. However if you still pass
* in a selector it will look for that element first and call the action on that element.
*
* You can chain `$` or `$$` together in order to walk down the DOM tree.
*
* <example>
:index.html
<ul id="menu">
<li><a href="/">Home</a></li>
<li><a href="/">Developer Guide</a></li>
<li><a href="/">API</a></li>
<li><a href="/">Contribute</a></li>
</ul>
:$.js
it('should get text a menu link', function () {
var text = $('#menu');
console.log(text.$$('li')[2].$('a').getText()); // outputs: "API"
// same as
console.log(text.$$('li')[2].getText('a'));
});
* </example>
*
* @alias $$
* @param {String} selector selector to fetch multiple elements
* @type utility
*
*/
var $$ = function $$(selector) {
return this.elements(selector).then(function (res) {
return res.value.map(function (el, i) {
el.value = { ELEMENT: el.ELEMENT };
el.selector = selector;
el.index = i;
return el;
});
});
};
exports.default = $$;
module.exports = exports["default"];

View File

@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
* The `$` command is a short way to call the [`element`](/api/protocol/element.html) command in order
* to fetch a single element on the page. It returns an object that with an extended prototype to call
* action commands without passing in a selector. However if you still pass in a selector it will look
* for that element first an call the action on that element.
*
* You can chain `$` or `$$` together in order to walk down the DOM tree.
*
* <example>
:index.html
<ul id="menu">
<li><a href="/">Home</a></li>
<li><a href="/">Developer Guide</a></li>
<li><a href="/">API</a></li>
<li><a href="/">Contribute</a></li>
</ul>
:$.js
it('should get text a menu link', function () {
var text = $('#menu');
console.log(text.$$('li')[2].$('a').getText()); // outputs: "API"
// same as
console.log(text.$$('li')[2].getText('a'));
});
* </example>
*
* @alias $
* @param {String} selector selector to fetch a certain element
* @type utility
*
*/
var $ = function $(selector) {
return this.element(selector);
};
exports.default = $;
module.exports = exports["default"];

View File

@ -0,0 +1,48 @@
/**
*
* Add custom command to client/browser instance. Read more about `addCommand` [here](/guide/usage/customcommands.html).
*
* <example>
:addCommandAsync.js
// adding `async` as function name disables the synchronous behavior of WebdriverIO commands
// in case you need to interact with other 3rd party libraries that support promises
client.addCommand("getUrlAndTitle", function async (customVar) {
return this.url().then(function(urlResult) {
return this.getTitle().then(function(titleResult) {
console.log(customVar); // "a custom variable"
return { url: urlResult.value, title: titleResult }
})
})
})
:addCommand.js
browser.addCommand("getUrlAndTitle", function (customVar) {
return {
url: this.getUrl(),
title: this.getTitle(),
customVar: customVar
}
})
:example.js
it('should use my custom command', function () {
browser.url('http://www.github.com')
var result = browser.getUrlAndTitle('foobar')
assert.strictEqual(result.url, 'https://github.com/')
assert.strictEqual(result.title, 'GitHub · Where software is built')
assert.strictEqual(result.customVar, 'foobar')
})
* </example>
*
* @alias browser.addCommand
* @param {String} commandName name of your custom command
* @param {Function} customMethod your custom method
* @param {Boolean} overwrite if set to `true` you can overwrite existing commands
* @type utility
*
*/
// Nothing to see here!
// You can find the actual implementation in /lib/webdriverio.js
"use strict";

View File

@ -0,0 +1,100 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var addValue = function addValue(selector, value) {
var _this = this;
/*!
* parameter check
*/
if (typeof value === 'number') {
value = '' + value;
}
if (typeof value !== 'string' && !Array.isArray(value)) {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with addValue command');
}
return this.elements(selector).then(function (res) {
if (!res.value || res.value.length === 0) {
/*!
* throw NoSuchElement error if no element was found
*/
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var self = _this;
var elementIdValueCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdValueCommands.push(self.elementIdValue(elem.ELEMENT, value));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdValueCommands);
});
}; /**
*
* Add a value to an object found by given selector. You can also use unicode
* characters like Left arrow or Back space. WebdriverIO will take care of
* translating them into unicode characters. Youll find all supported characters
* [here](https://w3c.github.io/webdriver/webdriver-spec.html#dfn-character-types).
* To do that, the value has to correspond to a key from the table.
*
* <example>
:addValue.js
it('should demonstrate the addValue command', function () {
var input = $('.input')
input.setValue('test')
input.addValue(123)
// same as
browser.setValue('.input', 'test')
browser.addValue('.input', '123')
var value = elem.getValue()
assert(value === 'test123') // true
})
* </example>
*
* @alias browser.addValue
* @param {String} selector Input element
* @param {String|Number} values value to be added
* @uses protocol/elements, protocol/elementIdValue
* @type action
*
*/
exports.default = addValue;
module.exports = exports['default'];

View File

@ -0,0 +1,43 @@
/**
* You can use `call` to execute any async action within your test spec. The command itself
* it treated like a synchronous function. It accepts promises and stops the execution until
* the promise has resolved.
*
* <example>
:call.js
it('some testing here', function() {
browser.url('http://google.com')
// make an asynchronous call using any 3rd party library supporting promises
// e.g. call to backend or db to inject fixture data
browser.call(function () {
return somePromiseLibrary.someMethod().then(function () {
// ...
})
})
// example for async call to 3rd party library that doesn't support promises
browser.call(function () {
return new Promise(function(resolve, reject) {
someOtherNodeLibrary.someMethod(param1, function(err, res) {
if (err) {
return reject(err)
}
resolve(res)
})
})
})
// continue synchronously
browser.click('#elemA')
browser.setValue('.firstname','webdriverbot')
});
* </example>
*
* @alias browser.call
* @param {Function} callback function to be called
* @type utility
*
*/
"use strict";

View File

@ -0,0 +1,77 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Given a selector corresponding to an `<input type=file>` chooseFile will upload
* the local file to the browser machine and fill the form accordingly. It does not
* submit the form for you. This command only works for desktop browser.
*
* <example>
:call.js
it('uploads a file and fills the form with it', async function () {
var toUpload = path.join(__dirname, '..', '..', 'fixtures', 'cat-to-upload.gif')
browser.chooseFile('#upload-test', toUpload)
browser.getValue('#upload-test')
expect(/cat\-to\-upload\.gif$/.test(val)).to.be.equal(true)
})
* </example>
*
* @alias browser.chooseFile
* @param {String} selector input element
* @param {String} localPath local path to file to be uploaded
* @uses utility/uploadFile, action/addValue
* @type utility
*
*/
var chooseFile = function chooseFile(selector, localPath) {
var _this = this;
/*!
* parameter check
*/
if (typeof localPath !== 'string') {
return new _ErrorHandler.CommandError('number or type of arguments don\'t agree with chooseFile command');
}
/*!
* mobile check
*/
if (this.isMobile) {
return new _ErrorHandler.CommandError('chooseFile command is not supported on mobile platforms');
}
return new _promise2.default(function (resolve, reject) {
_fs2.default.stat(localPath, function (err) {
/* istanbul ignore next */
if (err) {
return reject(new _ErrorHandler.CommandError('File to upload does not exists on your system'));
}
_this.uploadFile(localPath).then(function (res) {
return this.addValue(selector, res.value);
}).then(resolve, reject);
});
});
};
exports.default = chooseFile;
module.exports = exports['default'];

View File

@ -0,0 +1,82 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var clearElement = function clearElement(selector) {
var _this = this;
return this.elements(selector).then(function (res) {
if (!res.value || res.value.length === 0) {
// throw NoSuchElement error if no element was found
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdClearCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdClearCommands.push(_this.elementIdClear(elem.ELEMENT, 'value'));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdClearCommands);
});
}; /**
*
* Clear a `<textarea>` or text `<input>` elements value. Make sure you can interact with the
* element before using this command. You can't clear an input element that is disabled or in
* readonly mode.
*
* <example>
:clearElement.js
it('should demonstrate the clearElement command', function () {
var input = $('.input')
input.setValue('test123')
console.log(input.getValue()) // returns 'test123'
input.clearElement()
// or
browser.clearElement('.input')
var value = browser.getValue('.input')
assert(value === ''); // true
})
* </example>
*
* @alias browser.clearElement
* @param {String} selector input element
* @uses protocol/elements, protocol/elementIdClear
* @type action
*
*/
exports.default = clearElement;
module.exports = exports['default'];

View File

@ -0,0 +1,60 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var click = function click(selector) {
var _this = this;
return this.element(selector).then(function (elem) {
/**
* check if element was found and throw error if not
*/
if (!elem.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.elementIdClick(elem.value.ELEMENT);
});
}; /**
*
* Click on an element based on given selector.
*
* <example>
:example.html
<button id="myButton" onclick="document.getElementById('someText').innerHTML='I was clicked'">Click me</button>
<div id="someText">I was not clicked</div>
:click.js
it('should demonstrate the click command', function () {
var myButton = $('#myButton')
myButton.click()
// or
browser.click('#myButton')
var text = browser.getText('#someText');
assert(text === 'I was clicked'); // true
})
:example.js
it('should fetch menu links and visit each page', function () {
links = $$('#menu a');
links.forEach(function (link) {
link.click();
});
});
* </example>
*
* @alias browser.click
* @param {String} selector element to click on. If it matches with more than one DOM-element it automatically clicks on the first element
* @uses protocol/element, protocol/elementIdClick
* @type action
*
*/
exports.default = click;
module.exports = exports['default'];

View File

@ -0,0 +1,52 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var close = function close(windowHandle) {
var _this = this;
if (typeof windowHandle !== 'string') {
return this.getTabIds().then(function (tabIds) {
if (tabIds.length === 0) {
throw new _ErrorHandler.RuntimeError('' + 'Can\'t switch to the next tab because all windows are closed. ' + 'Make sure you keep at least one window open!');
}
return _this.window().switchTab(tabIds[0]);
});
}
return this.window().switchTab(windowHandle);
}; /**
*
* Close current window (and focus on an other window). If no window handle is given
* it automatically switches back to the first handle.
*
* <example>
:close.js
it('should demonstrate the close command', function () {
browser.url('http://github.com')
browser.newWindow('http://google.com')
var title = browser.getTitle()
console.log(title) // outputs: "Google"
browser.close()
title = browser.getTitle()
console.log(title) // outputs: "GitHub · Build software better, together."
})
* </example>
*
* @alias browser.close
* @param {String=} windowHandle new window to focus on
* @uses protocol/window, window/switchTab
* @type window
*
*/
exports.default = close;
module.exports = exports['default'];

View File

@ -0,0 +1,141 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _vm = require('vm');
var _vm2 = _interopRequireDefault(_vm);
var _repl = require('repl');
var _repl2 = _interopRequireDefault(_repl);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var debug = function debug() {
var commandTimeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 5000;
var _this = this;
var enableStdout = arguments[1];
var enableLogging = arguments[2];
var commandIsRunning = false;
var logLevel = this.logger.logLevel;
this.logger.logLevel = 'verbose';
this.logger.debug();
if (!enableLogging) {
this.logger.logLevel = logLevel;
}
var myEval = function myEval(cmd, context, filename, callback) {
if (commandIsRunning) {
return;
}
if (cmd === 'browser\n') {
return callback(null, '[WebdriverIO REPL client]');
}
commandIsRunning = true;
var result = void 0;
if (typeof global.wdioSync === 'function') {
return global.wdioSync(function () {
try {
result = _vm2.default.runInThisContext(cmd);
} catch (e) {
commandIsRunning = false;
return callback(e);
}
callback(null, result);
commandIsRunning = false;
})();
}
context.browser = _this;
try {
result = _vm2.default.runInThisContext(cmd);
} catch (e) {
commandIsRunning = false;
return callback(e);
}
if (!result || typeof result.then !== 'function') {
commandIsRunning = false;
return callback(null, result);
}
var timeout = setTimeout(function () {
return callback(new _ErrorHandler.RuntimeError('Command execution timed out'));
}, commandTimeout);
result.then(function (res) {
commandIsRunning = false;
clearTimeout(timeout);
return callback(null, res);
}, function (e) {
commandIsRunning = false;
clearTimeout(timeout);
return callback(e);
});
};
var replServer = _repl2.default.start({
prompt: '> ',
eval: myEval,
input: process.stdin,
output: process.stdout,
useGlobal: true,
ignoreUndefined: true
});
return new _promise2.default(function (resolve) {
replServer.on('exit', function () {
_this.logger.logLevel = logLevel;
resolve();
});
});
}; /**
*
* This command helps you to debug your integration tests. It stops the running browser and gives
* you time to jump into it and check the state of your application (e.g. using the dev tools).
* Your terminal transforms into a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
* interface that will allow you to try out certain commands, find elements and test actions on
* them.
*
* [![WebdriverIO REPL](http://webdriver.io/images/repl.gif)](http://webdriver.io/images/repl.gif)
*
* If you run the WDIO testrunner make sure you increase the timeout property of your test framework
* your are using (e.g. Mocha or Jasmine) in order to prevent the continuation due to a test timeout.
* Also avoid to execute the command with multiple capabilities running at the same time.
*
* <iframe width="560" height="315" src="https://www.youtube.com/embed/xWwP-3B_YyE" frameborder="0" allowfullscreen></iframe>
*
* <example>
:debug.js
it('should demonstrate the debug command', function () {
browser.setValue('#input', 'FOO')
browser.debug() // jumping into the browser and change value of #input to 'BAR'
var value = browser.getValue('#input')
console.log(value) // outputs: "BAR"
})
* </example>
*
* @alias browser.debug
* @type utility
*
*/
exports.default = debug;
module.exports = exports['default'];

View File

@ -0,0 +1,60 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Delete cookies visible to the current page. By providing a cookie name it just removes the single cookie.
*
* <example>
:deleteCookie.js
it('should delete cookies', function () {
browser.setCookie({name: 'test', value: '123'})
browser.setCookie({name: 'test2', value: '456'})
browser.setCookie({name: 'test3', value: '789'})
var cookies = browser.getCookie()
console.log(cookies)
// outputs:
// [
// { name: 'test', value: '123' },
// { name: 'test2', value: '456' }
// { name: 'test3', value: '789' }
// ]
browser.deleteCookie('test3')
cookies = browser.getCookie()
console.log(cookies)
// outputs:
// [
// { name: 'test', value: '123' },
// { name: 'test2', value: '456' }
// ]
browser.deleteCookie()
cookies = browser.getCookie()
console.log(cookies) // outputs: []
})
* </example>
*
* @alias browser.deleteCookie
* @param {String=} name name of cookie to be deleted
* @uses protocol/cookie
* @type cookie
*
*/
var deleteCookie = function deleteCookie(name) {
/*!
* parameter check
*/
if (typeof name !== 'string') {
name = null;
}
return this.cookie('DELETE', name);
};
exports.default = deleteCookie;
module.exports = exports['default'];

View File

@ -0,0 +1,64 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var doubleClick = function doubleClick(selector) {
var _this = this;
if (this.isMobile) {
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.touchDoubleClick(res.value.ELEMENT);
});
}
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.moveTo(res.value.ELEMENT);
}).doDoubleClick();
}; /**
*
* Double-click on an element based on given selector.
*
* <example>
:example.html
<button id="myButton" ondblclick="document.getElementById('someText').innerHTML='I was dblclicked'">Click me</button>
<div id="someText">I was not clicked</div>
:doubleClick.js
it('should demonstrate the doubleClick command', function () {
var myButton = $('#myButton')
myButton.doubleClick()
// or
browser.doubleClick('#myButton')
var value = browser.getText('#someText')
assert(value === 'I was dblclicked') // true
})
* </example>
*
* @alias browser.doubleClick
* @param {String} selector element to double click on. If it matches with more than on DOM-element it automatically clicks on the first element
* @uses protocol/element, protocol/moveTo, protocol/doDoubleClick, protocol/touchDoubleClick
* @type action
*
*/
exports.default = doubleClick;
module.exports = exports['default'];

View File

@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Drag an item to a destination element. __Note:__ this command only works for some drag&drop implementation
* and some browser because of the way how Selenium simulates mouse events.
*
* @alias browser.dragAndDrop
* @param {String} sourceElem source selector
* @param {String} destinationElem destination selector
* @uses action/moveToObject, protocol/buttonDown, protocol/buttonUp, property/getLocation, protocol/touchDown, protocol/touchMove, protocol/touchUp
* @type action
*
*/
var dragAndDrop = function dragAndDrop(selector, destinationElem) {
var _this = this;
if (this.isMobile) {
return this.getLocation(selector).then(function (location) {
return _this.touchDown(location.x, location.y);
}).getLocation(destinationElem).then(function (location) {
return _this.touchMove(location.x, location.y).touchUp(location.x, location.y);
});
}
return this.moveToObject(selector).buttonDown().moveToObject(destinationElem).buttonUp();
};
exports.default = dragAndDrop;
module.exports = exports["default"];

View File

@ -0,0 +1,35 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* End the session and close browser. This command is only supported in standalone mode. If you
* are using the wdio testrunner you can't close the browser before your spec finishes. The testrunner
* will close the browser for you after the spec has finished.
*
* However if you want to refresh the browser session you can try the [`reload`](/api/utility/reload.html)
* command.
*
* <example>
:endAsync.js
client
.init() // starts session and opens the browser
.url('http://google.com')
// ... other commands
.end(); // ends session and close browser
* </example>
*
* @alias browser.end
* @uses protocol/session
* @type utility
*
*/
var end = function end() {
return this.session('delete');
};
exports.default = end;
module.exports = exports['default'];

View File

@ -0,0 +1,60 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* End all selenium server sessions at once. Like the [`end`](/api/utility/end.html) command is this command
* only supported in standalone mode.
*
* @alias browser.endAll
* @uses protocol/sessions, protocol/session
* @type utility
*
*/
var endAll = function endAll() {
var _this = this;
return this.sessions().then(function (res) {
var sessionCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var session = _step.value;
sessionCommands.push(_this.session('delete', session.id));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(sessionCommands);
});
};
exports.default = endAll;
module.exports = exports['default'];

View File

@ -0,0 +1,102 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getAttribute = function getAttribute(selector, attributeName) {
var _this = this;
/*!
* parameter check
*/
if (typeof attributeName !== 'string') {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with getAttribute command');
}
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdAttributeCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdAttributeCommands.push(_this.elementIdAttribute(elem.ELEMENT, attributeName));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdAttributeCommands, {
extractValue: true
});
});
}; /**
*
* Get an attribute from an DOM-element based on the selector and attribute name.
* Returns a list of attribute values if selector matches multiple elements.
*
* <example>
:index.html
<form action="/submit" method="post" class="loginForm">
<input type="text" name="name" placeholder="username"></input>
<input type="text" name="password" placeholder="password"></input>
<input type="submit" name="submit" value="submit"></input>
</form>
:getAttribute.js
it('should demonstrate the getAttribute command', function () {
var form = $('form')
var attr = form.getAttribute('method')
console.log(attr) // outputs: "post"
// or
console.log(browser.getAttribute('form', 'method')) // outputs: "post"
// if your selector matches multiple elements it returns an array of results
var allInputs = $$('.loginForm input')
console.log(allInputs.map(function(el) { return el.getAttribute('name'); })) // outputs: ['name', 'password', 'submit']
})
* </example>
*
* @alias browser.getAttribute
* @param {String} selector element with requested attribute
* @param {String} attributeName requested attribute
* @return {String|String[]|null} The value of the attribute(s), or null if it is not set on the element.
* @uses protocol/elements, protocol/elementIdAttribute
* @type property
*
*/
exports.default = getAttribute;
module.exports = exports['default'];

View File

@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Returns a list of previous called commands + their arguments and execution timestamp.
*
* <example>
:getCommandHistoryAsync.js
client
.init()
.url('http://www.google.com')
.click('#username')
.addValue('#password', 'text')
.pause(2000)
.getCommandHistory().then(function(history){
console.log(history);
// outputs:
// [ { name: 'init', args: [], timestamp: 1487078962707 },
// { name: 'url', args: [ 'http://www.google.com' ], timestamp: 1487078962707 },
// { name: 'click', args: [ 'body' ], timestamp: 1487078962707 },
// { name: 'element',
// args: [ 'body' ],
// timestamp: 1487078962707,
// result:
// { state: 'success',
// sessionId: 'c2aea856-ba18-48c0-8745-aa292f6394bc',
// hCode: 1094372184,
// value: [Object],
// class: 'org.openqa.selenium.remote.Response',
// status: 0,
// selector: 'body' } },
// { name: 'elementIdClick',
// args: [ '0' ],
// timestamp: 1487078962707,
// result:
// { state: 'success',
// sessionId: 'c2aea856-ba18-48c0-8745-aa292f6394bc',
// hCode: 1704637158,
// value: null,
// class: 'org.openqa.selenium.remote.Response',
// status: 0 } },
// { name: 'addValue', args: [ '#lst-ib', 'webdriverio' ], timestamp: 1487078962707 },
// { name: 'elements',
// args: [ '#lst-ib' ],
// timestamp: 1487078962707,
// result:
// { state: 'success',
// sessionId: 'c2aea856-ba18-48c0-8745-aa292f6394bc',
// hCode: 1171202369,
// value: [Object],
// class: 'org.openqa.selenium.remote.Response',
// status: 0,
// selector: '#lst-ib' } },
// { name: 'elementIdValue',
// args: [ '1', 'webdriverio' ],
// timestamp: 1487078962707,
// result:
// { state: 'success',
// sessionId: 'c2aea856-ba18-48c0-8745-aa292f6394bc',
// hCode: 447115314,
// value: null,
// class: 'org.openqa.selenium.remote.Response',
// status: 0 } },
// { name: 'pause', args: [ 2000 ], timestamp: 1487078962707 } ]
})
.end();
* </example>
*
* @alias browser.getCommandHistory
* @return {Object[]} list of recent called commands + their arguments
* @type utility
*
*/
var getCommandHistory = function getCommandHistory() {
return this.commandList.slice(0, -1);
};
exports.default = getCommandHistory;
module.exports = exports["default"];

View File

@ -0,0 +1,61 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Retrieve a [cookie](https://w3c.github.io/webdriver/webdriver-spec.html#cookies)
* visible to the current page. You can query a specific cookie by providing the cookie name or
* retrieve all.
*
* <example>
:getCookie.js
it('should return a cookie for me', function () {
browser.setCookie({name: 'test', value: '123'})
browser.setCookie({name: 'test2', value: '456'})
var testCookie = browser.getCookie('test')
console.log(testCookie); // outputs: { name: 'test', value: '123' }
var allCookies = browser.getCookie()
console.log(allCookies);
// outputs:
// [
// { name: 'test', value: '123' },
// { name: 'test2', value: '456' }
// ]
})
* </example>
*
* @alias browser.getCookie
* @param {String=} name name of requested cookie
* @return {Object|null} requested cookie if existing
* @uses protocol/cookie
* @type cookie
*
*/
var getCookie = function getCookie(name) {
/*!
* paramter check
*/
if (typeof name !== 'string') {
name = null;
}
return this.cookie().then(function (res) {
res.value = res.value || [];
if (typeof name === 'string') {
return res.value.filter(function (cookie) {
return cookie.name === name;
})[0] || null;
}
return res.value || (typeof name === 'string' ? null : []);
});
};
exports.default = getCookie;
module.exports = exports['default'];

View File

@ -0,0 +1,148 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _parseCSS = require('../helpers/parseCSS.js');
var _parseCSS2 = _interopRequireDefault(_parseCSS);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Get a css property from a DOM-element selected by given selector. The return value
* is formatted to be testable. Colors gets parsed via [rgb2hex](https://www.npmjs.org/package/rgb2hex)
* and all other properties get parsed via [css-value](https://www.npmjs.org/package/css-value).
*
* Note that shorthand CSS properties (e.g. background, font, border, margin, padding, list-style, outline,
* pause, cue) are not returned, in accordance with the DOM CSS2 specification - you should directly access
* the longhand properties (e.g. background-color) to access the desired values.
*
* <example>
:example.html
<label id="myLabel" for="input" style="color: #0088cc; font-family: helvetica, arial, freesans, clean, sans-serif, width: 100px">Some Label</label>
:getCssProperty.js
it('should demonstrate the getCssProperty command', function () {
var elem = $('#myLabel')
var color = elem.getCssProperty('color')
console.log(color)
// outputs the following:
// {
// property: 'color',
// value: 'rgba(0, 136, 204, 1)',
// parsed: {
// hex: '#0088cc',
// alpha: 1,
// type: 'color',
// rgba: 'rgba(0, 136, 204, 1)'
// }
// }
var font = elem.getCssProperty('font-family')
console.log(font)
// outputs the following:
// {
// property: 'font-family',
// value: 'helvetica',
// parsed: {
// value: [ 'helvetica', 'arial', 'freesans', 'clean', 'sans-serif' ],
// type: 'font',
// string: 'helvetica, arial, freesans, clean, sans-serif'
// }
// }
var width = elem.getCssProperty('width')
console.log(width)
// outputs the following:
// {
// property: 'width',
// value: '100px',
// parsed: {
// type: 'number',
// string: '100px',
// unit: 'px',
// value: 100
// }
// }
})
* </example>
*
* @alias browser.getCssProperty
* @param {String} selector element with requested style attribute
* @param {String} cssProperty css property name
* @uses protocol/elements, protocol/elementIdCssProperty
* @type property
*
*/
var getCssProperty = function getCssProperty(selector, cssProperty) {
var _this = this;
/*!
* parameter check
*/
if (typeof cssProperty !== 'string') {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with getCssProperty command');
}
return this.elements(selector).then(function (res) {
if (!res.value || res.value.length === 0) {
// throw NoSuchElement error if no element was found
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdCssPropertyCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdCssPropertyCommands.push(_this.elementIdCssProperty(elem.ELEMENT, cssProperty));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _promise2.default.all(elementIdCssPropertyCommands);
}).then(function (result) {
/**
* result already unwrapped when command was reran
*/
if (!Array.isArray(result)) {
return result;
}
return (0, _parseCSS2.default)(result, cssProperty);
});
};
exports.default = getCssProperty;
module.exports = exports['default'];

View File

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Retrieve the current window handle.
*
* <example>
:getCurrenteTabId.js
it('should return the current tab id', function () {
browser.url('http://webdriver.io')
var tabId = browser.getCurrentTabId()
console.log(tabid)
// outputs something like the following:
// "CDwindow-C43FB686-949D-4232-828B-583398FBD0C0"
})
* </example>
*
* @alias browser.getCurrentTabId
* @return {String} the window handle URL of the current focused window
* @uses protocol/windowHandle
* @type window
*
*/
var getCurrentTabId = function getCurrentTabId() {
return this.unify(this.windowHandle(), {
extractValue: true
});
};
exports.default = getCurrentTabId;
module.exports = exports["default"];

View File

@ -0,0 +1,113 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getElementSize = function getElementSize(selector, prop) {
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || this.lastResult.selector);
}
var elementIdSizeCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdSizeCommands.push(this.elementIdSize(elem.ELEMENT));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _promise2.default.all(elementIdSizeCommands);
}).then(function (sizes) {
/**
* result already unwrapped when command was reran
*/
if (!Array.isArray(sizes)) {
return sizes;
}
sizes = sizes.map(function (size) {
if (typeof prop === 'string' && prop.match(/(width|height)/)) {
return size.value[prop];
}
return {
width: size.value.width,
height: size.value.height
};
});
return sizes.length === 1 ? sizes[0] : sizes;
});
}; /**
*
* Get the width and height for an DOM-element based given selector.
*
* <example>
:getElementSize.js
it('should give me the size of an element', function () {
browser.url('http://github.com')
var logo = $('.octicon-mark-github')
var size = logo.getElementSize()
// or
size = browser.getElementSize('.octicon-mark-github')
console.log(size) // outputs: { width: 32, height: 32 }
var width = logo.getElementSize('width')
// or
width = browser.getElementSize('.octicon-mark-github', 'width')
console.log(width) // outputs: 32
var height = logo.getElementSize('height')
// or
height = browser.getElementSize('.octicon-mark-github', 'height')
console.log(height) // outputs: 32
})
* </example>
*
* @alias browser.getElementSize
* @param {String} selector element with requested size
* @param {String*} prop size to receive (optional "width|height")
* @return {Object|Number} requested element size (`{ width: <Number>, height: <Number> }`) or actual width/height as number if prop param is given
* @uses protocol/elements, protocol/elementIdSize
* @type property
*
*/
exports.default = getElementSize;
module.exports = exports['default'];

View File

@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Get the current geolocation.
*
* <example>
:getGeoLocation.js
it('should return my current location', function () {
var location = browser.getGeoLocation()
console.log(location)
// outputs:
// {
// latitude: 51.1045407,
// longitude: 13.2017384,
// altitude: 20.23345
// }
})
* </example>
*
* @alias browser.getGeoLocation
* @return {Object} the current geo location (`{latitude: number, longitude: number, altitude: number}`)
* @uses protocol/location
* @type mobile
*
*/
var getGeoLocation = function getGeoLocation() {
return this.unify(this.location(), {
extractValue: true
});
};
exports.default = getGeoLocation;
module.exports = exports["default"];

View File

@ -0,0 +1,69 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Get the details of the Selenium Grid node running a session
*
* <example>
:grid.js
it('should return grid information', function () {
console.log(browser.getGridNodeDetails())
// {
// success: true,
// msg: "proxy found !",
// id: "MacMiniA10",
// request: {
// ...
// configuration: {
// ...
// },
// capabilities: [
// {
// ...
// }
// ]
// }
// }
})
* </example>
*
* @alias browser.getGridNodeDetails
* @uses grid/gridTestSession, grid/gridProxyDetails
* @type grid
*/
var getGridNodeDetails = function getGridNodeDetails() {
var _this = this;
return this.gridTestSession().then(function (session) {
return _this.gridProxyDetails(session.proxyId).then(function (details) {
delete session.msg;
delete session.success;
delete details.msg;
delete details.success;
delete details.id;
return (0, _assign2.default)(details, session);
});
}).catch(function (e) {
if (e.seleniumStack && e.seleniumStack.type === 'GridApiError') {
return {
error: e.message
};
}
});
};
exports.default = getGridNodeDetails;
module.exports = exports['default'];

View File

@ -0,0 +1,69 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var _getHTML = require('../scripts/getHTML');
var _getHTML2 = _interopRequireDefault(_getHTML);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Get source code of specified DOM element by selector.
*
* <example>
:index.html
<div id="test">
<span>Lorem ipsum dolor amet</span>
</div>
:getHTML.js
it('should get html for certain elements', function () {
var outerHTML = browser.getHTML('#test');
console.log(outerHTML);
// outputs:
// "<div id="test"><span>Lorem ipsum dolor amet</span></div>"
var innerHTML = browser.getHTML('#test', false);
console.log(innerHTML);
// outputs:
// "<span>Lorem ipsum dolor amet</span>"
});
* </example>
*
* @alias browser.getHTML
* @param {String} selector element to get the current DOM structure from
* @param {Boolean=} includeSelectorTag if true it includes the selector element tag (default: true)
* @uses action/selectorExecute
* @type property
*
*/
var getHTML = function getHTML(selector, includeSelectorTag) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if includeSelectorTag is used
*/
includeSelectorTag = typeof includeSelectorTag === 'boolean' ? includeSelectorTag : true;
return this.selectorExecute(selector, _getHTML2.default, includeSelectorTag).then(function (html) {
/**
* throw NoSuchElement error if no element was found
*/
if (!html) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
return html && html.length === 1 ? html[0] : html;
});
};
exports.default = getHTML;
module.exports = exports['default'];

View File

@ -0,0 +1,93 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getLocation = function getLocation(selector, prop) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var results = [];
var that = _this;
return new _promise2.default(function (resolve, reject) {
var hasError = false;
function processNext() {
var current = res.value.pop();
return that.elementIdLocation(current.ELEMENT).catch(function (err) {
hasError = true;
reject(err);
}).then(function (location) {
if (hasError) {
return;
}
if (prop === 'x' || prop === 'y') {
results.push(location.value[prop]);
} else {
results.push({
x: location.value.x,
y: location.value.y
});
}
if (res.value.length) {
return processNext();
} else {
resolve(results.length === 1 ? results[0] : results);
}
});
}
return processNext();
});
});
}; /**
*
* Determine an elements location on the page. The point (0, 0) refers to
* the upper-left corner of the page.
*
* <example>
:getLocation.js
it('should get the location of one or multiple elements', function () {
browser.url('http://github.com');
var location = browser.getLocation('.octicon-mark-github');
console.log(location); // outputs: { x: 150, y: 20 }
var xLocation = browser.getLocation('.octicon-mark-github', 'x')
console.log(xLocation); // outputs: 150
var yLocation = browser.getLocation('.octicon-mark-github', 'y')
console.log(yLocation); // outputs: 20
});
* </example>
*
* @alias browser.getLocation
* @param {String} selector element with requested position offset
* @param {String} property can be "x" or "y" to get a result value directly for easier assertions
* @return {Object|Object[]} The X and Y coordinates for the element on the page (`{x:number, y:number}`)
* @uses protocol/elements, protocol/elementIdLocation
* @type property
*
*/
exports.default = getLocation;
module.exports = exports['default'];

View File

@ -0,0 +1,108 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getLocationInView = function getLocationInView(selector, prop) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdLocationInViewCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdLocationInViewCommands.push(_this.elementIdLocationInView(elem.ELEMENT));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _promise2.default.all(elementIdLocationInViewCommands);
}).then(function (locations) {
/**
* result already unwrapped when command was reran
*/
if (!Array.isArray(locations)) {
return locations;
}
locations = locations.map(function (location) {
if (typeof prop === 'string' && prop.match(/(x|y)/)) {
return location.value[prop];
}
return {
x: location.value.x,
y: location.value.y
};
});
return locations.length === 1 ? locations[0] : locations;
});
}; /**
*
* Determine an elements location on the screen once it has been scrolled into view.
*
* <example>
:getLocationInView.js
it('should get the location of one or multiple elements in view', function () {
browser.url('http://github.com');
var location = browser.getLocationInView('.octicon-mark-github');
console.log(location); // outputs: { x: 150, y: 20 }
var xLocation = browser.getLocationInView('.octicon-mark-github', 'x')
console.log(xLocation); // outputs: 150
var yLocation = browser.getLocationInView('.octicon-mark-github', 'y')
console.log(yLocation); // outputs: 20
});
* </example>
*
* @alias browser.getLocationInView
* @param {String} selector element with requested position offset
* @return {Object|Object[]} The X and Y coordinates for the element on the page (`{x:number, y:number}`)
*
* @uses protocol/elements, protocol/elementIdLocationInView
* @type property
*
*/
exports.default = getLocationInView;
module.exports = exports['default'];

View File

@ -0,0 +1,40 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var getOrientation = function getOrientation() {
if (!this.isMobile) {
throw new _ErrorHandler.CommandError('getOrientation command is not supported on non mobile platforms');
}
return this.unify(this.orientation(), {
lowercase: true,
extractValue: true
});
}; /**
*
* Get the current browser orientation. This command only works for mobile environments like Android Emulator,
* iOS Simulator or on real devices.
*
* <example>
:getOrientation.js
it('should get the orientation of my mobile device', function () {
var orientation = browser.getOrientation();
console.log(orientation); // outputs: "landscape"
});
* </example>
*
* @alias browser.getOrientation
* @return {String} device orientation (`landscape/portrait`)
* @uses protocol/orientation
* @for android, ios
* @type mobile
*
*/
exports.default = getOrientation;
module.exports = exports['default'];

View File

@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Get source code of the page. This command won't work in mobile environments for native apps. If you running
* hybrid tests make sure that you are in the webview before calling this command.
*
* <example>
:getSource.js
it('should get the source of the html document', function () {
browser.url('http://webdriver.io');
var source = browser.getSource();
console.log(source); // outputs: "<!DOCTYPE html>\n<title>Webdriver.io</title>..."
});
* </example>
*
* @alias browser.getSource
* @return {String} source code of current website
* @uses protocol/source
* @type property
*
*/
var getSource = function getSource() {
return this.unify(this.source(), {
extractValue: true
});
};
exports.default = getSource;
module.exports = exports["default"];

View File

@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Retrieve a list of all window handles available in the session. You can use these handles to switch
* to a different tab.
*
* <example>
:getTabIds.js
it('should get the source of the html document', function () {
browser.url('http://webdriver.io');
var tabIds = browser.getTabIds();
console.log(tabIds); // outputs: ['f9b387e0-99bd-11e6-8881-d3174a61fdce']
browser.newWindow('http://google.com');
tabIds = browser.getTabIds();
console.log(tabIds); // outputs: ['f9b387e0-99bd-11e6-8881-d3174a61fdce', 'fb4e9a40-99bd-11e6-8881-d3174a61fdce' ]
});
* </example>
*
* @alias browser.getTabIds
* @return {String[]} a list of window handles
* @uses protocol/windowHandles
* @type window
*
*/
var getTabIds = function getTabIds() {
return this.unify(this.windowHandles(), {
extractValue: true
});
};
exports.default = getTabIds;
module.exports = exports["default"];

View File

@ -0,0 +1,82 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getTagName = function getTagName(selector) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdNameCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdNameCommands.push(_this.elementIdName(elem.ELEMENT));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdNameCommands, {
extractValue: true
});
});
}; /**
*
* Get tag name of a DOM-element found by given selector.
*
* <example>
:index.html
<div id="elem">Lorem ipsum</div>
:getTagName.js
it('should demonstrate the getTagName command', function () {
var elem = $('#elem');
var tagName = elem.getTagName();
console.log(tagName); // outputs: "div"
})
* </example>
*
* @alias browser.getTagName
* @param {String} selector element with requested tag name
* @return {String|String[]} the element's tag name, as a lowercase string
* @uses protocol/elements, protocol/elementIdName
* @type property
*
*/
exports.default = getTagName;
module.exports = exports['default'];

View File

@ -0,0 +1,101 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getText = function getText(selector) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdTextCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdTextCommands.push(_this.elementIdText(elem.ELEMENT));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdTextCommands, {
extractValue: true
});
});
}; /**
*
* Get the text content from a DOM-element found by given selector. Make sure the element
* you want to request the text from [is interactable](http://www.w3.org/TR/webdriver/#interactable)
* otherwise you will get an empty string as return value. If the element is disabled or not
* visible and you still want to receive the text content use [getHTML](http://webdriver.io/api/property/getHTML.html)
* as a workaround.
*
* <example>
:index.html
<div id="elem">
Lorem ipsum <strong>dolor</strong> sit amet,<br>
consetetur sadipscing elitr
</div>
<span style="display: none">I am invisible</span>
:getText.js
it('should get text of an element or elements', function () {
var text = browser.getText('#elem');
console.log(text);
// outputs the following:
// "Lorem ipsum dolor sit amet,consetetur sadipscing elitr"
var spanText = browser.getText('span');
console.log(text);
// outputs "" (empty string) since element is not interactable
});
it('get content from table cell', function () {
browser.url('http://the-internet.herokuapp.com/tables');
var rows = $$('#table1 tr');
var columns = rows[1].$$('td'); // get columns of 2nd row
console.log(columns[2].getText()); // get text of 3rd column
});
* </example>
*
* @alias browser.getText
* @param {String} selector element with requested text
* @return {String|String[]} content of selected element (all HTML tags are removed)
* @uses protocol/elements, protocol/elementIdText
* @type property
*
*/
exports.default = getText;
module.exports = exports['default'];

View File

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Get the title of current opened website. This command only works for browser environments or on mobile
* devices with webview enabled (hybrid tests).
*
* <example>
:getTitle.js
it('should get the title of the document', function () {
browser.url('http://webdriver.io');
var title = browser.getTitle()
console.log(title);
// outputs the following:
// "WebdriverIO - WebDriver bindings for Node.js"
});
* </example>
*
* @alias browser.getTitle
* @return {String} current page title
* @uses protocol/title
* @type property
*
*/
var getTitle = function getTitle() {
return this.unify(this.title(), {
extractValue: true
});
};
exports.default = getTitle;
module.exports = exports["default"];

View File

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Get the url of current opened website.
*
* <example>
:getUrl.js
it('should get the url of the current page', function () {
browser.url('http://webdriver.io');
var url = browser.getUrl();
console.log(url);
// outputs the following:
// "http://webdriver.io"
});
* </example>
*
* @alias browser.getUrl
* @return {String} current page url
* @uses protocol/url
* @type property
*
*/
var getUrl = function getUrl() {
return this.unify(this.url(), {
extractValue: true
});
};
exports.default = getUrl;
module.exports = exports["default"];

View File

@ -0,0 +1,82 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getValue = function getValue(selector) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdAttributeCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdAttributeCommands.push(_this.elementIdAttribute(elem.ELEMENT, 'value'));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdAttributeCommands, {
extractValue: true
});
});
}; /**
*
* Get the value of a `<textarea>`, `<select>` or text `<input>` found by given selector.
*
* <example>
:index.html
<input type="text" value="John Doe" id="username">
:getValue.js
it('should demonstrate the getValue command', function () {
var inputUser = $('#username');
var value = inputUser.getValue();
console.log(value); // outputs: "John Doe"
});
* </example>
*
* @alias browser.getValue
* @param {String} selector input, textarea, or select element
* @return {String} requested input value
* @uses protocol/elements, protocol/elementIdAttribute
* @type property
*
*/
exports.default = getValue;
module.exports = exports['default'];

View File

@ -0,0 +1,55 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getViewportSize = require('../scripts/getViewportSize');
var _getViewportSize2 = _interopRequireDefault(_getViewportSize);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var getViewportSize = function getViewportSize(prop) {
return this.execute(_getViewportSize2.default).then(function (res) {
if (typeof prop === 'string' && prop.match(/(width|height)/)) {
prop = 'screen' + prop.slice(0, 1).toUpperCase() + prop.slice(1);
return res.value[prop];
}
return {
width: res.value.screenWidth || 0,
height: res.value.screenHeight || 0
};
});
}; /**
*
* Get viewport size of the current browser window. This command only works on desktop browser or in a mobile
* environment with a webview enabled.
*
* <example>
:getViewportSize.js
it('should return the viewport size', function () {
browser.url('http://webdriver.io');
var size = browser.getViewportSize()
console.log(size); // outputs: {width: 1024, height: 768}
var width = browser.getViewportSize('width')
console.log(size); // outputs: 1024
var height = browser.getViewportSize('height');
console.log(height); // outputs: 768
});
* </example>
*
* @alias browser.getViewportSize
* @param {String} property if "width" or "height" is set it returns only that property
* @return {Object} viewport width and height of the browser
* @uses protocol/execute
* @type window
*
*/
exports.default = getViewportSize;
module.exports = exports['default'];

View File

@ -0,0 +1,65 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var hasFocus = function hasFocus(selector) {
var _this = this;
return this.unify(this.elements(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value || !res.value.length) {
throw new _ErrorHandler.RuntimeError(7);
}
return res.value;
}).then(function (elements) {
return _this.execute(function (elemArray) {
var focused = document.activeElement;
if (!focused) {
return false;
}
return elemArray.filter(function (elem) {
return focused === elem;
}).length > 0;
}, elements);
}), {
extractValue: true
});
}; /**
*
* Return true or false if the selected DOM-element currently has focus. If the selector matches
* multiple elements, it will return true if one of the elements has focus.
*
* <example>
:index.html
<input name="login" autofocus="" />
:hasFocus.js
it('should detect the focus of an element', function () {
browser.url('/');
var loginInput = $('[name="login"]');
console.log(loginInput.hasFocus()); // outputs: false
loginInput.click();
console.log(loginInput.hasFocus()); // outputs: true
})
* </example>
*
* @alias browser.hasFocus
* @param {String} selector selector for element(s) to test for focus
* @return {Boolean} true if one of the matching elements has focus
* @uses protocol/execute protocol/elements
* @type state
*
*/
exports.default = hasFocus;
module.exports = exports['default'];

View File

@ -0,0 +1,35 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var hold = function hold(selector) {
var _this = this;
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.touchLongClick(res.value.ELEMENT);
});
}; /**
*
* Long press on an element using finger motion events. This command works only in a
* mobile context.
*
* @alias browser.hold
* @param {String} selector element to hold on
* @uses protocol/element, protocol/touchLongClick
* @type mobile
*
*/
exports.default = hold;
module.exports = exports['default'];

View File

@ -0,0 +1,88 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var isEnabled = function isEnabled(selector) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdEnabledCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdEnabledCommands.push(_this.elementIdEnabled(elem.ELEMENT));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdEnabledCommands, {
extractValue: true
});
});
}; /**
*
* Return true or false if the selected DOM-element found by given selector is enabled.
*
* <example>
:index.html
<input type="text" name="inputField" class="input1">
<input type="text" name="inputField" class="input2" disabled>
<input type="text" name="inputField" class="input3" disabled="disabled">
:isEnabled.js
it('should detect if an element is enabled', function () {
var isEnabled = browser.isEnabled('.input1');
console.log(isEnabled); // outputs: true
var isEnabled2 = browser.isEnabled('.input2');
console.log(isEnabled2); // outputs: false
var isEnabled3 = browser.isEnabled('.input3')
console.log(isEnabled3); // outputs: false
});
* </example>
*
* @alias browser.isEnabled
* @param {String} selector DOM-element
* @return {Boolean|Boolean[]} true if element(s)* (is|are) enabled
* @uses protocol/elements, protocol/elementIdEnabled
* @type state
*
*/
exports.default = isEnabled;
module.exports = exports['default'];

View File

@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Returns true if at least one element is existing by given selector
*
* <example>
:index.html
<div id="notDisplayed" style="display: none"></div>
<div id="notVisible" style="visibility: hidden"></div>
<div id="notInViewport" style="position:absolute; left: 9999999"></div>
<div id="zeroOpacity" style="opacity: 0"></div>
:isExisting.js
it('should detect if elements are existing', function () {
var isExisting;
isExisting = browser.isExisting('#someRandomNonExistingElement');
console.log(isExisting); // outputs: false
isExisting = browser.isExisting('#notDisplayed');
console.log(isExisting); // outputs: true
isExisting = browser.isExisting('#notVisible');
console.log(isExisting); // outputs: true
isExisting = browser.isExisting('#notInViewport');
console.log(isExisting); // outputs: true
isExisting = browser.isExisting('#zeroOpacity');
console.log(isExisting); // outputs: true
});
* </example>
*
* @alias browser.isExisting
* @param {String} selector DOM-element
* @return {Boolean|Boolean[]} true if element(s)* [is|are] existing
* @uses protocol/elements
* @type state
*
*/
var isExisting = function isExisting(selector) {
return this.elements(selector).then(function (res) {
if (Array.isArray(res.value) && res.value.length > 0) {
return true;
}
return false;
});
};
exports.default = isExisting;
module.exports = exports["default"];

View File

@ -0,0 +1,88 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var isSelected = function isSelected(selector) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdSelectedCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdSelectedCommands.push(_this.elementIdSelected(elem.ELEMENT));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdSelectedCommands, {
extractValue: true
});
});
}; /**
*
* Return true or false if an `<option>` element, or an `<input>` element of type
* checkbox or radio is currently selected found by given selector.
*
* <example>
:index.html
<select name="selectbox" id="selectbox">
<option value="John Doe">John Doe</option>
<option value="Layla Terry" selected="selected">Layla Terry</option>
<option value="Bill Gilbert">Bill Gilbert"</option>
</select>
:isSelected.js
it('should detect if an element is selected', function () {
var element = $('[value="Layla Terry"]');
console.log(element.isSelected()); // outputs: true
browser.selectByValue('#selectbox', 'Bill Gilbert');
console.log(element.isSelected()); // outputs: false
});
* </example>
*
* @alias browser.isSelected
* @param {String} selector option element or input of type checkbox or radio
* @return {Boolean|Boolean[]} true if element is selected
* @uses protocol/elements, protocol/elementIdSelected
* @type state
*
*/
exports.default = isSelected;
module.exports = exports['default'];

View File

@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require("babel-runtime/core-js/get-iterator");
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Return true if the selected DOM-element found by given selector is visible. Returns an array if multiple DOM-elements are found for the given selector.
*
* <example>
:index.html
<div id="notDisplayed" style="display: none"></div>
<div id="notVisible" style="visibility: hidden"></div>
<div id="notInViewport" style="position:absolute; left: 9999999"></div>
<div id="zeroOpacity" style="opacity: 0"></div>
:isVisible.js
it('should detect if an element is visible', function () {
var isVisible = browser.isVisible('#notDisplayed');
console.log(isVisible); // outputs: false
isVisible = browser.isVisible('#notVisible');
console.log(isVisible); // outputs: false
isVisible = browser.isVisible('#notExisting');
console.log(isVisible); // outputs: false
isVisible = browser.isVisible('#notInViewport');
console.log(isVisible); // outputs: true
isVisible = browser.isVisible('#zeroOpacity');
console.log(isVisible); // outputs: true
});
* </example>
*
* @alias browser.isVisible
* @param {String} selector DOM-element
* @return {Boolean|Boolean[]} true if element(s)* [is|are] visible
* @uses protocol/elements, protocol/elementIdDisplayed
* @type state
*
*/
var isVisible = function isVisible(selector) {
var _this = this;
return this.elements(selector).then(function (res) {
/**
* if element does not exist it is automatically not visible ;-)
*/
if (!res.value || res.value.length === 0) {
return false;
}
var elementIdDisplayedCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdDisplayedCommands.push(_this.elementIdDisplayed(elem.ELEMENT));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdDisplayedCommands, {
extractValue: true
});
});
};
exports.default = isVisible;
module.exports = exports["default"];

View File

@ -0,0 +1,63 @@
'use strict';
var _isWithinViewport = require('../scripts/isWithinViewport');
var _isWithinViewport2 = _interopRequireDefault(_isWithinViewport);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
module.exports = function isVisibleWithinViewport(selector) {
return this.selectorExecute(selector, _isWithinViewport2.default).then(function (res) {
if (Array.isArray(res) && res.length === 1) {
return res[0];
}
return res;
}, function (err) {
/**
* if element does not exist it is automatically not visible :-)
*/
if (err.message.indexOf('NoSuchElement') > -1) {
return true;
}
throw err;
});
}; /**
*
* Return true if the selected DOM-element found by given selector is visible and within the viewport.
*
* <example>
:index.html
<div id="notDisplayed" style="display: none"></div>
<div id="notVisible" style="visibility: hidden"></div>
<div id="notInViewport" style="position:absolute; left: 9999999"></div>
<div id="zeroOpacity" style="opacity: 0"></div>
:isVisibleWithinViewport.js
:isVisible.js
it('should detect if an element is visible', function () {
var isVisibleWithinViewport = browser.isVisibleWithinViewport('#notDisplayed');
console.log(isVisibleWithinViewport); // outputs: false
isVisibleWithinViewport = browser.isVisibleWithinViewport('#notVisible');
console.log(isVisibleWithinViewport); // outputs: false
isVisibleWithinViewport = browser.isVisibleWithinViewport('#notExisting');
console.log(isVisibleWithinViewport); // outputs: false
isVisibleWithinViewport = browser.isVisibleWithinViewport('#notInViewport');
console.log(isVisibleWithinViewport); // outputs: false
isVisibleWithinViewport = browser.isVisibleWithinViewport('#zeroOpacity');
console.log(isVisibleWithinViewport); // outputs: false
});
* </example>
*
* @alias browser.isVisibleWithinViewport
* @param {String} selector DOM-element
* @return {Boolean|Boolean[]} true if element(s)* [is|are] visible
* @uses protocol/selectorExecute, protocol/timeoutsAsyncScript
* @type state
*
*/

View File

@ -0,0 +1,30 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _handleMouseButtonCommand = require('../helpers/handleMouseButtonCommand');
var _handleMouseButtonCommand2 = _interopRequireDefault(_handleMouseButtonCommand);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var leftClick = function leftClick(selector, xoffset, yoffset) {
return _handleMouseButtonCommand2.default.call(this, selector, 'left', xoffset, yoffset);
}; /**
*
* Apply left click on an element. If selector is not provided, click on the last
* moved-to location.
*
* @alias browser.leftClick
* @param {String} selector element to click on
* @param {Number} xoffset X offset to move to, relative to the top-left corner of the element.
* @param {Number} yoffset Y offset to move to, relative to the top-left corner of the element.
* @uses protocol/element, protocol/buttonPress
* @type action
*
*/
exports.default = leftClick;
module.exports = exports['default'];

View File

@ -0,0 +1,30 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _handleMouseButtonCommand = require('../helpers/handleMouseButtonCommand');
var _handleMouseButtonCommand2 = _interopRequireDefault(_handleMouseButtonCommand);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var middleClick = function middleClick(selector, xoffset, yoffset) {
return _handleMouseButtonCommand2.default.call(this, selector, 'middle', xoffset, yoffset);
}; /**
*
* Apply middle click on an element. If selector is not provided, click on the last
* moved-to location.
*
* @alias browser.middleClick
* @param {String} selector element to click on
* @param {Number} xoffset X offset to move to, relative to the top-left corner of the element.
* @param {Number} yoffset Y offset to move to, relative to the top-left corner of the element.
* @uses protocol/element, protocol/buttonPress
* @type action
*
*/
exports.default = middleClick;
module.exports = exports['default'];

View File

@ -0,0 +1,73 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var moveToObject = function moveToObject(selector, xoffset, yoffset) {
var _this = this;
/**
* check for offset params
*/
var hasOffsetParams = true;
if (typeof xoffset !== 'number' && typeof yoffset !== 'number') {
hasOffsetParams = false;
}
if (this.isMobile) {
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.elementIdSize(res.value.ELEMENT).then(function (size) {
return _this.elementIdLocation(res.value.ELEMENT).then(function (location) {
return { size: size, location: location };
});
});
}).then(function (res) {
var x = res.location.value.x + res.size.value.width / 2;
var y = res.location.value.y + res.size.value.height / 2;
if (hasOffsetParams) {
x = res.location.value.x + xoffset;
y = res.location.value.y + yoffset;
}
return _this.touchMove(x, y);
});
}
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.moveTo(res.value.ELEMENT, xoffset, yoffset);
});
}; /**
*
* Move the mouse by an offset of the specificed element. If an element is provided but no
* offset, the mouse will be moved to the center of the element. If the element is not
* visible, it will be scrolled into view.
*
* @alias browser.moveToObject
* @param {String} selector element to move to
* @param {Number} xoffset X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
* @param {Number} yoffset Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
* @uses protocol/element, protocol/elementIdLocation
* @type action
*
*/
exports.default = moveToObject;
module.exports = exports['default'];

View File

@ -0,0 +1,71 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _newWindow = require('../scripts/newWindow');
var _newWindow2 = _interopRequireDefault(_newWindow);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Open new window in browser. This command is the equivalent function to `window.open()`. This command does not
* work in mobile environments.
*
* __Note:__ When calling this command you automatically switch to the new window.
*
* <example>
:newWindowSync.js
it('should open a new tab', function () {
browser.url('http://google.com')
console.log(browser.getTitle()); // outputs: "Google"
browser.newWindow('http://webdriver.io', 'WebdriverIO window', 'width=420,height=230,resizable,scrollbars=yes,status=1')
console.log(browser.getTitle()); // outputs: "WebdriverIO - WebDriver bindings for Node.js"
browser.close()
console.log(browser.getTitle()); // outputs: "Google"
});
* </example>
*
* @alias browser.newWindow
* @param {String} url website URL to open
* @param {String} windowName name of the new window
* @param {String} windowFeatures features of opened window (e.g. size, position, scrollbars, etc.)
* @uses protocol/execute, window/getTabIds, window/switchTab
* @type window
*
*/
var newWindow = function newWindow(url) {
var _this = this;
var windowName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
var windowFeatures = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
/*!
* parameter check
*/
if (typeof url !== 'string' || typeof windowName !== 'string' || typeof windowFeatures !== 'string') {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with newWindow command');
}
/*!
* mobile check
*/
if (this.isMobile) {
throw new _ErrorHandler.CommandError('newWindow command is not supported on mobile platforms');
}
return this.execute(_newWindow2.default, url, windowName, windowFeatures).getTabIds().then(function (tabs) {
return _this.switchTab(tabs[tabs.length - 1]);
});
};
exports.default = newWindow;
module.exports = exports['default'];

View File

@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require("babel-runtime/core-js/promise");
var _promise2 = _interopRequireDefault(_promise);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Pauses execution for a specific amount of time. It is recommended to not use this command to wait for an
* element to show up. In order to avoid flaky test results it is better to use commands like
* [`waitforExist`](/api/utility/waitForExist.html) or other waitFor* commands.
*
* <example>
:pause.js
it('should pause the execution', function () {
var starttime = new Date().getTime();
browser.pause(3000);
var endtime = new Date().getTime();
console.log(endtime - starttime); // outputs: 3000
});
* </example>
*
* @alias browser.pause
* @param {Number} milliseconds time in ms
* @type utility
*
*/
var pause = function pause() {
var milliseconds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1000;
return new _promise2.default(function (resolve) {
return setTimeout(resolve, milliseconds);
});
};
exports.default = pause;
module.exports = exports["default"];

View File

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Release touch sequence on specific element.
*
* @alias browser.release
* @param {String} selector element to release on
* @uses property/getLocation, protocol/touchUp
* @type mobile
*
*/
var release = function release(selector) {
var _this = this;
return this.getLocation(selector).then(function (res) {
return _this.touchUp(res.x, res.y);
});
};
exports.default = release;
module.exports = exports["default"];

View File

@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require("babel-runtime/core-js/promise");
var _promise2 = _interopRequireDefault(_promise);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Creates a new Selenium session with your current capabilities. This is useful if you
* test highly stateful application where you need to clean the browser session between
* the tests in your spec file to avoid creating hundreds of single test files with WDIO.
* Be careful though, this command affects your test time tremendously since spawning
* new Selenium sessions is very time consuming especially when using cloud services.
*
* <example>
:reloadSync.js
it('should reload my session', function () {
console.log(browser.sessionId); // outputs: e042b3f3cd5a479da4e171825e96e655
browser.reload();
console.log(browser.sessionId); // outputs: 9a0d9bf9d4864160aa982c50cf18a573
})
* </example>
*
* @alias browser.reload
* @type utility
*
*/
var reload = function reload() {
var _this = this;
var oldSessionId = this.requestHandler.sessionID;
return this.end().init().then(function (res) {
var newSessionId = _this.requestHandler.sessionID;
if (!Array.isArray(_this.options.onReload)) {
return _promise2.default.resolve();
}
return _promise2.default.all(_this.options.onReload.map(function (hook) {
return hook(oldSessionId, newSessionId);
}));
}).catch(function (e) {
console.log("Error in onReload hook: \"" + e.stack + "\"");
});
};
exports.default = reload;
module.exports = exports["default"];

View File

@ -0,0 +1,30 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _handleMouseButtonCommand = require('../helpers/handleMouseButtonCommand');
var _handleMouseButtonCommand2 = _interopRequireDefault(_handleMouseButtonCommand);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var rightClick = function rightClick(selector, xoffset, yoffset) {
return _handleMouseButtonCommand2.default.call(this, selector, 'right', xoffset, yoffset);
}; /**
*
* Apply right click on an element. If selector is not provided, click on the last
* moved-to location.
*
* @alias browser.rightClick
* @param {String} selector element to click on
* @param {Number} xoffset X offset to move to, relative to the top-left corner of the element.
* @param {Number} yoffset Y offset to move to, relative to the top-left corner of the element.
* @uses protocol/element, protocol/buttonPress
* @type action
*
*/
exports.default = rightClick;
module.exports = exports['default'];

View File

@ -0,0 +1,64 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = saveScreenshot;
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _safeBuffer = require('safe-buffer');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Save a screenshot as a base64 encoded PNG with the current state of the browser. Be aware that some Selenium driver
* are taking screenshots of the whole document (e.g. phantomjs) and others only of the current viewport. If you want
* to always be sure that the screenshot has the size of the whole document, use [wdio-screenshot](https://www.npmjs.com/package/wdio-screenshot)
* to enhance this command with that functionality.
*
* This command also doesn't support the [element screenshot](https://w3c.github.io/webdriver/webdriver-spec.html#take-element-screenshot)
* feature yet as it isn't supported by most of the drivers. However the protocol command for it is available
* to use (see [elementIdScreenshot](http://webdriver.io/api/protocol/elementIdScreenshot.html)).
*
* <example>
:saveScreenshot.js
it('should save a screenshot of the browser view', function () {
// receive screenshot as Buffer
var screenshot = browser.saveScreenshot(); // returns base64 string buffer
fs.writeFileSync('./myShort.png', screenshot)
// save screenshot to file and receive as Buffer
screenshot = browser.saveScreenshot('./snapshot.png');
// save screenshot to file
browser.saveScreenshot('./snapshot.png');
});
* </example>
*
* @alias browser.saveScreenshot
* @param {Function|String=} filename path to the generated image (relative to the execution directory)
* @uses protocol/screenshot
* @type utility
*
*/
function saveScreenshot(filename) {
var _this = this;
return this.screenshot().then(function (res) {
_this.emit('screenshot', { data: res.value, filename: filename });
var screenshot = new _safeBuffer.Buffer(res.value, 'base64');
if (typeof filename === 'string') {
_fs2.default.writeFileSync(filename, screenshot);
}
return screenshot;
});
}
module.exports = exports['default'];

View File

@ -0,0 +1,108 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _ErrorHandler = require('../utils/ErrorHandler');
var _scroll = require('../scripts/scroll');
var _scroll2 = _interopRequireDefault(_scroll);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Scroll to a specific element. You can also append/pass two offset values as parameter
* to scroll to a specific position.
*
* <example>
:scroll.js
it('should demonstrate the scroll command', function () {
var elem = $('#myElement');
// scroll to specific element
elem.scroll();
// scroll to specific element with offset
// scroll offset will be added to elements position
elem.scroll(100, 100);
// scroll to specific x and y position
browser.scroll(0, 250);
});
* </example>
*
* @alias browser.scroll
* @param {String=} selector element to scroll to
* @param {Number=} xoffset x offset to scroll to
* @param {Number=} yoffset y offset to scroll to
* @uses protocol/element, protocol/elementIdLocation, protocol/touchScroll, protocol/execute
* @type utility
*
*/
var scroll = function scroll(selector, xoffset, yoffset) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if an offset is used
*/
xoffset = typeof xoffset === 'number' ? xoffset : 0;
yoffset = typeof yoffset === 'number' ? yoffset : 0;
if (typeof selector === 'number' && typeof xoffset === 'number') {
yoffset = xoffset;
xoffset = selector;
selector = null;
}
if (this.isMobile) {
var queue = _promise2.default.resolve();
if (selector) {
queue = this.element(selector);
}
return queue.then(function (res) {
/**
* check if element was found and throw error if not
*/
if (res && !res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
if (typeof res !== 'undefined') {
selector = res.value.ELEMENT;
}
return _this.touchScroll(selector, xoffset, yoffset);
});
}
if (selector) {
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.elementIdLocation(res.value.ELEMENT);
}).then(function (location) {
return _this.execute(_scroll2.default, location.value.x + xoffset, location.value.y + yoffset);
});
}
return this.execute(_scroll2.default, xoffset, yoffset);
};
exports.default = scroll;
module.exports = exports['default'];

View File

@ -0,0 +1,88 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var selectByAttribute = function selectByAttribute(selector, attribute, value) {
var _this = this;
/**
* convert value into string
*/
if (typeof value === 'number') {
value = value.toString();
}
/**
* get options element by xpath
*/
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
/**
* find option elem using xpath
*/
var normalized = '[normalize-space(@' + attribute.trim() + ') = "' + value.trim() + '"]';
return _this.elementIdElement(res.value.ELEMENT, './option' + normalized + '|./optgroup/option' + normalized);
}).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
/**
* select option
*/
return _this.elementIdClick(res.value.ELEMENT);
});
}; /**
*
* Select option with a specific value.
*
* <example>
:example.html
<select id="selectbox">
<option value="someValue0">uno</option>
<option value="someValue1">dos</option>
<option value="someValue2">tres</option>
<option value="someValue3">cuatro</option>
<option value="someValue4">cinco</option>
<option name="someName5" value="someValue5">seis</option>
</select>
:selectByAttribute.js
it('should demonstrate the selectByAttribute command', function () {
var selectBox = $('#selectbox');
var value = selectBox.getValue();
console.log(value); // returns "someValue0"
selectBox.selectByAttribute('value', 'someValue3');
console.log(selectBox.getValue()); // returns "someValue3"
selectBox.selectByAttribute('name', 'someName5');
console.log(selectBox.getValue()); // returns "someValue5"
});
* </example>
*
* @alias browser.selectByAttribute
* @param {String} selector select element that contains the options
* @param {String} attribute attribute of option element to get selected
* @param {String} value value of option element to get selected
* @uses protocol/element, protocol/elementIdClick, protocol/elementIdElement
* @type action
*
*/
exports.default = selectByAttribute;
module.exports = exports['default'];

View File

@ -0,0 +1,72 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var selectByIndex = function selectByIndex(selector, index) {
var _this = this;
/*!
* negative index check
*/
if (index < 0) {
throw new _ErrorHandler.CommandError('index needs to be 0 or any other positive number');
}
return this.element(selector).then(function (element) {
/**
* check if element was found and throw error if not
*/
if (!element.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.elementIdElements(element.value.ELEMENT, '<option>');
}).then(function (elements) {
if (elements.value.length === 0) {
throw new _ErrorHandler.CommandError('select element (' + selector + ') doesn\'t contain any option element');
}
if (elements.value.length - 1 < index) {
throw new _ErrorHandler.CommandError('option with index "' + index + '" not found. Select element (' + selector + ') only contains ' + elements.value.length + ' option elements');
}
return _this.elementIdClick(elements.value[index].ELEMENT);
});
}; /**
*
* Select option with a specific index.
*
* <example>
:example.html
<select id="selectbox">
<option value="someValue0">uno</option>
<option value="someValue1">dos</option>
<option value="someValue2">tres</option>
<option value="someValue3">cuatro</option>
<option value="someValue4">cinco</option>
<option value="someValue5">seis</option>
</select>
:selectByIndex.js
it('should demonstrate the selectByIndex command', function () {
var selectBox = $('#selectbox');
console.log(selectBox.getValue()); // returns "someValue0"
selectBox.selectByIndex(4);
console.log(selectBox.getValue()); // returns "someValue4"
});
* </example>
*
* @alias browser.selectByIndex
* @param {String} selector select element that contains the options
* @param {Number} index option index
* @uses protocol/element, protocol/elementIdElements, protocol/elementIdClick
* @type action
*
*/
exports.default = selectByIndex;
module.exports = exports['default'];

View File

@ -0,0 +1,44 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Select option with a specific value.
*
* <example>
:example.html
<select id="selectbox">
<option value="someValue0">uno</option>
<option value="someValue1">dos</option>
<option value="someValue2">tres</option>
<option value="someValue3">cuatro</option>
<option value="someValue4">cinco</option>
<option value="someValue5">seis</option>
</select>
:selectByValue.js
it('should demonstrate the selectByValue command', function () {
var selectBox = $('#selectbox');
console.log(selectBox.getValue()); // returns "someValue0"
selectBox.selectByValue('someValue3');
console.log(selectBox.getValue()); // returns "someValue3"
});
* </example>
*
* @alias browser.selectByValue
* @param {String} selector select element that contains the options
* @param {String} value value of option element to get selected
* @uses protocol/element, protocol/elementIdClick, protocol/elementIdElement
* @type action
*
*/
var selectByValue = function selectByValue(selector, value) {
return this.selectByAttribute(selector, 'value', value);
};
exports.default = selectByValue;
module.exports = exports['default'];

View File

@ -0,0 +1,81 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var selectByVisibleText = function selectByVisibleText(selector, text) {
var _this = this;
/**
* get select element
*/
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
/**
* find option elem using xpath
*/
var formatted = '"' + text.trim() + '"';
if (/"/.test(text)) {
formatted = 'concat("' + text.trim().split('"').join('", \'"\', "') + '")'; // escape quotes
}
var normalized = '[normalize-space(.) = ' + formatted + ']';
return _this.elementIdElement(res.value.ELEMENT, './option' + normalized + '|./optgroup/option' + normalized);
}).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
/**
* select option
*/
return _this.elementIdClick(res.value.ELEMENT);
});
}; /**
*
* Select option which's displayed text matches the argument.
*
* <example>
:example.html
<select id="selectbox">
<option value="someValue0">uno</option>
<option value="someValue1">dos</option>
<option value="someValue2">tres</option>
<option value="someValue3">cuatro</option>
<option value="someValue4">cinco</option>
<option value="someValue5">seis</option>
</select>
:selectByVisibleText.js
it('demonstrate the selectByVisibleText command', function () {
var selectBox = $('#selectbox');
console.log(selectBox.getText('option:checked')); // returns "uno"
selectBox.selectByVisibleText('cuatro');
console.log(selectBox.getText('option:checked')); // returns "cuatro"
})
* </example>
*
* @alias browser.selectByVisibleText
* @param {String} selector select element that contains the options
* @param {String} text text of option element to get selected
* @uses protocol/element, protocol/elementIdClick, protocol/elementIdElement
* @type action
*
*/
exports.default = selectByVisibleText;
module.exports = exports['default'];

View File

@ -0,0 +1,109 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ensureClientSideSelectorSupport = require('../helpers/ensureClientSideSelectorSupport');
var _ensureClientSideSelectorSupport2 = _interopRequireDefault(_ensureClientSideSelectorSupport);
var _createSelectorScript = require('../scripts/createSelectorScript');
var _createSelectorScript2 = _interopRequireDefault(_createSelectorScript);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var selectorExecute = function selectorExecute(selector, script) {
var _this = this;
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
/**
* if selectorExecute gets executed with element as first citizen like
*
* ```js
* var elem = $('#elem');
* elem.selectorExecute(function () {...}, some, args);
* ```
*/
if (typeof selector === 'function' && this.lastResult && typeof this.lastResult.selector === 'string') {
args.unshift(script);
script = selector;
selector = [this.lastResult.selector];
/**
* if selectorExecute gets executed by getHTML
*/
} else if (selector === null) {
selector = [this.lastResult.selector];
}
if (typeof selector === 'string') {
selector = [selector];
}
if (!Array.isArray(selector)) {
throw new _ErrorHandler.CommandError('Argument \'selector\' must be string or array of strings.');
}
if (!/string|function/.test(typeof script)) {
throw new _ErrorHandler.CommandError('Argument \'script\' must be a function or string.');
}
var fullScript = _createSelectorScript2.default.call(this, script, selector, args);
return _ensureClientSideSelectorSupport2.default.call(this).execute(fullScript).then(function (res) {
var result = res && res.value;
if (result && result.message === 'NoSuchElement') {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
return result;
});
}; /**
* Works just like execute, only you can use selectors to pass html elements to
* the function you wish to execute in the browser.
*
* The function fn will receive every resolved selector as an array of html elements,
* even if there is only one result, or no result.
* These arrays are the first arguments the function fn receives.
* If you pass an array of selectors, the resulting html element arrays are returned in the same order.
*
* All arguments you append after function fn are added as the arguments after the html arrays.
* You can use any JSON value or a function as such an argument.
*
* <example>
:selectorExecute.js
it('it inject JavaScript to the page', function () {
var divCount = browser.selectorExecute("//div", function(divs, message) {
return divs.length + message;
}, " divs on the page");
console.log(divCount); // returns, for example, "68 divs on the page"
var divLinkCount = browser.selectorExecute(["//div", "=Read Post"], function(divs, links) {
var message = 'There are ';
message += divs.length + ' divs on the page';
message += ' and ';
message += links.length + ' links with an link text "' + links[0].text + '"';
return message;
});
console.log(divLinkCount); // returns, for example, "There are 68 divs on the page and 42 links with an link text 'Read Post'"
});
* </example>
*
* @alias browser.selectorExecute
* @param {String|Array.<String>} selectors single selector or array of selectors
* @param {Function} script function to get executed in the browser
* @param {...*} [argument1,...,argumentN] arguments added to fn. Can be any JSON value or function
* @uses protocol/execute
* @type action
*/
exports.default = selectorExecute;
module.exports = exports['default'];

View File

@ -0,0 +1,108 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ensureClientSideSelectorSupport = require('../helpers/ensureClientSideSelectorSupport');
var _ensureClientSideSelectorSupport2 = _interopRequireDefault(_ensureClientSideSelectorSupport);
var _createSelectorScript = require('../scripts/createSelectorScript');
var _createSelectorScript2 = _interopRequireDefault(_createSelectorScript);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var selectorExecuteAsync = function selectorExecuteAsync(selector, script) {
var _this = this;
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
/**
* if selectorExecuteAsync gets executed with element as first citizen like
*
* ```js
* var elem = $('#elem');
* elem.selectorExecuteAsync(function () {...}, some, args);
* ```
*/
if (typeof selector === 'function' && this.lastResult && typeof this.lastResult.selector === 'string') {
args.unshift(script);
script = selector;
selector = [this.lastResult.selector];
/**
* if selectorExecuteAsync gets executed by getHTML
*/
} else if (selector === null) {
selector = [this.lastResult.selector];
}
if (typeof selector === 'string') {
selector = [selector];
}
if (!Array.isArray(selector)) {
throw new _ErrorHandler.CommandError('Argument \'selector\' must be string or array of strings.');
}
if (!/string|function/.test(typeof script)) {
throw new _ErrorHandler.CommandError('Argument \'script\' must be a function or string.');
}
var fullScript = _createSelectorScript2.default.call(this, script, selector, args);
return _ensureClientSideSelectorSupport2.default.call(this).executeAsync(fullScript).then(function (res) {
var result = res && res.value;
if (result && result.message === 'NoSuchElement') {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
return result;
});
}; /**
* Works just like execute, only you can use Selenium selector strategies to pass html elements to
* the asynchronous function you wish to execute in the browser.
*
* The asynchronous function fn will receive every resolved selector as an array of html elements,
* even if there is only one result, or no result.
* These arrays are the first arguments the function fn receives.
* If you pass an array of selectors, the resulting html element arrays are returned in the same order.
*
* All arguments you append after function fn are added as the arguments after the html arrays.
* You can use any JSON value or a function as such an argument.
*
* <example>
:selectorExecuteAsync.js
it('should be able to inject JavaScript into the page that can be execute asynchronously', function () {
var divCount = browser.selectorExecuteAsync("//div", function(divs, message, callback) {
callback(divs.length + message);
}, " divs on the page")
console.log(divCount); // returns, for example, "68 divs on the page"
var divLinkCount = browser.selectorExecuteAsync(["//div", "=Read Post"], function(divs, links, callback) {
var message = 'There are ';
message += divs.length + ' divs on the page';
message += ' and ';
message += links.length + ' links with an link text "' + links[0].text + '"';
callback(message);
})
console.log(divLinkCount); // returns, for example, "There are 68 divs on the page and 42 links with an link text 'Read Post'"
});
* </example>
*
* @alias browser.selectorExecuteAsync
* @param {String|Array.<String>} selectors single selector or array of selectors
* @param {Function} script asynchronous function to get executed in the browser
* @param {...*} [argument1,...,argumentN] arguments added to fn. Can be any JSON value or function
* @uses protocol/execute
* @type action
*/
exports.default = selectorExecuteAsync;
module.exports = exports['default'];

View File

@ -0,0 +1,43 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var setCookie = function setCookie(cookieObj) {
/*!
* parameter check
*/
if (typeof cookieObj !== 'object') {
throw new _ErrorHandler.CommandError('Please specify a cookie object to set (see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#cookie-json-object for documentation.');
}
return this.cookie('POST', cookieObj);
}; /**
*
* Sets a [cookie](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#cookie-json-object)
* for current page. Make sure you are on the page that should receive the cookie. You can't set
* a cookie for an arbitrary page without being on that page.
*
* <example>
:setCookie.js
it('should set a cookie for the page', function () {
browser.url('/')
browser.setCookie({name: 'test', value: '123'});
var cookies = browser.getCookie();
console.log(cookies); // outputs: [{ name: 'test', value: '123' }]
});
* </example>
*
* @alias browser.setCookie
* @param {Object} cookie cookie object
* @uses protocol/cookie
* @type cookie
*
*/
exports.default = setCookie;
module.exports = exports['default'];

View File

@ -0,0 +1,30 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var setGeoLocation = function setGeoLocation(location) {
/*!
* parameter check
*/
if (typeof location !== 'object' || location.latitude === undefined || location.longitude === undefined || location.altitude === undefined) {
throw new _ErrorHandler.CommandError('location object need to have a latitude, longitude and altitude attribute');
}
return this.location(location);
}; /**
*
* Set the current geo location.
*
* @alias browser.setGeoLocation
* @param {Object} location the new location (`{latitude: number, longitude: number, altitude: number}`)
* @uses protocol/location
* @type mobile
*
*/
exports.default = setGeoLocation;
module.exports = exports['default'];

View File

@ -0,0 +1,41 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var setOrientation = function setOrientation(orientation) {
/*!
* parameter check
*/
if (typeof orientation !== 'string') {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with setOrientation command');
}
return this.orientation(orientation.toUpperCase());
}; /**
*
* Set a device orientation.
*
* <example>
:setOrientation.js
it('should set a geo location for the device', function () {
browser.setOrientation('landscape');
var orientation = browser.getOrientation();
console.log(orientation); // outputs: "landscape"
});
* </example>
*
* @alias browser.setOrientation
* @param {String} orientation the new browser orientation (`landscape/portrait`)
* @uses protocol/orientation
* @type mobile
* @for android, ios
*
*/
exports.default = setOrientation;
module.exports = exports['default'];

View File

@ -0,0 +1,95 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var setValue = function setValue(selector, value) {
var _this = this;
/*!
* parameter check
*/
if (typeof value === 'number') {
value = value.toString();
}
if (typeof value !== 'string' && !Array.isArray(value)) {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with setValue command');
}
return this.elements(selector).then(function (res) {
/**
* throw NoSuchElement error if no element was found
*/
if (!res.value || res.value.length === 0) {
throw new _ErrorHandler.CommandError(7, selector || _this.lastResult.selector);
}
var elementIdValueCommands = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(res.value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var elem = _step.value;
elementIdValueCommands.push(_this.elementIdClear(elem.ELEMENT).elementIdValue(elem.ELEMENT, value));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return _this.unify(elementIdValueCommands);
});
}; /**
*
* Send a sequence of key strokes to an element (clears value before). You can also use
* unicode characters like Left arrow or Back space. WebdriverIO will take care of
* translating them into unicode characters. Youll find all supported characters
* [here](https://w3c.github.io/webdriver/webdriver-spec.html#dfn-character-types).
* To do that, the value has to correspond to a key from the table.
*
* <example>
:setValue.js
it('should set value for a certain element', function () {
var input = $('.input');
input.setValue('test123');
// same as
browser.setValue('.input', 'test123');
console.log(input.getValue()); // outputs: 'test123'
});
* </example>
*
* @alias browser.setValue
* @param {String} selector Input element
* @param {String|Number|Array} values Input element
* @uses protocol/elements, protocol/elementIdClear, protocol/elementIdValue
* @type action
*
*/
exports.default = setValue;
module.exports = exports['default'];

View File

@ -0,0 +1,99 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getViewportSize = require('../scripts/getViewportSize');
var _getViewportSize2 = _interopRequireDefault(_getViewportSize);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* This command changes the viewport size of the browser. When talking about browser size we have to differentiate
* between the actual window size of the browser application and the document/viewport size of the website. The
* window size will always be bigger since it includes the height of any menu or status bars.
*
* The command tries to resize the browser multiple times (max 5 times) because Webdriver only allows to change
* the window size and doesn't take the viewport into consideration. This is handled by WebdriverIO internally.
*
* <example>
:setViewportSize.js
it('should resize the current viewport', function () {
browser.setViewportSize({
width: 500,
height: 500
});
var windowSize = browser.windowHandleSize();
console.log(windowSize.value); // outputs: { width: 500, height: 602 }
});
* </example>
*
* @alias browser.setViewportSize
* @param {Object} size window width/height
* @param {Boolean} type set to `false` to change window size, `true` (default) to change viewport size
* @uses protocol/execute, protocol/windowHandleSize
* @type window
*
*/
var MAX_TRIES = 5;
var setViewportSize = function setViewportSize(size, type) {
/**
* parameter check
*/
if (typeof size !== 'object' || typeof size.width !== 'number' || typeof size.height !== 'number' || typeof type !== 'undefined' && typeof type !== 'boolean') {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with setViewportSize command');
}
var shouldIndent = typeof type === 'undefined' ? true : type;
return shouldIndent ? _setViewportSize.call(this, size) : this.windowHandleSize(size);
};
/**
* to set viewport size properly we need to execute the process multiple times
* since the difference between the inner and outer size changes when browser
* switch between fullscreen modes or visibility of scrollbar
*/
var _setViewportSize = function _setViewportSize(size) {
var _this = this;
var retryNo = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
/**
* get window size
*/
return this.windowHandleSize().then(function (windowHandleSize) {
/**
* get viewport size
*/
return _this.execute(_getViewportSize2.default).then(function (viewportSize) {
var widthDiff = windowHandleSize.value.width - viewportSize.value.screenWidth;
var heightDiff = windowHandleSize.value.height - viewportSize.value.screenHeight;
/**
* change window size with indent
*/
return _this.windowHandleSize({
width: size.width + widthDiff,
height: size.height + heightDiff
});
}).execute(_getViewportSize2.default).then(function (res) {
/**
* if viewport size not equals desired size, execute process again
*/
if (retryNo < MAX_TRIES && (res.value.screenWidth !== size.width || res.value.screenHeight !== size.height)) {
return _setViewportSize.call(_this, size, ++retryNo);
}
});
});
};
exports.default = setViewportSize;
module.exports = exports['default'];

View File

@ -0,0 +1,53 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var submitForm = function submitForm(selector) {
var _this = this;
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.submit(res.value.ELEMENT);
});
}; /**
*
* Submits a form found by given selector. The submit command may also be applied
* to any element that is a descendant of a `<form>` element.
*
* <example>
:index.html
<form action="/form.php" method="post" id="loginForm">
<label for="username">User:</label>
<input type="text" name="username" id="username">
<label for="password">Password:</label>
<input type="password" name="password" id="password">
<input type="submit" value="Login">
</form>
:submitForm.js
it('should submit login form', function () {
browser.setValue('#username', 'foobar');
browser.setValue('#password', 'test123');
browser.submitForm('#loginForm');
});
* </example>
*
* @alias browser.submitForm
* @param {String} selector form element
* @uses protocol/element, protocol/submit
* @type action
*
*/
exports.default = submitForm;
module.exports = exports['default'];

View File

@ -0,0 +1,54 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ErrorHandler = require('../utils/ErrorHandler');
var swipe = function swipe(selector, xoffset, yoffset, speed) {
var _this = this;
if (arguments.length === 2 && typeof selector === 'number' && typeof xoffset === 'number') {
/*!
* you don't care where the swipe starts on the screen
*/
var xspeed = selector;
var yspeed = xoffset;
return this.touchFlick(xspeed, yspeed);
}
/*!
* command starts at a particular screen location
*/
return this.element(selector).then(function (res) {
/**
* check if element was found and throw error if not
*/
if (!res.value) {
throw new _ErrorHandler.RuntimeError(7);
}
return _this.touchFlick(res.value.ELEMENT.toString(), xoffset, yoffset, speed);
});
}; /**
*
* Perform a swipe on the screen or an element. If you want to swipe on a specific
* element make sure you provide a selector argument. If not just pass `xoffset`
* and `yoffset` as command arguments.
*
* Start at a particular screen location.
*
* @alias browser.swipe
* @param {String=} selector element to swipe on
* @param {Number=} xoffset x offset of swipe gesture (in pixels or relative units)
* @param {Number=} yoffset y offset of swipe gesture (in pixels or relative units)
* @param {Number=} speed time (in seconds) to spend performing the swipe
* @uses protocol/element, protocol/touchFlick
* @type mobile
*
*/
exports.default = swipe;
module.exports = exports['default'];

View File

@ -0,0 +1,36 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Perform a swipe down on an element.
*
* @alias browser.swipeDown
* @param {String} selector element to swipe on
* @param {Number=} yoffset y offset of swipe gesture (in pixels or relative units)
* @param {Number} speed number of pixels go per second
* @uses mobile/swipe
* @type mobile
*
*/
var swipeDown = function swipeDown(selector, yOffset, speed) {
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used
*/
yOffset = typeof yOffset === 'number' ? yOffset : 100;
speed = typeof speed === 'number' ? speed : 100;
/**
* make sure yoffset is positive so we scroll up
*/
yOffset = yOffset < 0 ? yOffset * -1 : yOffset;
return this.pause(100).swipe(selector, 0, yOffset, speed);
};
exports.default = swipeDown;
module.exports = exports['default'];

View File

@ -0,0 +1,36 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Perform a swipe left on an element.
*
* @alias browser.swipeLeft
* @param {String} selector element to swipe on
* @param {Number=} xoffset x offset of swipe gesture (in pixels or relative units)
* @param {Number} speed time (in seconds) to spend performing the swipe
* @uses mobile/flick
* @type mobile
*
*/
var swipeLeft = function swipeLeft(selector, xOffset, speed) {
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used
*/
xOffset = typeof xOffset === 'number' ? xOffset : 100;
speed = typeof speed === 'number' ? speed : 100;
/**
* make sure xoffset is positive so we scroll right
*/
xOffset = xOffset > 0 ? xOffset * -1 : xOffset;
return this.pause(100).swipe(selector, xOffset, 0, speed);
};
exports.default = swipeLeft;
module.exports = exports['default'];

View File

@ -0,0 +1,36 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Perform a swipe right on an element.
*
* @alias browser.swipeRight
* @param {String} selector element to swipe on
* @param {Number=} xoffset x offset of swipe gesture (in pixels or relative units)
* @param {Number} speed time (in seconds) to spend performing the swipe
* @uses mobile/swipe
* @type mobile
*
*/
var swipeRight = function swipeRight(selector, xOffset, speed) {
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used
*/
xOffset = typeof xOffset === 'number' ? xOffset : -100;
speed = typeof speed === 'number' ? speed : 100;
/**
* make sure xoffset is negative so we scroll left
*/
xOffset = xOffset < 0 ? xOffset * -1 : xOffset;
return this.pause(100).swipe(selector, xOffset, 0, speed);
};
exports.default = swipeRight;
module.exports = exports['default'];

View File

@ -0,0 +1,36 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Perform a swipe up on an element.
*
* @alias browser.swipeUp
* @param {String} selector element to swipe on
* @param {Number=} yoffset y offset of swipe gesture (in pixels or relative units)
* @param {Number} speed time (in seconds) to spend performing the swipe
* @uses mobile/swipe
* @type mobile
*
*/
var swipeUp = function swipeUp(selector, yOffset, speed) {
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used
*/
yOffset = typeof yOffset === 'number' ? yOffset : -100;
speed = typeof speed === 'number' ? speed : 100;
/**
* make sure yoffset is negative so we scroll down
*/
yOffset = yOffset > 0 ? yOffset * -1 : yOffset;
return this.pause(100).swipe(selector, 0, yOffset, speed);
};
exports.default = swipeUp;
module.exports = exports['default'];

View File

@ -0,0 +1,39 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
*
* Switch focus to a particular tab / window handle.
*
* @alias browser.switchTab
* @param {String=} windowHandle window handle URL to focus on (if no handle was specified the command switches to the first available one)
* @uses protocol/window, window/getTabIds, window/switchTab
* @type window
*
*/
var switchTab = function switchTab(windowHandle) {
var _this = this;
/*!
* parameter check
*/
if (typeof windowHandle !== 'string') {
windowHandle = null;
}
if (windowHandle) {
return this.window(windowHandle);
}
return this.windowHandles().then(function (tabIds) {
if (tabIds && tabIds.value && tabIds.value.length) {
return _this.switchTab(tabIds.value[0]);
}
});
};
exports.default = switchTab;
module.exports = exports['default'];

View File

@ -0,0 +1,35 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
* Put finger on an element (only in mobile context).
*
* @alias browser.touch
* @param {String} selector element to put finger on
* @param {Boolean} longClick if true touch click will be long (default: false)
* @uses property/getLocation, protocol/touchClick
* @type mobile
* @uses android
*
*/
var touch = function touch(selector, longClick) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used
*/
longClick = typeof longClick === 'boolean' ? longClick : false;
var touchCommand = longClick ? 'touchLongClick' : 'touchClick';
return this.getLocation(selector).then(function (val) {
return _this[touchCommand](val.x, val.y);
});
};
exports.default = touch;
module.exports = exports['default'];

View File

@ -0,0 +1,297 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
exports.default = touchAction;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* The Touch Action API provides the basis of all gestures that can be automated in Appium.
* It is currently only available to native apps and can not be used to interact with webapps.
* At its core is the ability to chain together _ad hoc_ individual actions, which will then be
* applied to an element in the application on the device. The basic actions that can be used are:
*
* - press (pass selector or (x,y) or both)
* - longPress (pass selector or (x,y) or both)
* - tap (pass selector or (x,y) or both)
* - moveTo (pass selector or (x,y) or both)
* - wait (pass ms (as milliseconds))
* - release (no arguments)
*
* If you use the touchAction command with a selector you don't need to pass the selector to each
* action. It will be propagated by the internally (if no x or y parameters are given).
*
* <example>
:touchAction.js
it('should do a touch gesture', function () {
var screen = $('//UITextbox');
// simple touch action on element
screen.touchAction('tap');
// same as
browser.touchAction('//UITextbox', 'tap')
// simple touch action using x y variables
browser.touchAction({
actions: 'tap', x: 300, y:200
})
// simple touch action using selector and x y variables
// tap location is 30px right and 20px down relative from the center of the element
browser.touchAction({
actions: 'tap', x: 30, y:20, selector: '//UIAApplication[1]/UIAElement[2]'
})
// multi action on an element (drag&drop)
screen.touchAction([
'press',
{ action: 'moveTo', x: 200, y: 0 },
'release'
])
// same as
browser.touchAction('//UITextbox', [
'press',
{ action: 'moveTo', x: 200, y: 0},
'release'
])
// drag&drop to element
screen.touchAction([
'press',
{ action: 'moveTo', selector: '//UIAApplication[1]/UIAElement[2]' },
'release'
]))
});
:multiTouchAction.js
it('should do a multitouch gesture', function () {
// drag&drop with two fingers 200px down
browser.touchAction([
[{action: 'press', x: 10, y: 10}, { action: 'moveTo', x: 0, y: 200 }, 'release'],
[{action: 'press', x: 100, y: 10}, { action: 'moveTo', x: 0, y: 200 }, 'release']]
])
})
* </example>
*
* @param {String} selector selector to execute the touchAction on
* @param {String} action action to execute
*
* @see https://saucelabs.com/blog/appium-sauce-labs-bootcamp-chapter-2-touch-actions
* @type mobile
* @for android, ios
* @uses mobile/performTouchAction, mobile/performMultiAction
*
*/
var TOUCH_ACTIONS = ['press', 'longPress', 'tap', 'moveTo', 'wait', 'release'];
var POS_ACTIONS = TOUCH_ACTIONS.slice(0, -2);
var ACCEPTED_OPTIONS = ['x', 'y', 'selector', 'element'];
function touchAction(selector, actions) {
var _this = this;
if (typeof selector !== 'string' || TOUCH_ACTIONS.indexOf(selector) > -1) {
actions = selector;
selector = this.lastResult;
}
if (!Array.isArray(actions)) {
actions = [actions];
}
/**
* check if multiAction
*/
if (Array.isArray(actions[0])) {
actions = formatArgs(selector, actions);
return _promise2.default.all(getSelectors.call(this, actions, true)).then(function (jsonElements) {
actions = replaceSelectorsById(actions, jsonElements);
return _this.performMultiAction({ actions: actions });
});
}
actions = formatArgs(selector, actions);
return _promise2.default.all(getSelectors.call(this, actions)).then(function (jsonElements) {
actions = replaceSelectorsById(actions, jsonElements);
return _this.performTouchAction({ actions: actions });
});
}
/**
* helper to determine if action has proper option arguments
* ('press', 'longPress', 'tap', 'moveTo' need at least some kind of position information)
* @param {String} action name of action
* @param {Object} options action options
* @return {Boolean} True if don't need any options or has a position option
*/
var hasValidActionOptions = function hasValidActionOptions(action, options) {
return POS_ACTIONS.indexOf(action) < 0 || POS_ACTIONS.indexOf(action) > -1 && (0, _keys2.default)(options).length > 0;
};
var formatArgs = function formatArgs(selector, actions) {
return actions.map(function (action) {
if (Array.isArray(action)) {
return formatArgs(selector, action);
}
var formattedAction = { action: action.action, options: {} };
/**
* propagate selector or element to options object
*/
if (selector &&
// selector is given as string `e.g. browser.touchAction(selector, 'tap')`
typeof selector === 'string' &&
// don't propagate for actions that don't require element options
POS_ACTIONS.indexOf(typeof action === 'string' ? action : formattedAction.action) > -1 &&
// don't propagate if user has x and y set
!(isFinite(action.x) && isFinite(action.y))) {
formattedAction.options.selector = selector;
} else if (selector &&
// selector is given by previous command
// e.g. $(selector).touchAction('tap')
selector.value &&
// don't propagate for actions that don't require element options
POS_ACTIONS.indexOf(typeof action === 'string' ? action : formattedAction.action) > -1 &&
// don't propagate if user has x and y set
!(isFinite(action.x) && isFinite(action.y))) {
formattedAction.options.element = selector.value.ELEMENT;
}
if (typeof action === 'string') {
if (!hasValidActionOptions(action, formattedAction.options)) {
throw new Error('Touch action "' + action + '" doesn\'t have proper options. Make sure certain actions like ' + (POS_ACTIONS.join(', ') + ' have position options like "selector", "x" or "y".'));
}
formattedAction.action = action;
/**
* remove options property if empyt
*/
if ((0, _keys2.default)(formattedAction.options).length === 0) {
delete formattedAction.options;
}
return formattedAction;
}
if (isFinite(action.x)) formattedAction.options.x = action.x;
if (isFinite(action.y)) formattedAction.options.y = action.y;
if (action.ms) formattedAction.options.ms = action.ms;
if (action.selector && POS_ACTIONS.indexOf(formattedAction.action) > -1) {
formattedAction.options.selector = action.selector;
}
if (action.element) {
formattedAction.options.element = action.element;
delete formattedAction.options.selector;
}
/**
* remove options property if empyt
*/
if ((0, _keys2.default)(formattedAction.options).length === 0) {
delete formattedAction.options;
}
/**
* option check
* make sure action has proper options before sending command to Appium
*/
if (formattedAction.action === 'release' && formattedAction.options) {
throw new Error('action "release" doesn\'t accept any options ' + ('("' + (0, _keys2.default)(formattedAction.options).join('", "') + '" found)'));
} else if (formattedAction.action === 'wait' && ((0, _keys2.default)(formattedAction.options).indexOf('x') > -1 || (0, _keys2.default)(formattedAction.options).indexOf('y') > -1)) {
throw new Error('action "wait" doesn\'t accept x, y options');
} else if (POS_ACTIONS.indexOf(formattedAction.action) > -1) {
for (var option in formattedAction.options) {
if (ACCEPTED_OPTIONS.indexOf(option) === -1) {
throw new Error('action "' + formattedAction.action + '" doesn\'t accept "' + option + '" as option');
}
}
if ((0, _keys2.default)(formattedAction.options || {}).length === 0) {
throw new Error('Touch actions like "' + formattedAction.action + '" need at least some kind of ' + 'position information like "selector", "x" or "y" options, you\'ve none given.');
}
}
return formattedAction;
});
};
var getSelectors = function getSelectors(actions) {
var _this2 = this;
var isMultiAction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var queriedSelectors = [];
/**
* flatten actions array
*/
if (isMultiAction) {
actions = [].concat.apply([], actions);
}
return actions
/**
* map down to list of selectors
*/
.map(function (action) {
return action.options && action.options.selector;
})
/**
* filter actions without selector and unique selectors
*/
.filter(function (selector) {
var res = Boolean(selector) && queriedSelectors.indexOf(selector) === -1;
queriedSelectors.push(selector);
return res;
})
/**
* call element command on selectors
*/
.map(function (selector) {
return _this2.element(selector);
});
};
/**
* replaces selector action properties with element ids after they got fetched
* @param {Object[]} actions list of actions
* @param {Object[]} elements list of fetched elements
* @return {Object[]} list of actions with proper element ids
*/
var replaceSelectorsById = function replaceSelectorsById(actions, elements) {
return actions.map(function (action) {
if (Array.isArray(action)) {
return replaceSelectorsById(action, elements);
}
if (!action.options || !action.options.selector) {
return action;
}
elements.forEach(function (element) {
if (action.options.selector === element.selector) {
action.options.element = element.value.ELEMENT;
delete action.options.selector;
}
});
return action;
});
};
module.exports = exports['default'];

View File

@ -0,0 +1,69 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _archiver = require('archiver');
var _archiver2 = _interopRequireDefault(_archiver);
var _ErrorHandler = require('../utils/ErrorHandler');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Uploads a file to the selenium server by using the [`file`](/api/protocol/file.html) command. Note that
* this command might not be supported as it is an undocumented Selenium command.
*
* @alias browser.uploadFile
* @param {String} localPath local path to file
* @type utility
* @uses protocol/file
*
*/
var uploadFile = function uploadFile(localPath) {
var _this = this;
/*!
* parameter check
*/
if (typeof localPath !== 'string') {
throw new _ErrorHandler.CommandError('number or type of arguments don\'t agree with uploadFile command');
}
var zipData = [];
var source = _fs2.default.createReadStream(localPath);
return new _promise2.default(function (resolve, reject) {
(0, _archiver2.default)('zip').on('error', function (e) {
throw new Error(e);
}).on('data', function (data) {
return zipData.push(data);
}).on('end', function () {
return _this.file(Buffer.concat(zipData).toString('base64')).then(resolve, reject);
}).append(source, { name: _path2.default.basename(localPath) }).finalize(function (err) {
/* istanbul ignore next */
if (err) {
reject(err);
}
});
});
};
exports.default = uploadFile;
module.exports = exports['default'];

View File

@ -0,0 +1,114 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Wait for an element (selected by css selector) for the provided amount of
* milliseconds to be (dis/en)abled. If multiple elements get queryied by given
* selector, it returns true (or false if reverse flag is set) if at least one
* element is (dis/en)abled.
*
* <example>
:index.html
<input type="text" id="username" value="foobar" disabled="disabled"></input>
<script type="text/javascript">
setTimeout(function () {
document.getElementById('username').disabled = false
}, 2000);
</script>
:waitForEnabledExample.js
it('should detect when element is enabled', function () {
browser.waitForEnabled('#username', 3000);
// same as
elem = $('#username');
elem.waitForEnabled(3000)
});
* </example>
*
* @alias browser.waitForEnabled
* @param {String} selector element to wait for
* @param {Number=} ms time in ms (default: 500)
* @param {Boolean=} reverse if true it waits for the opposite (default: false)
* @uses utility/waitUntil, state/isEnabled
* @type utility
*
*/
var waitForEnabled = function waitForEnabled(selector, ms, reverse) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used, like
*
* ```js
* var elem = $('#elem');
* elem.waitForXXX(10000, true);
* ```
*/
reverse = typeof reverse === 'boolean' ? reverse : false;
/*!
* ensure that ms is set properly
*/
if (typeof ms !== 'number') {
ms = this.options.waitforTimeout;
}
var isReversed = reverse ? '' : 'not';
var errorMsg = 'element ("' + (selector || this.lastResult.selector) + '") still ' + isReversed + ' enabled after ' + ms + 'ms';
return this.waitUntil(function () {
return _this.isEnabled(selector).then(function (isEnabled) {
if (!Array.isArray(isEnabled)) {
return isEnabled !== reverse;
}
var result = reverse;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(isEnabled), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var val = _step.value;
if (!reverse) {
result = result || val;
} else {
result = result && val;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result !== reverse;
});
}, ms, errorMsg);
};
exports.default = waitForEnabled;
module.exports = exports['default'];

View File

@ -0,0 +1,108 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Wait for an element (selected by css selector) for the provided amount of
* milliseconds to be present within the DOM. Returns true if the selector
* matches at least one element that exists in the DOM, otherwise throws an
* error. If the reverse flag is true, the command will instead return true
* if the selector does not match any elements.
*
* <example>
:waitForExistSyncExample.js
it('should display a notification message after successful form submit', function () {
var form = $('form');
var notification = $('.notification');
form.submit();
notification.waitForExist(5000); // same as `browser.waitForExist('.notification', 5000)`
expect(notification.getText()).to.be.equal('Data transmitted successfully!')
});
* </example>
*
* @alias browser.waitForExist
* @param {String} selector CSS selector to query
* @param {Number=} ms time in ms (default: 500)
* @param {Boolean=} reverse if true it instead waits for the selector to not match any elements (default: false)
* @uses utility/waitUntil, state/isExisting
* @type utility
*
*/
var waitForExist = function waitForExist(selector, ms, reverse) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used, like
*
* ```js
* var elem = $('#elem');
* elem.waitForXXX(10000, true);
* ```
*/
reverse = typeof reverse === 'boolean' ? reverse : false;
/*!
* ensure that ms is set properly
*/
if (typeof ms !== 'number') {
ms = this.options.waitforTimeout;
}
var isReversed = reverse ? '' : 'not';
var errorMsg = 'element ("' + (selector || this.lastResult.selector) + '") still ' + isReversed + ' existing after ' + ms + 'ms';
return this.waitUntil(function () {
return _this.isExisting(selector).then(function (isExisting) {
if (!Array.isArray(isExisting)) {
return isExisting !== reverse;
}
var result = reverse;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(isExisting), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var val = _step.value;
if (!reverse) {
result = result || val;
} else {
result = result && val;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result !== reverse;
});
}, ms, errorMsg);
};
exports.default = waitForExist;
module.exports = exports['default'];

View File

@ -0,0 +1,117 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Wait for an option or radio/checkbox element (selected by css selector) for the provided amount of
* milliseconds to be (un)selected or (un)checked. If multiple elements get queryied by given
* selector, it returns true (or false if reverse flag is set) if at least one element is (un)selected.
*
* <example>
:index.html
<select>
<option value="1" id="option1">1</option>
<option value="2" id="option2" selected="selected">2</option>
<option value="3" id="option3">3</option>
</select>
<script type="text/javascript">
setTimeout(function () {
document.getElementById('option1').selected = true;
}, 2000);
</script>
:waitForSelectedExample.js
it('should detect when an option is selected', function () {
browser.waitForSelected('#option1', 3000);
// same as
elem = $('#option1');
elem.waitForSelected(3000)
});
* </example>
*
* @alias browser.waitForSelected
* @param {String} selector element to wait for
* @param {Number=} ms time in ms (default: 500)
* @param {Boolean=} reverse if true it waits for the opposite (default: false)
* @uses utility/waitUntil, state/isSelected
* @type utility
*
*/
var waitForSelected = function waitForSelected(selector, ms, reverse) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used, like
*
* ```js
* var elem = $('#elem');
* elem.waitForXXX(10000, true);
* ```
*/
reverse = typeof reverse === 'boolean' ? reverse : false;
/*!
* ensure that ms is set properly
*/
if (typeof ms !== 'number') {
ms = this.options.waitforTimeout;
}
var isReversed = reverse ? '' : 'not';
var errorMsg = 'element ("' + (selector || this.lastResult.selector) + '") still ' + isReversed + ' selected after ' + ms + 'ms';
return this.waitUntil(function () {
return _this.isSelected(selector).then(function (isSelected) {
if (!Array.isArray(isSelected)) {
return isSelected !== reverse;
}
var result = reverse;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(isSelected), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var val = _step.value;
if (!reverse) {
result = result || val;
} else {
result = result && val;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result !== reverse;
});
}, ms, errorMsg);
};
exports.default = waitForSelected;
module.exports = exports['default'];

View File

@ -0,0 +1,114 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Wait for an element (selected by css selector) for the provided amount of
* milliseconds to have text/content. If multiple elements get queryied by given
* selector, it returns true (or false if reverse flag is set) if at least one
* element has text/content.
*
* <example>
:index.html
<div id="elem"></div>
<script type="text/javascript">
setTimeout(function () {
document.getElementById('elem').innerHTML = 'some text';
}, 2000);
</script>
:waitForTextExample.js
it('should detect when element has text', function () {
browser.waitForText('#elem', 3000);
// same as
elem = $('#elem');
elem.waitForText(3000)
});
* </example>
*
* @alias browser.waitForText
* @param {String} selector element to wait for
* @param {Number=} ms time in ms (default: 500)
* @param {Boolean=} reverse if true it waits for the opposite (default: false)
* @uses utility/waitUntil, property/getText
* @type utility
*
*/
var waitForText = function waitForText(selector, ms, reverse) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used, like
*
* ```js
* var elem = $('#elem');
* elem.waitForXXX(10000, true);
* ```
*/
reverse = typeof reverse === 'boolean' ? reverse : false;
/*!
* ensure that ms is set properly
*/
if (typeof ms !== 'number') {
ms = this.options.waitforTimeout;
}
var isReversed = reverse ? 'with' : 'without';
var errorMsg = 'element ("' + (selector || this.lastResult.selector) + '") still ' + isReversed + ' text after ' + ms + 'ms';
return this.waitUntil(function () {
return _this.getText(selector).then(function (text) {
if (!Array.isArray(text)) {
return text !== '' !== reverse;
}
var result = reverse;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(text), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var val = _step.value;
if (!reverse) {
result = result || val !== '';
} else {
result = result && val === '';
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result !== reverse;
});
}, ms, errorMsg);
};
exports.default = waitForText;
module.exports = exports['default'];

View File

@ -0,0 +1,114 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Wait for an element (selected by css selector) for the provided amount of
* milliseconds to have a value. If multiple elements get queryied by given
* selector, it returns true (or false if reverse flag is set) if at least one
* element has a value.
*
* <example>
:index.html
<input name="someInput" id="elem" value=""></input>
<script type="text/javascript">
setTimeout(function () {
document.getElementById('elem').value = 'some text';
}, 2000);
</script>
:waitForValueExample.js
it('should detect when element has value', function () {
browser.waitForValue('#elem', 3000);
// same as
elem = $('#elem');
elem.waitForValue(3000)
});
* </example>
*
* @alias browser.waitForValue
* @param {String} selector element to wait
* @param {Number=} ms time in ms (default: 500)
* @param {Boolean=} reverse if true it waits for the opposite (default: false)
* @uses utility/waitUntil, property/getValue
* @type utility
*
*/
var waitForValue = function waitForValue(selector, ms, reverse) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used, like
*
* ```js
* var elem = $('#elem');
* elem.waitForXXX(10000, true);
* ```
*/
reverse = typeof reverse === 'boolean' ? reverse : false;
/*!
* ensure that ms is set properly
*/
if (typeof ms !== 'number') {
ms = this.options.waitforTimeout;
}
var isReversed = reverse ? 'with' : 'without';
var errorMsg = 'element ("' + (selector || this.lastResult.selector) + '") still ' + isReversed + ' a value after ' + ms + 'ms';
return this.waitUntil(function () {
return _this.getValue(selector).then(function (value) {
if (!Array.isArray(value)) {
return value !== '' !== reverse;
}
var result = reverse;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(value), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var val = _step.value;
if (!reverse) {
result = result || val !== '';
} else {
result = result && val === '';
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result !== reverse;
});
}, ms, errorMsg);
};
exports.default = waitForValue;
module.exports = exports['default'];

View File

@ -0,0 +1,114 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
*
* Wait for an element (selected by css selector) for the provided amount of
* milliseconds to be (in)visible. If multiple elements get queryied by given
* selector, it returns true (or false if reverse flag is set) if at least one
* element is visible.
*
* <example>
:index.html
<div id="elem" style="visibility: hidden;">Hello World!</div>
<script type="text/javascript">
setTimeout(function () {
document.getElementById('elem').style.visibility = 'visible';
}, 2000);
</script>
:waitForVisibleExample.js
it('should detect when element is visible', function () {
browser.waitForVisible('#elem', 3000);
// same as
elem = $('#elem');
elem.waitForVisible(3000)
});
* </example>
*
* @alias browser.waitForVisible
* @param {String} selector element to wait for
* @param {Number=} ms time in ms (default: 500)
* @param {Boolean=} reverse if true it waits for the opposite (default: false)
* @uses utility/waitUntil, state/isVisible
* @type utility
*
*/
var waitForVisible = function waitForVisible(selector, ms, reverse) {
var _this = this;
/**
* we can't use default values for function parameter here because this would
* break the ability to chain the command with an element if reverse is used, like
*
* ```js
* var elem = $('#elem');
* elem.waitForXXX(10000, true);
* ```
*/
reverse = typeof reverse === 'boolean' ? reverse : false;
/*!
* ensure that ms is set properly
*/
if (typeof ms !== 'number') {
ms = this.options.waitforTimeout;
}
var isReversed = reverse ? '' : 'not';
var errorMsg = 'element ("' + (selector || this.lastResult.selector) + '") still ' + isReversed + ' visible after ' + ms + 'ms';
return this.waitUntil(function () {
return _this.isVisible(selector).then(function (isVisible) {
if (!Array.isArray(isVisible)) {
return isVisible !== reverse;
}
var result = reverse;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(isVisible), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var val = _step.value;
if (!reverse) {
result = result || val;
} else {
result = result && val;
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result !== reverse;
});
}, ms, errorMsg);
};
exports.default = waitForVisible;
module.exports = exports['default'];

View File

@ -0,0 +1,92 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
exports.default = function (condition, timeout, timeoutMsg, interval) {
/*!
* ensure that timeout and interval are set properly
*/
if (typeof timeout !== 'number') {
timeout = this.options.waitforTimeout;
}
if (typeof interval !== 'number') {
interval = this.options.waitforInterval;
}
var fn = void 0;
if (typeof condition === 'function') {
fn = condition.bind(this);
} else {
fn = function fn() {
return _promise2.default.resolve(condition);
};
}
var isSync = this.options.sync;
var timer = new _Timer2.default(interval, timeout, fn, true, isSync);
return timer.catch(function (e) {
if (e.message === 'timeout' && typeof timeoutMsg === 'string') {
throw new _ErrorHandler.WaitUntilTimeoutError(timeoutMsg);
}
if (e.type === 'NoSuchElement') {
throw new _ErrorHandler.WaitUntilTimeoutError(e.message);
}
throw new _ErrorHandler.WaitUntilTimeoutError('Promise was rejected with the following reason: ' + e.message);
});
};
var _ErrorHandler = require('../utils/ErrorHandler');
var _Timer = require('../utils/Timer');
var _Timer2 = _interopRequireDefault(_Timer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
module.exports = exports['default']; /**
*
* This wait command is your universal weapon if you want to wait on something. It expects a condition
* and waits until that condition is fulfilled with a truthy value. A condition can be either a promise
* or a command result. The commands within the condition are getting executed synchronously like in
* your test.
*
* A common example is to wait until a certain element contains a certain text (see example).
*
* <example>
:example.html
<div id="someText">I am some text</div>
<script>
setTimeout(function() {
$('#someText').html('I am now different');
}, 1000);
</script>
:waitUntil.js
it('should wait until text has changed', function () {
browser.waitUntil(function () {
return browser.getText('#someText') === 'I am now different'
}, 5000, 'expected text to be different after 5s');
});
* </example>
*
*
* @alias browser.waitUntil
* @param {Function|Promise} condition condition to wait on
* @param {Number=} timeout timeout in ms (default: 500)
* @param {String=} timeoutMsg error message to throw when waitUntil times out
* @param {Number=} interval interval between condition checks (default: 500)
* @uses utility/pause
* @type utility
*
*/