siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
300 lines (239 loc) • 10.5 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.SenchaTouch
@extends Siesta.Test.Browser
@mixin Siesta.Test.ExtJSCore
@mixin Siesta.Test.ExtJS.Observable
@mixin Siesta.Test.ExtJS.FormField
@mixin Siesta.Test.ExtJS.Component
@mixin Siesta.Test.ExtJS.Element
@mixin Siesta.Test.ExtJS.Store
A base class for testing Sencha Touch applications. It inherits from {@link Siesta.Test.Browser}
and adds various ST specific assertions.
This file is a reference only, for a getting start guide and manual, please refer to <a href="#!/guide/getting_started_browser">Siesta getting started in browser environment</a> guide.
*/
Class('Siesta.Test.SenchaTouch', {
isa : Siesta.Test.Browser,
does : [
Siesta.Test.ExtJSCore,
Siesta.Test.ExtJS.Component,
Siesta.Test.ExtJS.Element,
Siesta.Test.ExtJS.Observable,
Siesta.Test.ExtJS.Store,
Siesta.Test.ExtJS.Ajax,
Siesta.Test.ExtJS.FormField
],
has : {
performSetup : true,
isSTSetupDone : false,
moveCursorBetweenPoints : false
},
override : {
isReady : function () {
var result = this.SUPERARG(arguments);
var R = Siesta.Resource('Siesta.Test.SenchaTouch');
if (!result.ready) return result;
if (!this.parent && this.performSetup && !this.isSTSetupDone) return {
ready : false,
reason : R.get('STSetupFailed')
}
return {
ready : true
}
},
doStart : function () {
var me = this;
var Ext = this.getExt();
if (Ext) {
// execute "Ext.setup()" for top-level tests only
if (this.performSetup && !this.parent)
// calling before the SUPER, to possibly avoid waiting in "isReady" polling at all
// (since page can be already DOM ready)
Ext.setup({
onReady : function () {
me.isSTSetupDone = true
}
})
}
// calling SUPER to setup the loader paths, Ext.setup() will already do Ext.require
this.SUPERARG(arguments)
}
},
methods : {
initialize : function () {
// delete the possibly provided native simulator to force synthetic
if (!this.parent) this.simulator = null
this.SUPERARG(arguments)
},
// one of these methods feels redundant
getTouchBundlePath : function() {
var path;
var testDescriptor = this.project.getScriptDescriptor(this.url)
while (testDescriptor && !path) {
if (testDescriptor.preload) {
Joose.A.each(testDescriptor.preload, function (url) {
if (url.match && url.match(/(.*sencha-touch-\d\.\d+\.\d+.*?)\/sencha-touch(.*)\.js/)) {
path = url;
return false;
}
});
}
testDescriptor = testDescriptor.parent;
}
return path;
},
getTouchBundleFolder : function() {
var folder;
var testDescriptor = this.project.getScriptDescriptor(this.url)
while (testDescriptor && !folder) {
if (testDescriptor.preload) {
Joose.A.each(testDescriptor.preload, function (url) {
var regex = /(.*sencha-touch-\d\.\d+\.\d+.*?)\/sencha-touch(.*)\.js/;
var match = regex.exec(url);
if (match) {
folder = match[1];
}
});
}
testDescriptor = testDescriptor.parent;
}
return folder;
},
getExtBundleFolder : function() {
var folder;
this.project.mainPreset.eachResource(function (resource) {
var desc = resource.asDescriptor();
var regex = /(.*sencha-touch-\d\.\d+\.\d+.*?)\/sencha-touch-all(?:-debug)?\.js/;
var match = regex.exec(desc.url);
if (match) {
folder = match[1];
}
});
return folder;
},
/**
* This method will simulate a finger move to an xy-coordinate or an element (the center of it)
*
* @param {Siesta.Test.ActionTarget} target Target point to move the finger to.
* @param {Function} callback (optional) To run this method async, provide a callback method to be called after the operation is completed.
* @param {Object} scope (optional) the scope for the callback
* @param {Array} offset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or ["50%", "50%"] to click in the center.
*/
moveFingerTo : function(target, callback, scope, offset) {
this.moveCursorTo.apply(this, arguments);
},
/**
* This method will simulate a finger move from current position relative by the x and y distances provided.
*
* @param {Array} delta The delta offset to move the finger by.
* @param {Function} callback (optional) To run this method async, provide a callback method to be called after the operation is completed.
* @param {Object} scope (optional) the scope for the callback
*/
moveFingerBy : function(delta, callback, scope) {
if (!delta) {
var R = Siesta.Resource('Siesta.Test.SenchaTouch');
throw R.get('moveFingerByInvalidInput');
}
this.moveCursorBy.apply(this, arguments);
},
scrollUntil : function(target, direction, checkerFn, callback, scope) {
var me = this,
startDate = new Date(),
dir = direction;
var R = Siesta.Resource('Siesta.Test.SenchaTouch');
// Invert direction, Scroll up => Swipe down
switch(dir) {
case 'u':
case 'up':
direction = 'down';
break;
case 'd':
case 'down':
direction = 'up';
break;
case 'l':
case 'left':
direction = 'right';
break;
case 'r':
case 'right':
direction = 'left';
break;
default:
throw R.get('invalidSwipeDir') + ': ' + direction;
}
var inner = function() {
if (checkerFn.call(scope || me, target)) {
// We're done
me.processCallbackFromTest(callback, null, scope || me)
} else {
me.swipe(target, direction, function() {
if (new Date() - startDate < this.waitForTimeout) {
var as = me.beginAsync();
setTimeout(function() {
me.endAsync(as);
inner();
}, 1000);
} else {
me.fail(R.get('scrollUntilFailed'));
}
});
}
};
inner();
},
/**
* Waits until the supplied x&y scroll property has the passed value. You can test for either x or y, or both.
*
* @param {Ext.scroller.Scroller} scrollable The scroller instance
* @param {String} direction 'up', 'down', 'left' or 'right'
* @param {Siesta.Test.ActionTarget} actionTarget The target, either an element or a CSS selector normally.
* @param {Function} callback The callback to call
* @param {Object} scope The scope for the callback
*/
scrollUntilElementVisible : function(scrollable, direction, actionTarget, callback, scope) {
var me = this;
if (!actionTarget || !scrollable) {
var R = Siesta.Resource('Siesta.Test.SenchaTouch');
this.fail(R.get('scrollUntilElementVisibleInvalid'));
return;
}
this.scrollUntil(scrollable, direction, function() {
var element = me.normalizeElement(actionTarget, true);
return me.elementIsInView(element);
},
callback, scope);
},
/**
* Waits until the supplied x&y scroll property has the passed value. You can test for either x or y, or both.
*
* @param {Ext.scroller.Scroller} scroller The scroller instance
* @param {Object} position An object with an x, y, or x&y values. Ex. { x : 0 } or { x : 0, y : 200 }.
* @param {Int} value
* @param {Function} callback The callback to call
* @param {Object} scope The scope for the callback
* @param {Int} timeout The maximum amount of time to wait for the condition to be fulfilled. Defaults to the {@link Siesta.Test.ExtJS#waitForTimeout} value.
*/
waitForScrollerPosition: function(scroller, pos, callback, scope, timeout) {
return this.waitFor({
method : function() {
return (!('x' in pos) || pos.x === scroller.position.x) && (!('y' in pos) || pos.y === scroller.position.y);
},
callback : callback,
scope : scope,
timeout : timeout,
assertionName : 'waitForScrollerPosition',
description : ' ' + Siesta.Resource('Siesta.Test.SenchaTouch', 'scrollerReachPos') + ' '+ Siesta.Util.Serializer.stringify(pos)
});
},
areAnimationsRunning : function() {
var Ext = this.Ext();
return Ext && Ext.Anim && !Joose.O.isEmpty(Ext.Anim.running);
}
}
})