New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@netsells/simulate-user

Package Overview
Dependencies
Maintainers
9
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@netsells/simulate-user - npm Package Compare versions

Comparing version 1.0.6 to 1.1.0

9

CHANGELOG.md
# 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 @@

315

dist/index.js

@@ -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",

@@ -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.&lt;String&gt;</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.&lt;undefined&gt;</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.&lt;*&gt;</code></dt>
<dd><p>Returns a promise which times out if the passed in promise doesn&#39;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.&lt;SimulateUser&gt;</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.&lt;SimulateUser&gt;</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&#39;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.&lt;String&gt;</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.&lt;undefined&gt;</code>
* [.timeout(func, limit)](#SimulateUser+timeout) ⇒ <code>Promise.&lt;\*&gt;</code>
* [.getEventOptions(options)](#SimulateUser+getEventOptions) ⇒ <code>Object</code>
* [.querySelectorAll(query)](#SimulateUser+querySelectorAll) ⇒ [<code>Array.&lt;SimulateUser&gt;</code>](#SimulateUser)
* [.getElementById(id)](#SimulateUser+getElementById) ⇒ [<code>SimulateUser</code>](#SimulateUser) \| <code>null</code>
* [.getElementsByName(name)](#SimulateUser+getElementsByName) ⇒ [<code>Array.&lt;SimulateUser&gt;</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.&lt;String&gt;</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.&lt;String&gt;</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.&lt;undefined&gt;</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.&lt;undefined&gt;</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.&lt;\*&gt;</code>
### simulateUser.timeout(func, limit) ⇒ <code>Promise.&lt;\*&gt;</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.&lt;SimulateUser&gt;</code>
### simulateUser.querySelectorAll(query) ⇒ [<code>Array.&lt;SimulateUser&gt;</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.&lt;SimulateUser&gt;</code>
### simulateUser.getElementsByName(name) ⇒ [<code>Array.&lt;SimulateUser&gt;</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

@@ -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;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc