siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
334 lines (246 loc) • 14.1 kB
JavaScript
StartTest(function(t) {
if (typeof console === 'undefined') console = { log : function () {
} };
var isNativeFF = t.bowser.firefox && t.simulator.type == 'native'
t.it("After mouse interactions, the target el must be reevaluated", function (t) {
document.body.innerHTML =
'<div style="position:absolute; left: 5px; top: 5px; border:1px solid black;width:50px;height:50px" id="outer">' +
'<div style="background:#aaa;position:absolute;top:0;left:0;width:40px;height:40px" id="lvl1">' +
'</div>' +
'</div>';
var inner = document.getElementById('lvl1');
var outer = document.getElementById('outer');
outer.addEventListener('click', function(){ inner.style.display = 'none'; });
// DEBUGGING AID
// inner.on('mouseover', function(){ console.log('inner mouseover'); });
// inner.on('mouseout', function(){ console.log('inner mouseout'); });
// inner.on('mouseenter', function(){ console.log('inner mouseenter'); });
// inner.on('mouseleave', function(){ console.log('inner mouseleave'); });
// outer.on('mouseover', function(){ console.log('outer mouseover'); });
// outer.on('mouseenter', function(){ console.log('outer mouseenter'); });
// outer.on('mouseleave', function(){ console.log('outer mouseleave'); });
// The second mouseover is fired as part of the waitForTargetAndSyncMousePosition method
// called from the moveCursor to prepare for the actual action
t.willFireNTimes(inner, 'mouseover', 1, 'inner mouseover');
t.willFireNTimes(inner, 'mouseout', 1, 'inner mouseout');
t.willFireNTimes(inner, 'mouseenter', 1, 'inner mouseenter');
t.willFireNTimes(inner, 'mouseleave', 1, 'inner mouseleave');
// 2 events in native windows with Chrome for some reason (1 on linux)
t.willFireNTimes(outer, 'mouseenter', t.bowser.windows && t.bowser.blink && t.simulator.type == 'native' ? 2 :1, 'outer mouseenter');
t.chain(
{ click : '#outer' },
{ waitFor : 100 },
// Should trigger inner element 'mouseout' event + 'mouseleave' event (fired manually by Ext if browser doesn't support it)
{ action : 'moveCursor', by : [ 2, 0 ] }
);
})
t.it("After mousedown, we should fire mouseleave if target moved", function (t) {
t.chain(
{ setCursorPosition : [ 0, 0 ] },
function (next) {
document.body.innerHTML =
'<div style="position:absolute;top:0;left:10px;border:1px solid black;width:10px;height:10px" id="outer"></div>';
var outer = document.getElementById('outer');
outer.addEventListener('mousedown', function(){ outer.style.left = '20px'; });
// outer.addEventListener('mouseenter',function(e) {console.log(e.type, e.target) });
// outer.addEventListener('mouseleave',function(e) {console.log(e.type, e.target) });
t.willFireNTimes(outer, 'mouseenter', 1, 'outer mouseenter');
t.willFireNTimes(outer, 'mouseleave', isNativeFF ? 0 : 1, 'outer mouseleave');
next()
},
{ click : '#outer' }
);
})
t.it("After mouseup, we should fire mouseleave if target moved", function (t) {
t.chain(
{ setCursorPosition : [ 0, 0 ] },
function (next) {
// note, that we've changed the `top` position of the div, to be different from previous case
// otherwise tests fails in puppeteer with native events
// possibly if browser (chrome) performs setting of "innerHTML" with the same content
// it does some caching re-use, which, in combination with native events breaks something
document.body.innerHTML =
'<div style="position:absolute;top:10px;left:10px;border:1px solid black;width:10px;height:10px" id="outer"></div>';
var outer = document.getElementById('outer');
outer.addEventListener('mouseup', function(){ outer.style.left = '20px'; });
// outer.addEventListener('mouseenter', (e) => console.log(e.type, e.target) );
// outer.addEventListener('mouseleave', (e) => console.log(e.type, e.target));
t.willFireNTimes(outer, 'mouseenter', 1, 'outer mouseenter');
t.willFireNTimes(outer, 'mouseleave', isNativeFF ? 0 : 1, 'outer mouseleave');
next()
},
{ click : '#outer' }
);
})
t.it("After click, we should fire mouseleave if target moved", function (t) {
t.chain(
{ setCursorPosition : [ 0, 0 ] },
function (next) {
// see note above
document.body.innerHTML =
'<div style="position:absolute;top:20px;left:10px;border:1px solid black;width:10px;height:10px" id="outer"></div>';
var outer = document.getElementById('outer');
outer.addEventListener('click', function(){ outer.style.left = '20px'; });
// outer.addEventListener('mouseenter', (e) => console.log(e.type, e.target) );
// outer.addEventListener('mouseleave', (e) => console.log(e.type, e.target));
t.willFireNTimes(outer, 'mouseenter', 1, 'outer mouseenter');
t.willFireNTimes(outer, 'mouseleave', isNativeFF ? 0 : 1, 'outer mouseleave');
next()
},
{ click : '#outer' }
);
})
t.it("mouseenter should be fired for underlying (usually parent) elements too", function (t) {
document.body.innerHTML =
'<div style="position:absolute;top:0;left:50px; border:1px solid black;width:50px;height:50px" id="outer1">' +
'<div style="background:#aaa;position:absolute;top:0;left:0;width:40px;height:40px" id="inner1">' +
'</div>' +
'</div>';
var inner = document.getElementById('inner1');
var outer = document.getElementById('outer1');
t.chain(
{ moveCursorTo : [ 0, 0 ] },
function (next) {
t.willFireNTimes(outer, 'mouseenter', 1, 'outer mouseenter');
t.willFireNTimes(inner, 'mouseenter', 1, 'inner mouseenter');
next()
},
{ moveCursorTo : '#inner1' }
);
})
t.it("should fire mouseleave if target moved after drag -> mouseup", function (t) {
t.chain(
{ moveCursorTo : [1,1]},
function (next) {
document.body.innerHTML =
'<div style="position:absolute;top:0;left:50px;border:1px solid black;width:100px;height:100px" id="outer"></div>';
var outer = document.getElementById('outer');
outer.addEventListener('mouseup', function(){
outer.style.left = '200px';
});
// outer.addEventListener('mouseenter', (e) => console.log(e.type, e.target) );
// outer.addEventListener('mouseleave', (e) => console.log(e.type, e.target));
// document.body.addEventListener('mouseover', (e) => {console.log(e.type, e.target);});
t.willFireNTimes(outer, 'mouseenter', 1, 'outer mouseenter');
t.willFireNTimes(outer, 'mouseleave', isNativeFF ? 0 : 1, 'outer mouseleave');
// NOTE: Firefox doesn't fire mouseover after the DIV is moved, Chrome does
// 1 mouseover is 'outer' bubbling
// 1 mouseover is when 'outer' is removed
t.willFireNTimes(document.body, 'mouseover', isNativeFF ? 1 : 2, 'body mouseover');
next()
},
{ drag : [1,1], to : '#outer' }
);
})
t.it("should fire mouseleave if target was removed from DOM after mouseup", function (t) {
t.chain(
{ moveCursorTo : [1,1]},
function (next) {
document.body.innerHTML =
'<div style="position:absolute;top:0;left:10px;border:1px solid black;width:10px;height:10px" id="outer"></div>';
var outer = document.getElementById('outer');
outer.addEventListener('mouseup', function(){
outer.parentElement.removeChild(outer);
});
// outer.addEventListener('mouseenter', function(e) {
// console.log(e.type, e.target);
// // debugger
// });
// outer.addEventListener('mouseleave', function (e) {
// console.log(e.type, e.target)
// // debugger
// });
// outer.addEventListener('mouseout', function (e) {
// console.log(e.type, e.target)
// // debugger
// });
// document.body.addEventListener('mouseover', function(e) {
// // debugger
// console.log(e.type, e.target)
// });
t.willFireNTimes(outer, 'mouseenter', 1, 'outer mouseenter');
t.willFireNTimes(outer, 'mouseout', 0, 'outer mouseout not fired');
t.willFireNTimes(outer, 'mouseleave', 0, 'outer mouseleave');
// NOTE: Firefox doesn't fire mouseover after the DIV is moved, Chrome does
// 1 mouseover is 'outer' bubbling
// 1 mouseover is when 'outer' is removed
t.willFireNTimes(document.body, 'mouseover', 2, 'body mouseover');
next()
},
{ click : '#outer' }
);
})
t.it("should fire mouseout/mouseover when dragging target that hides on mousedown and reappears after mouseup", function (t) {
var inner, outer, innerContent
t.chain(
{ moveCursorTo : [ 1, 1 ] },
function (next) {
document.body.innerHTML =
'<div style="position:absolute;top:0;left:100px;border:1px solid black;width:100px;height:100px;" id="outer">' +
'<div style="position:absolute;top:40px;left:40px;border:1px solid green;width:40px;height:40px;" id="inner">' +
'<div style="margin:5px;background:red;width:80%;height:80%" id="inner-content">' +
'BLARGH' +
'</div>' +
'</div>' +
'</div>';
inner = document.getElementById('inner');
outer = document.getElementById('outer');
innerContent = document.getElementById('inner-content');
t.$(inner).mousedown(function () {
if (t.bowser.linux)
inner.style.display = 'none';
else
inner.style.visibility = 'hidden';
});
t.$(document.body).mouseup(function (e) {
if (t.bowser.linux)
inner.style.display = 'block';
else
inner.style.visibility = '';
});
// document.body.addEventListener('mousemove', (e)=>{console.log(e.type, e.target)});
// document.body.addEventListener('mouseover', (e)=>{console.log(e.type, e.target)});
// document.body.addEventListener('mouseout', (e)=>{console.log(e.type, e.target)});
// document.body.addEventListener('mouseenter', (e)=>{console.log(e.type, e.target)});
// document.body.addEventListener('mouseleave', (e)=>{console.log(e.type, e.target)});
// document.body.addEventListener('mousedown', (e)=>{console.log(e.type, e.target)});
// document.body.addEventListener('mouseup', (e)=>{console.log(e.type, e.target)});
// document.body.addEventListener('click', (e)=>{console.log(e.type, e.target)});
t.willFireNTimes(innerContent, 'mouseout', 1, 'inner is mouseout');
next()
},
{ drag : '#inner', by : [ 5, 0 ], dragOnly : true },
function (next) {
t.willFireNTimes(outer, 'mouseout', 1, 'outer mouseout fired');
t.willFireNTimes(inner, 'mouseover', 1, 'inner mouseover fired');
next()
},
{ mouseUp : null }
);
})
t.it("Should support moving mouse to SVG element and clicking it", function (t) {
document.body.innerHTML =
'<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 3 2">' +
' <rect width="1" height="2" x="0" fill="#008d46" />' +
' <rect width="1" height="2" x="1" fill="#ffffff" />' +
' <rect width="1" height="2" x="2" fill="#d2232c" />' +
'</svg>';
//
// The second mouseover is fired as part of the waitForTargetAndSyncMousePosition method
// called from the moveCursor to prepare for the actual action
var firstRect = document.querySelector('svg > rect');
t.willFireNTimes(firstRect, 'mouseover', 1);
t.willFireNTimes(firstRect, 'mouseout', 1);
t.willFireNTimes(firstRect, 'mouseenter', 1);
t.willFireNTimes(firstRect, 'mouseleave', 1);
t.willFireNTimes(firstRect, 'mousedown', 1);
t.willFireNTimes(firstRect, 'mouseup', 1);
t.willFireNTimes(firstRect, 'click', 1);
t.chain(
{ moveCursorTo : 'rect'},
{ click : 'rect'},
// Should trigger inner element 'mouseout' event + 'mouseleave' event (fired manually by Ext if browser doesn't support it)
{ action : 'moveCursor', to : [ 2, 150 ] }
);
})
});