siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
279 lines (216 loc) • 10 kB
JavaScript
/*
Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license
*/
Singleton('Siesta.Project.Browser.FeatureSupport', {
does : [
Siesta.Util.Role.CanCalculatePageScroll
],
has : {
isConfigured : false,
supports : Joose.I.Object,
simulator : {
lazy : 'this.buildWebSimulator'
},
tests : {
init : [
{
id : 'TouchEvents',
fn : function() {
return this.isEventSupported('touchend', window);
}
},
{
id : 'PointerEvents',
fn : function () {
return Boolean(window.PointerEvent)
}
},
{
id : 'MSPointerEvents',
fn : function() {
return Boolean(window.MSPointerEvent)
}
},
{
id : 'PointerEventsGeneric',
fn : function () {
return Boolean(window.PointerEvent || window.MSPointerEvent)
}
},
// "fn"s are called as methods of the "Siesta.Project.Browser.FeatureSupport" singleton
{
id : "mouseEnterLeave",
fn : function() {
var el = document.createElement("div");
return 'onmouseenter' in el && 'onmouseleave' in el;
}
},
{
id : "enterOnAnchorTriggersClick",
fn : function() {
var sim = this.getSimulator(),
E = Siesta.Test.UserAgent.KeyCodes().keys.ENTER,
result = false;
var anchor = $('<a href="foo" style="display:none">test me</a>');
$('body').append(anchor);
anchor.focus({ preventScroll : true });
anchor.click(function(e) {
result = true;
return false;
});
sim.simulateEvent(anchor, 'keypress', { keyCode : E, charCode : 0 });
anchor.remove();
return result;
}
},
{
id : "canSimulateKeyCharacters",
fn : function() {
var sim = this.getSimulator();
var input = $('<input class="siesta-hidden" type="text" />'),
A = Siesta.Test.UserAgent.KeyCodes().keys.A;
$('body').append(input);
input.focus({ preventScroll : true });
sim.simulateEvent(input, 'keypress', { keyCode : A, charCode : A });
sim.simulateEvent(input, 'textInput', { text : "A" });
var result = input.val() === 'A';
input.remove();
return result;
}
},
{
id : "canSimulateBackspace",
fn : function() {
var sim = this.getSimulator();
var input = $('<input class="siesta-hidden" type="text" />'),
BS = Siesta.Test.UserAgent.KeyCodes().keys.BACKSPACE,
A = Siesta.Test.UserAgent.KeyCodes().keys.A;
$('body').append(input);
input.focus({ preventScroll : true });
sim.simulateEvent(input, 'keypress', { keyCode : A, charCode : A });
sim.simulateEvent(input, 'keypress', { keyCode : A, charCode : A });
sim.simulateEvent(input, 'keypress', { keyCode : BS, charCode : BS });
var result = input.val() === 'A';
input.remove();
return result;
}
},
{
id : "enterSubmitsForm",
fn : function() {
var sim = this.getSimulator(),
E = Siesta.Test.UserAgent.KeyCodes().keys.ENTER,
result = false;
var form = $('<form method="post"><input type="text"/></form>');
var input = $(form).find('input');
$('body').append(form);
form[0].onsubmit = function(e) {
result = true;
return false;
};
input.focus({ preventScroll : true });
sim.simulateEvent(input, 'keypress', { keyCode : E, charCode : 0 });
form.remove();
return result;
}
},
// remove after https://bugzilla.mozilla.org/show_bug.cgi?id=959992 will be fixed
{
id : "imageWithIdCreatesGlobalEnumerable",
fn : function () {
var img = $('<img id="test_img_id"/>');
$('body').append(img);
var hasImgId = false
for (var i in window) {
if (i == 'test_img_id') hasImgId = true
}
img.remove();
return hasImgId;
}
},
// Safari triggers native 'change' event when an INPUT is blurred
{
id : "inputFiresChangeAfterLosingFocus",
fn : function() {
var sim = this.getSimulator();
var input = document.createElement('input'),
result = false,
A = Siesta.Test.UserAgent.KeyCodes().keys.A;
input.className = "siesta-hidden";
document.body.appendChild(input);
input.addEventListener('change', function (ev) {
result = ev.isTrusted;
});
input.focus({ preventScroll : true });
sim.simulateEvent(input, 'keydown', { keyCode : A, charCode : A });
sim.simulateEvent(input, 'keypress', { keyCode : A, charCode : A });
sim.simulateEvent(input, 'keyup', { keyCode : A, charCode : A });
sim.simulateEvent(input, 'textInput', { text : "A" });
input.blur();
document.body.removeChild(input);
return result;
}
}
]
}
},
methods : {
buildWebSimulator : function () {
return new Siesta.Test.Simulator({
global : window,
test : {
normalizeElement : function(a) { return a[ 0 ] || a; }
}
});
},
configure : function() {
// Already configured
if (this.isConfigured) return
this.isConfigured = true
this.maintainScrollPositionDuring(function () {
for (var i = 0; i < this.tests.length; i++) {
var test = this.tests[i];
var testId = test.id;
var detectorFn = test.fn;
try {
// also save the results to "results" property - we'll use this in our own test suite
// where we copy the feature testing results from the outer scope to inner
this.supports[ testId ] = detectorFn.call(this);
} catch (e) {
this.supports[ testId ] = false
}
}
})
},
// from Modernizr
isEventSupported: function (eventName, element) {
var isSupported;
if (!eventName) return false
if (!element || typeof element === 'string') element = document.createElement(element || 'div');
// Testing via the `in` operator is sufficient for modern browsers and IE.
// When using `setAttribute`, IE skips "unload", WebKit skips "unload" and
// "resize", whereas `in` "catches" those.
eventName = 'on' + eventName;
isSupported = eventName in element;
// Fallback technique for old Firefox - bit.ly/event-detection
if (!isSupported) {
if (!element.setAttribute) {
// Switch to generic element if it lacks `setAttribute`.
// It could be the `document`, `window`, or something else.
element = document.createElement('div');
}
element.setAttribute(eventName, '');
isSupported = typeof element[ eventName ] === 'function';
if (element[ eventName ] !== undefined ) {
// If property was created, "remove it" by setting value to `undefined`.
element[ eventName ] = undefined;
}
element.removeAttribute(eventName);
}
return isSupported;
}
}
})