@netsells/simulate-user
Advanced tools
Comparing version 1.0.6 to 1.1.0
# Changelog | ||
## 1.1.0 (12/9/19) | ||
- Deprecated `fillSelect`, `fillIn` now can take SearchProperties or a string as the second parameter | ||
- Added `parentElement` | ||
- Added `directText` | ||
- Add `direct` option for when finding elements based on text content | ||
- Added `className` | ||
- Add optional search argument to click child elements | ||
## 1.0.6 (10/9/19) | ||
@@ -4,0 +13,0 @@ |
@@ -12,2 +12,4 @@ "use strict"; | ||
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); | ||
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); | ||
@@ -37,6 +39,15 @@ | ||
* @property {Function} predicate - Predicate function wrappers must match | ||
* @property {Function} visible - If element must be visible or not | ||
* @property {Boolean} visible - If element must be visible or not | ||
* @property {Boolean} direct - If text should be a direct child or not | ||
*/ | ||
/** | ||
* A generic value selector. For a `textarea` or `input` it should always be a | ||
* string or number, for a `select` it can be a string or a `SearchProperties` | ||
* | ||
* @typedef ValueSelector | ||
* @type {SearchProperties|String|Number} | ||
*/ | ||
/** | ||
* Simulate a user | ||
@@ -67,30 +78,5 @@ */ | ||
(0, _createClass2["default"])(SimulateUser, [{ | ||
key: "log", | ||
key: "sleep", | ||
/** | ||
* Proxy for console.log | ||
* | ||
* @param {*} ...args | ||
*/ | ||
value: function log() { | ||
var _console; | ||
(_console = console).log.apply(_console, arguments); // eslint-disable-line no-console | ||
} | ||
/** | ||
* Proxy for console.error | ||
* | ||
* @param {*} ...args | ||
*/ | ||
}, { | ||
key: "error", | ||
value: function error() { | ||
var _console2; | ||
(_console2 = console).error.apply(_console2, arguments); // eslint-disable-line no-console | ||
} | ||
/** | ||
* Returns a promise which resolves in a certain amount of milliseconds | ||
@@ -102,5 +88,2 @@ * | ||
*/ | ||
}, { | ||
key: "sleep", | ||
value: function sleep(timeout) { | ||
@@ -242,3 +225,5 @@ return new Promise(function (resolve) { | ||
_ref$visible = _ref.visible, | ||
visible = _ref$visible === void 0 ? false : _ref$visible; | ||
visible = _ref$visible === void 0 ? false : _ref$visible, | ||
_ref$direct = _ref.direct, | ||
direct = _ref$direct === void 0 ? false : _ref$direct; | ||
var all = this.querySelectorAll(query); | ||
@@ -248,3 +233,3 @@ | ||
all = all.filter(function (wrapper) { | ||
var texts = [wrapper.text, text].map(function (t) { | ||
var texts = [wrapper[direct ? 'directText' : 'text'], text].map(function (t) { | ||
return (t || '').toString(); | ||
@@ -516,2 +501,4 @@ }); | ||
* Click this node | ||
* | ||
* @param {SearchProperties?} search | ||
*/ | ||
@@ -521,8 +508,51 @@ | ||
key: "click", | ||
value: function click() { | ||
this.log('click', this.node); | ||
this.dispatchEvent(new MouseEvent('mousedown')); | ||
this.dispatchEvent(new MouseEvent('mouseup')); | ||
this.node.click(); | ||
} | ||
value: function () { | ||
var _click = (0, _asyncToGenerator2["default"])( | ||
/*#__PURE__*/ | ||
_regenerator["default"].mark(function _callee5() { | ||
var search, | ||
options, | ||
_args5 = arguments; | ||
return _regenerator["default"].wrap(function _callee5$(_context5) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
case 0: | ||
search = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : null; | ||
this.log('click', this.node, search); | ||
if (!search) { | ||
_context5.next = 6; | ||
break; | ||
} | ||
_context5.next = 5; | ||
return this.find(search).then(function (el) { | ||
return el.click(); | ||
}); | ||
case 5: | ||
return _context5.abrupt("return"); | ||
case 6: | ||
options = this.getEventOptions({ | ||
bubbles: true | ||
}); | ||
this.dispatchEvent(new MouseEvent('mousedown', options)); | ||
this.dispatchEvent(new MouseEvent('mouseup', options)); | ||
this.node.click(); | ||
case 10: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
} | ||
}, _callee5, this); | ||
})); | ||
function click() { | ||
return _click.apply(this, arguments); | ||
} | ||
return click; | ||
}() | ||
/** | ||
@@ -539,8 +569,8 @@ * Attach files to this input element | ||
/*#__PURE__*/ | ||
_regenerator["default"].mark(function _callee5(files) { | ||
_regenerator["default"].mark(function _callee6(files) { | ||
var dataTransfer, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file; | ||
return _regenerator["default"].wrap(function _callee5$(_context5) { | ||
return _regenerator["default"].wrap(function _callee6$(_context6) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
switch (_context6.prev = _context6.next) { | ||
case 0: | ||
@@ -551,3 +581,3 @@ dataTransfer = new DataTransfer(); | ||
_iteratorError = undefined; | ||
_context5.prev = 4; | ||
_context6.prev = 4; | ||
@@ -559,14 +589,14 @@ for (_iterator = files[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
_context5.next = 12; | ||
_context6.next = 12; | ||
break; | ||
case 8: | ||
_context5.prev = 8; | ||
_context5.t0 = _context5["catch"](4); | ||
_context6.prev = 8; | ||
_context6.t0 = _context6["catch"](4); | ||
_didIteratorError = true; | ||
_iteratorError = _context5.t0; | ||
_iteratorError = _context6.t0; | ||
case 12: | ||
_context5.prev = 12; | ||
_context5.prev = 13; | ||
_context6.prev = 12; | ||
_context6.prev = 13; | ||
@@ -578,6 +608,6 @@ if (!_iteratorNormalCompletion && _iterator["return"] != null) { | ||
case 15: | ||
_context5.prev = 15; | ||
_context6.prev = 15; | ||
if (!_didIteratorError) { | ||
_context5.next = 18; | ||
_context6.next = 18; | ||
break; | ||
@@ -589,6 +619,6 @@ } | ||
case 18: | ||
return _context5.finish(15); | ||
return _context6.finish(15); | ||
case 19: | ||
return _context5.finish(12); | ||
return _context6.finish(12); | ||
@@ -601,6 +631,6 @@ case 20: | ||
case "end": | ||
return _context5.stop(); | ||
return _context6.stop(); | ||
} | ||
} | ||
}, _callee5, this, [[4, 8, 12, 20], [13,, 15, 19]]); | ||
}, _callee6, this, [[4, 8, 12, 20], [13,, 15, 19]]); | ||
})); | ||
@@ -697,3 +727,3 @@ | ||
* | ||
* @param {String} text | ||
* @param {String|Number} text | ||
*/ | ||
@@ -705,5 +735,6 @@ | ||
this.log('typeValue', text); | ||
var value = (text || '').toString(); | ||
this.focus(); | ||
this.node.value = text; | ||
var key = (text || '').toString().slice(-1)[0]; | ||
this.node.value = value; | ||
var key = value.slice(-1)[0]; | ||
@@ -720,3 +751,3 @@ if (key) { | ||
* @param {String} label | ||
* @param {String} value | ||
* @param {ValueSelector} value | ||
* | ||
@@ -731,26 +762,26 @@ * @returns {SimulateUser} - The field wrapper | ||
/*#__PURE__*/ | ||
_regenerator["default"].mark(function _callee6(label, value) { | ||
_regenerator["default"].mark(function _callee7(label, value) { | ||
var field; | ||
return _regenerator["default"].wrap(function _callee6$(_context6) { | ||
return _regenerator["default"].wrap(function _callee7$(_context7) { | ||
while (1) { | ||
switch (_context6.prev = _context6.next) { | ||
switch (_context7.prev = _context7.next) { | ||
case 0: | ||
this.log('fillIn', label); | ||
_context6.next = 3; | ||
_context7.next = 3; | ||
return this.field(label); | ||
case 3: | ||
field = _context6.sent; | ||
_context6.next = 6; | ||
field = _context7.sent; | ||
_context7.next = 6; | ||
return field.fill(value); | ||
case 6: | ||
return _context6.abrupt("return", field); | ||
return _context7.abrupt("return", field); | ||
case 7: | ||
case "end": | ||
return _context6.stop(); | ||
return _context7.stop(); | ||
} | ||
} | ||
}, _callee6, this); | ||
}, _callee7, this); | ||
})); | ||
@@ -767,3 +798,3 @@ | ||
* | ||
* @param {String} text | ||
* @param {ValueSelector} value | ||
*/ | ||
@@ -776,30 +807,28 @@ | ||
/*#__PURE__*/ | ||
_regenerator["default"].mark(function _callee7(text) { | ||
return _regenerator["default"].wrap(function _callee7$(_context7) { | ||
_regenerator["default"].mark(function _callee8(value) { | ||
return _regenerator["default"].wrap(function _callee8$(_context8) { | ||
while (1) { | ||
switch (_context7.prev = _context7.next) { | ||
switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context7.t0 = this.tag; | ||
_context7.next = _context7.t0 === 'select' ? 3 : 6; | ||
_context8.t0 = this.tag; | ||
_context8.next = _context8.t0 === 'select' ? 3 : 6; | ||
break; | ||
case 3: | ||
_context7.next = 5; | ||
return this.select({ | ||
text: text | ||
}); | ||
_context8.next = 5; | ||
return this.select(value); | ||
case 5: | ||
return _context7.abrupt("break", 8); | ||
return _context8.abrupt("break", 8); | ||
case 6: | ||
_context7.next = 8; | ||
return this.typeValue(text); | ||
_context8.next = 8; | ||
return this.typeValue(value); | ||
case 8: | ||
case "end": | ||
return _context7.stop(); | ||
return _context8.stop(); | ||
} | ||
} | ||
}, _callee7, this); | ||
}, _callee8, this); | ||
})); | ||
@@ -816,5 +845,7 @@ | ||
* | ||
* @deprecated since version 1.1.0 | ||
* | ||
* @param {String} label | ||
* @param {String} text | ||
* @param {Object} options | ||
* @param {SearchProperties} options | ||
* | ||
@@ -829,17 +860,18 @@ * @returns {SimulateUser} - The field wrapper | ||
/*#__PURE__*/ | ||
_regenerator["default"].mark(function _callee8(label, text) { | ||
_regenerator["default"].mark(function _callee9(label, text) { | ||
var options, | ||
field, | ||
_args8 = arguments; | ||
return _regenerator["default"].wrap(function _callee8$(_context8) { | ||
_args9 = arguments; | ||
return _regenerator["default"].wrap(function _callee9$(_context9) { | ||
while (1) { | ||
switch (_context8.prev = _context8.next) { | ||
switch (_context9.prev = _context9.next) { | ||
case 0: | ||
options = _args8.length > 2 && _args8[2] !== undefined ? _args8[2] : {}; | ||
_context8.next = 3; | ||
options = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : {}; | ||
this.warn('fillSelect is deprecated. Use fillIn'); | ||
_context9.next = 4; | ||
return this.field(label); | ||
case 3: | ||
field = _context8.sent; | ||
_context8.next = 6; | ||
case 4: | ||
field = _context9.sent; | ||
_context9.next = 7; | ||
return field.select((0, _objectSpread2["default"])({ | ||
@@ -849,11 +881,11 @@ text: text | ||
case 6: | ||
return _context8.abrupt("return", field); | ||
case 7: | ||
return _context9.abrupt("return", field); | ||
case 7: | ||
case 8: | ||
case "end": | ||
return _context8.stop(); | ||
return _context9.stop(); | ||
} | ||
} | ||
}, _callee8, this); | ||
}, _callee9, this); | ||
})); | ||
@@ -870,3 +902,3 @@ | ||
* | ||
* @param {Object} options | ||
* @param {ValueSelector} value | ||
*/ | ||
@@ -879,24 +911,19 @@ | ||
/*#__PURE__*/ | ||
_regenerator["default"].mark(function _callee9(_ref3) { | ||
var text, exact, caseSensitive, option; | ||
return _regenerator["default"].wrap(function _callee9$(_context9) { | ||
_regenerator["default"].mark(function _callee10(value) { | ||
var options, option; | ||
return _regenerator["default"].wrap(function _callee10$(_context10) { | ||
while (1) { | ||
switch (_context9.prev = _context9.next) { | ||
switch (_context10.prev = _context10.next) { | ||
case 0: | ||
text = _ref3.text, exact = _ref3.exact, caseSensitive = _ref3.caseSensitive; | ||
this.log('select', { | ||
text: text, | ||
exact: exact, | ||
caseSensitive: caseSensitive | ||
}); | ||
_context9.next = 4; | ||
return this.find({ | ||
query: 'option', | ||
text: text, | ||
exact: exact, | ||
caseSensitive: caseSensitive | ||
}); | ||
this.log('select', value); | ||
options = (0, _typeof2["default"])(value) === 'object' ? value : { | ||
text: value | ||
}; | ||
_context10.next = 4; | ||
return this.find((0, _objectSpread2["default"])({ | ||
query: 'option' | ||
}, options)); | ||
case 4: | ||
option = _context9.sent; | ||
option = _context10.sent; | ||
this.node.value = option.value; | ||
@@ -907,6 +934,6 @@ this.sendChangeEvent(); | ||
case "end": | ||
return _context9.stop(); | ||
return _context10.stop(); | ||
} | ||
} | ||
}, _callee9, this); | ||
}, _callee10, this); | ||
})); | ||
@@ -977,4 +1004,4 @@ | ||
}); | ||
return options.map(function (_ref4) { | ||
var value = _ref4.value; | ||
return options.map(function (_ref3) { | ||
var value = _ref3.value; | ||
return value; | ||
@@ -995,2 +1022,39 @@ }); | ||
/** | ||
* Get text content which is a direct child of this node | ||
* | ||
* @returns {String} | ||
*/ | ||
}, { | ||
key: "directText", | ||
get: function get() { | ||
return Array.from(this.node.childNodes).filter(function (node) { | ||
return node instanceof Text; | ||
}).map(function (node) { | ||
return node.textContent; | ||
}).join(' ').trim(); | ||
} | ||
/** | ||
* Get the parentElement in a wrapper | ||
* | ||
* @returns {SimulateUser} | ||
*/ | ||
}, { | ||
key: "parentElement", | ||
get: function get() { | ||
return this.node.parentElement && this.constructor.build(this.node.parentElement); | ||
} | ||
/** | ||
* Proxy for className | ||
* | ||
* @returns {String} | ||
*/ | ||
}, { | ||
key: "className", | ||
get: function get() { | ||
return this.node.className; | ||
} | ||
/** | ||
* Proxy for value | ||
@@ -1043,2 +1107,11 @@ * | ||
exports["default"] = SimulateUser; | ||
['log', 'error', 'warn'].forEach(function (which) { | ||
SimulateUser.prototype[which] = function () { | ||
var _console; | ||
(_console = console)[which].apply(_console, arguments); // eslint-disable-line no-console | ||
}; | ||
}); | ||
var _default = SimulateUser; | ||
exports["default"] = _default; |
{ | ||
"name": "@netsells/simulate-user", | ||
"version": "1.0.6", | ||
"version": "1.1.0", | ||
"description": "Library for simulating user interactions using JavaScript in the browser", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
477
README.md
@@ -27,128 +27,10 @@ [![npm version](https://badge.fury.io/js/%40netsells%2Fsimulate-user.svg)](https://badge.fury.io/js/%40netsells%2Fsimulate-user) | ||
## Members | ||
## Classes | ||
<dl> | ||
<dt><a href="#visible">visible</a> ⇒ <code>Boolean</code></dt> | ||
<dd><p>Check if the node is visible</p> | ||
<dt><a href="#SimulateUser">SimulateUser</a></dt> | ||
<dd><p>Simulate a user</p> | ||
</dd> | ||
<dt><a href="#hidden">hidden</a> ⇒ <code>Boolean</code></dt> | ||
<dd><p>Check if the node is hidden</p> | ||
</dd> | ||
<dt><a href="#nextElementSibling">nextElementSibling</a> ⇒ <code>SimulateUser</code> | <code>null</code></dt> | ||
<dd><p>nextElementSibling but returns a wrapper</p> | ||
</dd> | ||
<dt><a href="#options">options</a> ⇒ <code>Array.<String></code></dt> | ||
<dd><p>Get all select option values</p> | ||
</dd> | ||
<dt><a href="#text">text</a> ⇒ <code>String</code></dt> | ||
<dd><p>Get trimmed text content</p> | ||
</dd> | ||
<dt><a href="#value">value</a> ⇒ <code>String</code></dt> | ||
<dd><p>Proxy for value</p> | ||
</dd> | ||
<dt><a href="#htmlFor">htmlFor</a> ⇒ <code>String</code></dt> | ||
<dd><p>Proxy for htmlFor</p> | ||
</dd> | ||
<dt><a href="#tag">tag</a> ⇒ <code>String</code></dt> | ||
<dd><p>tagName but lower case</p> | ||
</dd> | ||
</dl> | ||
## Functions | ||
<dl> | ||
<dt><a href="#build">build()</a> ⇒ <code>SimulateUser</code></dt> | ||
<dd><p>Generate a instance using the same class constructor</p> | ||
</dd> | ||
<dt><a href="#log">log()</a></dt> | ||
<dd><p>Proxy for console.log</p> | ||
</dd> | ||
<dt><a href="#error">error()</a></dt> | ||
<dd><p>Proxy for console.error</p> | ||
</dd> | ||
<dt><a href="#sleep">sleep(timeout)</a> ⇒ <code>Promise.<undefined></code></dt> | ||
<dd><p>Returns a promise which resolves in a certain amount of milliseconds</p> | ||
</dd> | ||
<dt><a href="#timeout">timeout(func, limit)</a> ⇒ <code>Promise.<*></code></dt> | ||
<dd><p>Returns a promise which times out if the passed in promise doesn't | ||
resolve in time</p> | ||
</dd> | ||
<dt><a href="#getEventOptions">getEventOptions(options)</a> ⇒ <code>Object</code></dt> | ||
<dd><p>Get options for an event</p> | ||
</dd> | ||
<dt><a href="#querySelectorAll">querySelectorAll(query)</a> ⇒ <code>Array.<SimulateUser></code></dt> | ||
<dd><p>Proxy for querySelectorAll but returns an array of wrappers instead of | ||
nods</p> | ||
</dd> | ||
<dt><a href="#getElementById">getElementById(id)</a> ⇒ <code>SimulateUser</code> | <code>null</code></dt> | ||
<dd><p>getElementById but returns a wrapper</p> | ||
</dd> | ||
<dt><a href="#getElementsByName">getElementsByName(name)</a> ⇒ <code>Array.<SimulateUser></code></dt> | ||
<dd><p>getElementsByName but returns an array of wrappers</p> | ||
</dd> | ||
<dt><a href="#closest">closest()</a> ⇒ <code>SimulateUser</code> | <code>null</code></dt> | ||
<dd><p>closest but returns a wrapper</p> | ||
</dd> | ||
<dt><a href="#all">all(options)</a> ⇒ <code>SimulateUser</code> | <code>null</code></dt> | ||
<dd><p>Search through page elements as a user would, using text</p> | ||
</dd> | ||
<dt><a href="#first">first(options)</a> ⇒ <code>SimulateUser</code> | <code>null</code></dt> | ||
<dd><p>Get the first element of a query to <code>all</code></p> | ||
</dd> | ||
<dt><a href="#find">find(options, limit)</a> ⇒ <code>SimulateUser</code></dt> | ||
<dd><p>Get the first element of a query to <code>all</code>, but throws an error if it's | ||
not found. Will wait for an element to appear (e.g. if a form is | ||
updating)</p> | ||
</dd> | ||
<dt><a href="#field">field(label)</a> ⇒ <code>SimulateUser</code> | <code>null</code></dt> | ||
<dd><p>Get a field based on its label</p> | ||
</dd> | ||
<dt><a href="#fieldSet">fieldSet(legend)</a> ⇒ <code>SimulateUser</code> | <code>null</code></dt> | ||
<dd><p>Get a fieldset based on its legend</p> | ||
</dd> | ||
<dt><a href="#dispatchEvent">dispatchEvent(event)</a></dt> | ||
<dd><p>Proxy for dispatchEvent</p> | ||
</dd> | ||
<dt><a href="#click">click()</a></dt> | ||
<dd><p>Click this node</p> | ||
</dd> | ||
<dt><a href="#attach">attach(files)</a></dt> | ||
<dd><p>Attach files to this input element</p> | ||
</dd> | ||
<dt><a href="#check">check(checked)</a></dt> | ||
<dd><p>Check this checkbox</p> | ||
</dd> | ||
<dt><a href="#focus">focus()</a></dt> | ||
<dd><p>Focus this element</p> | ||
</dd> | ||
<dt><a href="#blur">blur()</a></dt> | ||
<dd><p>Blur this element</p> | ||
</dd> | ||
<dt><a href="#typeKey">typeKey(key)</a></dt> | ||
<dd><p>Type a single key on this element</p> | ||
</dd> | ||
<dt><a href="#type">type(text)</a></dt> | ||
<dd><p>Type a string on this element</p> | ||
</dd> | ||
<dt><a href="#typeValue">typeValue(text)</a></dt> | ||
<dd><p>Type into a fields value. Only simulates the final key press then | ||
triggers a single change event</p> | ||
</dd> | ||
<dt><a href="#fillIn">fillIn(label, value)</a> ⇒ <code>SimulateUser</code></dt> | ||
<dd><p>Find a field by its label then fill it in</p> | ||
</dd> | ||
<dt><a href="#fill">fill(text)</a></dt> | ||
<dd><p>Fill in this node as a field</p> | ||
</dd> | ||
<dt><a href="#fillSelect">fillSelect(label, text, options)</a> ⇒ <code>SimulateUser</code></dt> | ||
<dd><p>Find a select by its label then fill it in</p> | ||
</dd> | ||
<dt><a href="#select">select(options)</a></dt> | ||
<dd><p>Change a value by the option text</p> | ||
</dd> | ||
<dt><a href="#sendChangeEvent">sendChangeEvent()</a></dt> | ||
<dd><p>Send a change event</p> | ||
</dd> | ||
</dl> | ||
## Typedefs | ||
@@ -159,91 +41,140 @@ | ||
<dd></dd> | ||
<dt><a href="#ValueSelector">ValueSelector</a> : <code><a href="#SearchProperties">SearchProperties</a></code> | <code>String</code> | <code>Number</code></dt> | ||
<dd><p>A generic value selector. For a <code>textarea</code> or <code>input</code> it should always be a | ||
string or number, for a <code>select</code> it can be a string or a <code>SearchProperties</code></p> | ||
</dd> | ||
</dl> | ||
<a name="visible"></a> | ||
<a name="SimulateUser"></a> | ||
## visible ⇒ <code>Boolean</code> | ||
Check if the node is visible | ||
## SimulateUser | ||
Simulate a user | ||
**Kind**: global variable | ||
<a name="hidden"></a> | ||
**Kind**: global class | ||
## hidden ⇒ <code>Boolean</code> | ||
Check if the node is hidden | ||
* [SimulateUser](#SimulateUser) | ||
* [new SimulateUser(node)](#new_SimulateUser_new) | ||
* _instance_ | ||
* [.visible](#SimulateUser+visible) ⇒ <code>Boolean</code> | ||
* [.hidden](#SimulateUser+hidden) ⇒ <code>Boolean</code> | ||
* [.nextElementSibling](#SimulateUser+nextElementSibling) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
* [.options](#SimulateUser+options) ⇒ <code>Array.<String></code> | ||
* [.text](#SimulateUser+text) ⇒ <code>String</code> | ||
* [.directText](#SimulateUser+directText) ⇒ <code>String</code> | ||
* [.parentElement](#SimulateUser+parentElement) ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
* [.className](#SimulateUser+className) ⇒ <code>String</code> | ||
* [.value](#SimulateUser+value) ⇒ <code>String</code> | ||
* [.htmlFor](#SimulateUser+htmlFor) ⇒ <code>String</code> | ||
* [.tag](#SimulateUser+tag) ⇒ <code>String</code> | ||
* [.sleep(timeout)](#SimulateUser+sleep) ⇒ <code>Promise.<undefined></code> | ||
* [.timeout(func, limit)](#SimulateUser+timeout) ⇒ <code>Promise.<\*></code> | ||
* [.getEventOptions(options)](#SimulateUser+getEventOptions) ⇒ <code>Object</code> | ||
* [.querySelectorAll(query)](#SimulateUser+querySelectorAll) ⇒ [<code>Array.<SimulateUser></code>](#SimulateUser) | ||
* [.getElementById(id)](#SimulateUser+getElementById) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
* [.getElementsByName(name)](#SimulateUser+getElementsByName) ⇒ [<code>Array.<SimulateUser></code>](#SimulateUser) | ||
* [.closest()](#SimulateUser+closest) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
* [.all(options)](#SimulateUser+all) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
* [.first(options)](#SimulateUser+first) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
* [.find(options, limit)](#SimulateUser+find) ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
* [.field(label)](#SimulateUser+field) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
* [.fieldSet(legend)](#SimulateUser+fieldSet) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
* [.dispatchEvent(event)](#SimulateUser+dispatchEvent) | ||
* [.click(search)](#SimulateUser+click) | ||
* [.attach(files)](#SimulateUser+attach) | ||
* [.check(checked)](#SimulateUser+check) | ||
* [.focus()](#SimulateUser+focus) | ||
* [.blur()](#SimulateUser+blur) | ||
* [.typeKey(key)](#SimulateUser+typeKey) | ||
* [.type(text)](#SimulateUser+type) | ||
* [.typeValue(text)](#SimulateUser+typeValue) | ||
* [.fillIn(label, value)](#SimulateUser+fillIn) ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
* [.fill(value)](#SimulateUser+fill) | ||
* ~~[.fillSelect(label, text, options)](#SimulateUser+fillSelect) ⇒ [<code>SimulateUser</code>](#SimulateUser)~~ | ||
* [.select(value)](#SimulateUser+select) | ||
* [.sendChangeEvent()](#SimulateUser+sendChangeEvent) | ||
* _static_ | ||
* [.build()](#SimulateUser.build) ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
**Kind**: global variable | ||
<a name="nextElementSibling"></a> | ||
<a name="new_SimulateUser_new"></a> | ||
## nextElementSibling ⇒ <code>SimulateUser</code> \| <code>null</code> | ||
nextElementSibling but returns a wrapper | ||
### new SimulateUser(node) | ||
Create a SimulateUser class for a page element | ||
**Kind**: global variable | ||
<a name="options"></a> | ||
## options ⇒ <code>Array.<String></code> | ||
Get all select option values | ||
| Param | Type | | ||
| --- | --- | | ||
| node | <code>HTMLElement</code> | | ||
**Kind**: global variable | ||
<a name="text"></a> | ||
<a name="SimulateUser+visible"></a> | ||
## text ⇒ <code>String</code> | ||
Get trimmed text content | ||
### simulateUser.visible ⇒ <code>Boolean</code> | ||
Check if the node is visible | ||
**Kind**: global variable | ||
<a name="value"></a> | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+hidden"></a> | ||
## value ⇒ <code>String</code> | ||
Proxy for value | ||
### simulateUser.hidden ⇒ <code>Boolean</code> | ||
Check if the node is hidden | ||
**Kind**: global variable | ||
<a name="htmlFor"></a> | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+nextElementSibling"></a> | ||
## htmlFor ⇒ <code>String</code> | ||
Proxy for htmlFor | ||
### simulateUser.nextElementSibling ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
nextElementSibling but returns a wrapper | ||
**Kind**: global variable | ||
<a name="tag"></a> | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+options"></a> | ||
## tag ⇒ <code>String</code> | ||
tagName but lower case | ||
### simulateUser.options ⇒ <code>Array.<String></code> | ||
Get all select option values | ||
**Kind**: global variable | ||
<a name="build"></a> | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+text"></a> | ||
## build() ⇒ <code>SimulateUser</code> | ||
Generate a instance using the same class constructor | ||
### simulateUser.text ⇒ <code>String</code> | ||
Get trimmed text content | ||
**Kind**: global function | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+directText"></a> | ||
| Param | Type | | ||
| --- | --- | | ||
| ...args | <code>\*</code> | | ||
### simulateUser.directText ⇒ <code>String</code> | ||
Get text content which is a direct child of this node | ||
<a name="log"></a> | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+parentElement"></a> | ||
## log() | ||
Proxy for console.log | ||
### simulateUser.parentElement ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
Get the parentElement in a wrapper | ||
**Kind**: global function | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+className"></a> | ||
| Param | Type | | ||
| --- | --- | | ||
| ...args | <code>\*</code> | | ||
### simulateUser.className ⇒ <code>String</code> | ||
Proxy for className | ||
<a name="error"></a> | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+value"></a> | ||
## error() | ||
Proxy for console.error | ||
### simulateUser.value ⇒ <code>String</code> | ||
Proxy for value | ||
**Kind**: global function | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+htmlFor"></a> | ||
| Param | Type | | ||
| --- | --- | | ||
| ...args | <code>\*</code> | | ||
### simulateUser.htmlFor ⇒ <code>String</code> | ||
Proxy for htmlFor | ||
<a name="sleep"></a> | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+tag"></a> | ||
## sleep(timeout) ⇒ <code>Promise.<undefined></code> | ||
### simulateUser.tag ⇒ <code>String</code> | ||
tagName but lower case | ||
**Kind**: instance property of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+sleep"></a> | ||
### simulateUser.sleep(timeout) ⇒ <code>Promise.<undefined></code> | ||
Returns a promise which resolves in a certain amount of milliseconds | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -254,9 +185,9 @@ | Param | Type | | ||
<a name="timeout"></a> | ||
<a name="SimulateUser+timeout"></a> | ||
## timeout(func, limit) ⇒ <code>Promise.<\*></code> | ||
### simulateUser.timeout(func, limit) ⇒ <code>Promise.<\*></code> | ||
Returns a promise which times out if the passed in promise doesn't | ||
resolve in time | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -268,8 +199,8 @@ | Param | Type | Default | | ||
<a name="getEventOptions"></a> | ||
<a name="SimulateUser+getEventOptions"></a> | ||
## getEventOptions(options) ⇒ <code>Object</code> | ||
### simulateUser.getEventOptions(options) ⇒ <code>Object</code> | ||
Get options for an event | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -280,9 +211,9 @@ | Param | Type | | ||
<a name="querySelectorAll"></a> | ||
<a name="SimulateUser+querySelectorAll"></a> | ||
## querySelectorAll(query) ⇒ <code>Array.<SimulateUser></code> | ||
### simulateUser.querySelectorAll(query) ⇒ [<code>Array.<SimulateUser></code>](#SimulateUser) | ||
Proxy for querySelectorAll but returns an array of wrappers instead of | ||
nods | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -293,8 +224,8 @@ | Param | Type | | ||
<a name="getElementById"></a> | ||
<a name="SimulateUser+getElementById"></a> | ||
## getElementById(id) ⇒ <code>SimulateUser</code> \| <code>null</code> | ||
### simulateUser.getElementById(id) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
getElementById but returns a wrapper | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -305,8 +236,8 @@ | Param | Type | | ||
<a name="getElementsByName"></a> | ||
<a name="SimulateUser+getElementsByName"></a> | ||
## getElementsByName(name) ⇒ <code>Array.<SimulateUser></code> | ||
### simulateUser.getElementsByName(name) ⇒ [<code>Array.<SimulateUser></code>](#SimulateUser) | ||
getElementsByName but returns an array of wrappers | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -317,8 +248,8 @@ | Param | Type | | ||
<a name="closest"></a> | ||
<a name="SimulateUser+closest"></a> | ||
## closest() ⇒ <code>SimulateUser</code> \| <code>null</code> | ||
### simulateUser.closest() ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
closest but returns a wrapper | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -329,8 +260,8 @@ | Param | Type | | ||
<a name="all"></a> | ||
<a name="SimulateUser+all"></a> | ||
## all(options) ⇒ <code>SimulateUser</code> \| <code>null</code> | ||
### simulateUser.all(options) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
Search through page elements as a user would, using text | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -341,8 +272,8 @@ | Param | Type | | ||
<a name="first"></a> | ||
<a name="SimulateUser+first"></a> | ||
## first(options) ⇒ <code>SimulateUser</code> \| <code>null</code> | ||
### simulateUser.first(options) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
Get the first element of a query to `all` | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -353,5 +284,5 @@ | Param | Type | | ||
<a name="find"></a> | ||
<a name="SimulateUser+find"></a> | ||
## find(options, limit) ⇒ <code>SimulateUser</code> | ||
### simulateUser.find(options, limit) ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
Get the first element of a query to `all`, but throws an error if it's | ||
@@ -361,3 +292,3 @@ not found. Will wait for an element to appear (e.g. if a form is | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
**Throws**: | ||
@@ -374,8 +305,8 @@ | ||
<a name="field"></a> | ||
<a name="SimulateUser+field"></a> | ||
## field(label) ⇒ <code>SimulateUser</code> \| <code>null</code> | ||
### simulateUser.field(label) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
Get a field based on its label | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
**Throws**: | ||
@@ -390,8 +321,8 @@ | ||
<a name="fieldSet"></a> | ||
<a name="SimulateUser+fieldSet"></a> | ||
## fieldSet(legend) ⇒ <code>SimulateUser</code> \| <code>null</code> | ||
### simulateUser.fieldSet(legend) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code> | ||
Get a fieldset based on its legend | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
**Throws**: | ||
@@ -406,8 +337,8 @@ | ||
<a name="dispatchEvent"></a> | ||
<a name="SimulateUser+dispatchEvent"></a> | ||
## dispatchEvent(event) | ||
### simulateUser.dispatchEvent(event) | ||
Proxy for dispatchEvent | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -418,14 +349,19 @@ | Param | Type | | ||
<a name="click"></a> | ||
<a name="SimulateUser+click"></a> | ||
## click() | ||
### simulateUser.click(search) | ||
Click this node | ||
**Kind**: global function | ||
<a name="attach"></a> | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
## attach(files) | ||
| Param | Type | Default | | ||
| --- | --- | --- | | ||
| search | [<code>SearchProperties</code>](#SearchProperties) | <code></code> | | ||
<a name="SimulateUser+attach"></a> | ||
### simulateUser.attach(files) | ||
Attach files to this input element | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -436,8 +372,8 @@ | Param | Type | | ||
<a name="check"></a> | ||
<a name="SimulateUser+check"></a> | ||
## check(checked) | ||
### simulateUser.check(checked) | ||
Check this checkbox | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -448,20 +384,20 @@ | Param | Type | Default | | ||
<a name="focus"></a> | ||
<a name="SimulateUser+focus"></a> | ||
## focus() | ||
### simulateUser.focus() | ||
Focus this element | ||
**Kind**: global function | ||
<a name="blur"></a> | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+blur"></a> | ||
## blur() | ||
### simulateUser.blur() | ||
Blur this element | ||
**Kind**: global function | ||
<a name="typeKey"></a> | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser+typeKey"></a> | ||
## typeKey(key) | ||
### simulateUser.typeKey(key) | ||
Type a single key on this element | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -472,8 +408,8 @@ | Param | Type | | ||
<a name="type"></a> | ||
<a name="SimulateUser+type"></a> | ||
## type(text) | ||
### simulateUser.type(text) | ||
Type a string on this element | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
@@ -484,21 +420,21 @@ | Param | Type | | ||
<a name="typeValue"></a> | ||
<a name="SimulateUser+typeValue"></a> | ||
## typeValue(text) | ||
### simulateUser.typeValue(text) | ||
Type into a fields value. Only simulates the final key press then | ||
triggers a single change event | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
| Param | Type | | ||
| --- | --- | | ||
| text | <code>String</code> | | ||
| text | <code>String</code> \| <code>Number</code> | | ||
<a name="fillIn"></a> | ||
<a name="SimulateUser+fillIn"></a> | ||
## fillIn(label, value) ⇒ <code>SimulateUser</code> | ||
### simulateUser.fillIn(label, value) ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
Find a field by its label then fill it in | ||
**Kind**: global function | ||
**Returns**: <code>SimulateUser</code> - - The field wrapper | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
**Returns**: [<code>SimulateUser</code>](#SimulateUser) - - The field wrapper | ||
@@ -508,22 +444,24 @@ | Param | Type | | ||
| label | <code>String</code> | | ||
| value | <code>String</code> | | ||
| value | [<code>ValueSelector</code>](#ValueSelector) | | ||
<a name="fill"></a> | ||
<a name="SimulateUser+fill"></a> | ||
## fill(text) | ||
### simulateUser.fill(value) | ||
Fill in this node as a field | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
| Param | Type | | ||
| --- | --- | | ||
| text | <code>String</code> | | ||
| value | [<code>ValueSelector</code>](#ValueSelector) | | ||
<a name="fillSelect"></a> | ||
<a name="SimulateUser+fillSelect"></a> | ||
## fillSelect(label, text, options) ⇒ <code>SimulateUser</code> | ||
### ~~simulateUser.fillSelect(label, text, options) ⇒ [<code>SimulateUser</code>](#SimulateUser)~~ | ||
***Deprecated*** | ||
Find a select by its label then fill it in | ||
**Kind**: global function | ||
**Returns**: <code>SimulateUser</code> - - The field wrapper | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
**Returns**: [<code>SimulateUser</code>](#SimulateUser) - - The field wrapper | ||
@@ -534,21 +472,32 @@ | Param | Type | | ||
| text | <code>String</code> | | ||
| options | <code>Object</code> | | ||
| options | [<code>SearchProperties</code>](#SearchProperties) | | ||
<a name="select"></a> | ||
<a name="SimulateUser+select"></a> | ||
## select(options) | ||
### simulateUser.select(value) | ||
Change a value by the option text | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
| Param | Type | | ||
| --- | --- | | ||
| options | <code>Object</code> | | ||
| value | [<code>ValueSelector</code>](#ValueSelector) | | ||
<a name="sendChangeEvent"></a> | ||
<a name="SimulateUser+sendChangeEvent"></a> | ||
## sendChangeEvent() | ||
### simulateUser.sendChangeEvent() | ||
Send a change event | ||
**Kind**: global function | ||
**Kind**: instance method of [<code>SimulateUser</code>](#SimulateUser) | ||
<a name="SimulateUser.build"></a> | ||
### SimulateUser.build() ⇒ [<code>SimulateUser</code>](#SimulateUser) | ||
Generate a instance using the same class constructor | ||
**Kind**: static method of [<code>SimulateUser</code>](#SimulateUser) | ||
| Param | Type | | ||
| --- | --- | | ||
| ...args | <code>\*</code> | | ||
<a name="SearchProperties"></a> | ||
@@ -567,3 +516,11 @@ | ||
| predicate | <code>function</code> | Predicate function wrappers must match | | ||
| visible | <code>function</code> | If element must be visible or not | | ||
| visible | <code>Boolean</code> | If element must be visible or not | | ||
| direct | <code>Boolean</code> | If text should be a direct child or not | | ||
<a name="ValueSelector"></a> | ||
## ValueSelector : [<code>SearchProperties</code>](#SearchProperties) \| <code>String</code> \| <code>Number</code> | ||
A generic value selector. For a `textarea` or `input` it should always be a | ||
string or number, for a `select` it can be a string or a `SearchProperties` | ||
**Kind**: global typedef |
132
src/index.js
@@ -12,9 +12,18 @@ import { timeout, TimeoutError } from 'promise-timeout'; | ||
* @property {Function} predicate - Predicate function wrappers must match | ||
* @property {Function} visible - If element must be visible or not | ||
* @property {Boolean} visible - If element must be visible or not | ||
* @property {Boolean} direct - If text should be a direct child or not | ||
*/ | ||
/** | ||
* A generic value selector. For a `textarea` or `input` it should always be a | ||
* string or number, for a `select` it can be a string or a `SearchProperties` | ||
* | ||
* @typedef ValueSelector | ||
* @type {SearchProperties|String|Number} | ||
*/ | ||
/** | ||
* Simulate a user | ||
*/ | ||
export default class SimulateUser { | ||
class SimulateUser { | ||
/** | ||
@@ -43,20 +52,2 @@ * Create a SimulateUser class for a page element | ||
/** | ||
* Proxy for console.log | ||
* | ||
* @param {*} ...args | ||
*/ | ||
log(...args) { | ||
console.log(...args); // eslint-disable-line no-console | ||
} | ||
/** | ||
* Proxy for console.error | ||
* | ||
* @param {*} ...args | ||
*/ | ||
error(...args) { | ||
console.error(...args); // eslint-disable-line no-console | ||
} | ||
/** | ||
* Returns a promise which resolves in a certain amount of milliseconds | ||
@@ -180,2 +171,3 @@ * | ||
visible = false, | ||
direct = false, | ||
}) { | ||
@@ -186,3 +178,6 @@ let all = this.querySelectorAll(query); | ||
all = all.filter(wrapper => { | ||
let texts = [wrapper.text, text].map(t => (t || '').toString()); | ||
let texts = [ | ||
wrapper[direct ? 'directText' : 'text'], | ||
text, | ||
].map(t => (t || '').toString()); | ||
@@ -341,8 +336,18 @@ if (!caseSensitive) { | ||
* Click this node | ||
* | ||
* @param {SearchProperties?} search | ||
*/ | ||
click() { | ||
this.log('click', this.node); | ||
async click(search = null) { | ||
this.log('click', this.node, search); | ||
this.dispatchEvent(new MouseEvent('mousedown')); | ||
this.dispatchEvent(new MouseEvent('mouseup')); | ||
if (search) { | ||
await this.find(search).then(el => el.click()); | ||
return; | ||
} | ||
const options = this.getEventOptions({ bubbles: true }); | ||
this.dispatchEvent(new MouseEvent('mousedown', options)); | ||
this.dispatchEvent(new MouseEvent('mouseup', options)); | ||
this.node.click(); | ||
@@ -421,3 +426,3 @@ } | ||
* | ||
* @param {String} text | ||
* @param {String|Number} text | ||
*/ | ||
@@ -427,6 +432,8 @@ typeValue(text) { | ||
const value = (text || '').toString(); | ||
this.focus(); | ||
this.node.value = text; | ||
this.node.value = value; | ||
const key = (text || '').toString().slice(-1)[0]; | ||
const key = value.slice(-1)[0]; | ||
@@ -444,3 +451,3 @@ if (key) { | ||
* @param {String} label | ||
* @param {String} value | ||
* @param {ValueSelector} value | ||
* | ||
@@ -462,8 +469,8 @@ * @returns {SimulateUser} - The field wrapper | ||
* | ||
* @param {String} text | ||
* @param {ValueSelector} value | ||
*/ | ||
async fill(text) { | ||
async fill(value) { | ||
switch (this.tag) { | ||
case 'select': { | ||
await this.select({ text }); | ||
await this.select(value); | ||
@@ -474,3 +481,3 @@ break; | ||
default: { | ||
await this.typeValue(text); | ||
await this.typeValue(value); | ||
} | ||
@@ -483,5 +490,7 @@ } | ||
* | ||
* @deprecated since version 1.1.0 | ||
* | ||
* @param {String} label | ||
* @param {String} text | ||
* @param {Object} options | ||
* @param {SearchProperties} options | ||
* | ||
@@ -491,2 +500,4 @@ * @returns {SimulateUser} - The field wrapper | ||
async fillSelect(label, text, options = {}) { | ||
this.warn('fillSelect is deprecated. Use fillIn'); | ||
const field = await this.field(label); | ||
@@ -505,12 +516,14 @@ | ||
* | ||
* @param {Object} options | ||
* @param {ValueSelector} value | ||
*/ | ||
async select({ text, exact, caseSensitive }) { | ||
this.log('select', { text, exact, caseSensitive }); | ||
async select(value) { | ||
this.log('select', value); | ||
const options = typeof value === 'object' | ||
? value | ||
: { text: value }; | ||
const option = await this.find({ | ||
query: 'option', | ||
text, | ||
exact, | ||
caseSensitive, | ||
...options, | ||
}); | ||
@@ -571,2 +584,33 @@ | ||
/** | ||
* Get text content which is a direct child of this node | ||
* | ||
* @returns {String} | ||
*/ | ||
get directText() { | ||
return Array.from(this.node.childNodes) | ||
.filter(node => node instanceof Text) | ||
.map(node => node.textContent) | ||
.join(' ') | ||
.trim(); | ||
} | ||
/** | ||
* Get the parentElement in a wrapper | ||
* | ||
* @returns {SimulateUser} | ||
*/ | ||
get parentElement() { | ||
return this.node.parentElement && this.constructor.build(this.node.parentElement); | ||
} | ||
/** | ||
* Proxy for className | ||
* | ||
* @returns {String} | ||
*/ | ||
get className() { | ||
return this.node.className; | ||
} | ||
/** | ||
* Proxy for value | ||
@@ -598,1 +642,9 @@ * | ||
} | ||
['log', 'error', 'warn'].forEach(which => { | ||
SimulateUser.prototype[which] = function(...args) { | ||
console[which](...args); // eslint-disable-line no-console | ||
}; | ||
}); | ||
export default SimulateUser; |
231051
1477
504