siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
174 lines (140 loc) • 6.83 kB
JavaScript
/*
Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license
*/
/**
@class Siesta.Test.UserAgent.Keyboard
This is a mixin, providing the keyboard events simulation functionality.
*/
Role('Siesta.Test.UserAgent.Keyboard', {
requires : [ 'normalizeElement', 'runPromiseAsync', 'activeElement' ],
does : [
Siesta.Util.Role.CanFormatStrings,
Siesta.Test.Browser.Role.CanWorkWithKeyboard
],
has : {
},
methods: {
/**
* This method will simulate keyboard typing on either a provided DOM element, or, if omitted, on the currently focuced DOM element.
* Simulation of certain special keys such as ENTER, ESC, LEFT etc is supported.
* You can type these special keys by using the all uppercase name the key inside square brackets: `[ENTER]`, `[BACKSPACE]`.
* See {@link Siesta.Test.UserAgent.KeyCodes} for a list of key names.
*
* For example:
*
t.type(el, 'Foo bar[ENTER]', function () {
...
})
*
* To type the `[ENTER]` as plain text and not as a special character - use double square brackets: `[[ENTER]]`
*
* To specify a control key like "shift/control/alt" of to be pressed during typing, use the `options` argument, for example:
t.type(el, 'Foo bar[ENTER]', callback, scope, { shiftKey : true, ctrlKey : true, altKey : true });
*
* This method returns a `Promise` which is resolved once the click has completed:
*
* t.type('#someEl', 'someText').then(function () {
* return t.type('#anotherEl', 'someText')
* }).then(function () {
* return t.type('#yetAnotherEl', 'someText')
* })
*
* See also {@link Siesta.Test#chain chain} method for slimer chaining notation.
*
* @param {Siesta.Test.ActionTarget} el The element to type into. If not provided, currently focused element will be used as target.
* @param {String} text The text to type, including any names of special keys in square brackets.
* @param {Function} callback A function to be called after the type operation is completed.
* @param {Object} scope The scope for the callback
* @param {Object} options (optional) any extra options used to configure the DOM key events (like holding shiftKey, ctrlKey, altKey etc).
* @param {Boolean} clearExisting (optional) true to clear existing text in the target before typing
*
* @return {Promise} Returns a promise resolved once the action has completed
*/
type : function (el, text, callback, scope, options, clearExisting, performTargetCheck) {
if (text == null) throw 'Must supply a string to type';
// Skip target check if user is simply targeting whatever is focused
if (!el) performTargetCheck = false;
el = el || this.activeElement();
var targetCheckPromise =
performTargetCheck !== false
?
this.waitForTargetAndSyncMousePosition(el, null, 'Type: ' + text, [], false, false)
:
Promise.resolve()
var me = this
return me.runPromiseAsync(targetCheckPromise.then(function () {
el = me.normalizeElement(el);
if (!el || el.disabled) {
return;
}
if (clearExisting) {
if ('value' in el) {
el.value = ''
}
// IE11 reports true for input´s `isContentEditable`, need to check this after 'value' check
else if (el.isContentEditable) {
el.innerHTML = ''
}
else {
// What's up here...?
}
}
var queue = new Siesta.Util.Queue({
deferer : me.originalSetTimeout,
deferClearer : me.originalClearTimeout,
interval : me.simulator.actionDelay,
callbackDelay : me.simulator.afterActionDelay,
observeTest : me
})
// Manually focus the element to type into first
queue.addStep({
processor : function () {
me.focus(el)
}
})
// focus the element one more time for IE - me seems to fix the weird sporadic failures in 042_keyevent_simulation3.t.js
// failures are caused by the field "blur" immediately after 1st focus
// no Ext "focus/blur" methods seems to be called, so it can be a browser behavior
bowser.msie && queue.addStep({
processor : function () {
me.focus(el)
}
})
queue.addStep({
isAsync : true,
processor : function (stepData) {
var promise = me.simulator.simulateType(text, options, { el : el })
me.runPromiseAsync(promise, '', stepData.next)
}
})
return new Promise(function (resolve, reject) {
queue.run(function () {
resolve()
})
})
}), 'type : `' + text + '`', callback, scope)
},
/**
* @param {Siesta.Test.ActionTarget} el
* @param {String} key
* @param {Object} options any extra options used to configure the DOM event. This argument can be omitted.
* @param {Function} callback A function to be called after the type operation is completed.
* @param {Object} scope The scope for the callback
*
* @return {Promise} Returns a promise resolved once the action has completed
*
* This method will simluate the key press, translated to the specified DOM element. It is generally exactly equivalent of
* typing a single character, special characters are supported in the same way as in {@link #type} method.
*/
keyPress: function (el, key, options, callback, scope) {
if (typeof options === 'function') {
callback = options;
options = undefined;
}
return this.type(el, key, callback, scope, options)
}
}
});