siesta 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/controllers/siesta/siesta_controller.rb +1 -1
- data/app/helpers/siesta/application_helper.rb +2 -2
- data/config/routes.rb +1 -1
- data/lib/siesta/test_suite.rb +3 -3
- data/lib/siesta/version.rb +1 -1
- data/vendor/assets/images/siesta/resources/images/trigger-groups.gif +0 -0
- data/vendor/assets/images/siesta/resources/images/trigger-leafs.gif +0 -0
- data/vendor/assets/javascripts/siesta/siesta-all.js +2144 -494
- data/vendor/assets/javascripts/siesta/siesta-nodejs-all.js +538 -138
- data/vendor/assets/javascripts/siesta/siesta-touch-all.js +1325 -449
- data/vendor/assets/stylesheets/siesta/resources/css/siesta-all.css +22 -2
- data/vendor/assets/stylesheets/siesta/resources/css/siesta-touch-all.css +1 -1
- metadata +1243 -1241
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
|
3
|
-
Siesta 1.1.
|
3
|
+
Siesta 1.1.5
|
4
4
|
Copyright(c) 2009-2012 Bryntum AB
|
5
5
|
http://bryntum.com/contact
|
6
6
|
http://bryntum.com/products/siesta/license
|
@@ -6114,7 +6114,9 @@ Class('Siesta.Content.Manager', {
|
|
6114
6114
|
require : true
|
6115
6115
|
},
|
6116
6116
|
|
6117
|
-
urls : Joose.I.Object
|
6117
|
+
urls : Joose.I.Object,
|
6118
|
+
|
6119
|
+
maxLoads : 5
|
6118
6120
|
},
|
6119
6121
|
|
6120
6122
|
|
@@ -6142,29 +6144,42 @@ Class('Siesta.Content.Manager', {
|
|
6142
6144
|
var errorCount = 0
|
6143
6145
|
|
6144
6146
|
var total = 0
|
6145
|
-
|
6147
|
+
var urlsArray = []
|
6148
|
+
Joose.O.each(urls, function (value, url) { total++; urlsArray.push(url) })
|
6146
6149
|
|
6147
|
-
if (total)
|
6148
|
-
|
6150
|
+
if (total) {
|
6151
|
+
|
6152
|
+
var loadSingle = function (url) {
|
6153
|
+
if (!url) return
|
6149
6154
|
|
6150
6155
|
me.load(url, function (content) {
|
6151
6156
|
if (errorCount) return
|
6152
6157
|
|
6153
6158
|
urls[ url ] = content
|
6154
6159
|
|
6155
|
-
if (++loadCount == total)
|
6160
|
+
if (++loadCount == total)
|
6161
|
+
callback && callback()
|
6162
|
+
else
|
6163
|
+
loadSingle(urlsArray.shift())
|
6156
6164
|
|
6157
6165
|
}, ignoreErrors ? function () {
|
6158
6166
|
|
6159
|
-
if (++loadCount == total)
|
6167
|
+
if (++loadCount == total)
|
6168
|
+
callback && callback()
|
6169
|
+
else
|
6170
|
+
loadSingle(urlsArray.shift())
|
6160
6171
|
|
6161
6172
|
} : function () {
|
6162
6173
|
errorCount++
|
6163
6174
|
|
6164
6175
|
errback && errback(url)
|
6165
6176
|
})
|
6166
|
-
}
|
6167
|
-
|
6177
|
+
}
|
6178
|
+
|
6179
|
+
// running only `maxLoads` "loading threads" at the same time
|
6180
|
+
for (var i = 0; i < this.maxLoads; i++) loadSingle(urlsArray.shift())
|
6181
|
+
|
6182
|
+
} else
|
6168
6183
|
callback && callback()
|
6169
6184
|
},
|
6170
6185
|
|
@@ -6206,6 +6221,8 @@ Class('Siesta.Result.Diagnostic', {
|
|
6206
6221
|
isa : Siesta.Result,
|
6207
6222
|
|
6208
6223
|
has : {
|
6224
|
+
isWarning : false,
|
6225
|
+
|
6209
6226
|
isSimulatedEvent : false,
|
6210
6227
|
|
6211
6228
|
// Used by simulated events
|
@@ -6217,8 +6234,7 @@ Class('Siesta.Result.Diagnostic', {
|
|
6217
6234
|
methods : {
|
6218
6235
|
|
6219
6236
|
toString : function () {
|
6220
|
-
|
6221
|
-
return message;
|
6237
|
+
return '# ' + this.description
|
6222
6238
|
}
|
6223
6239
|
}
|
6224
6240
|
});
|
@@ -6400,6 +6416,7 @@ Role('Siesta.Test.More', {
|
|
6400
6416
|
'onload',
|
6401
6417
|
'onerror',
|
6402
6418
|
'StartTest',
|
6419
|
+
'startTest',
|
6403
6420
|
// will be reported in IE8 after overriding
|
6404
6421
|
'setTimeout',
|
6405
6422
|
'clearTimeout'
|
@@ -6636,7 +6653,7 @@ Role('Siesta.Test.More', {
|
|
6636
6653
|
|
6637
6654
|
desc = desc || 'throwsOk';
|
6638
6655
|
|
6639
|
-
var e = this.
|
6656
|
+
var e = this.getExceptionCatcher()(func)
|
6640
6657
|
|
6641
6658
|
// assuming no one will throw undefined exception..
|
6642
6659
|
if (e === undefined) {
|
@@ -6648,7 +6665,7 @@ Role('Siesta.Test.More', {
|
|
6648
6665
|
return
|
6649
6666
|
}
|
6650
6667
|
|
6651
|
-
if (e instanceof this.
|
6668
|
+
if (e instanceof this.getTestErrorClass())
|
6652
6669
|
//IE uses non-standard 'description' property for error msg
|
6653
6670
|
e = e.message || e.description
|
6654
6671
|
|
@@ -6703,7 +6720,7 @@ Role('Siesta.Test.More', {
|
|
6703
6720
|
func = [ desc, desc = func][ 0 ]
|
6704
6721
|
}
|
6705
6722
|
|
6706
|
-
var e = this.
|
6723
|
+
var e = this.getExceptionCatcher()(func)
|
6707
6724
|
|
6708
6725
|
if (e === undefined)
|
6709
6726
|
this.pass(desc)
|
@@ -6892,9 +6909,9 @@ Role('Siesta.Test.More', {
|
|
6892
6909
|
*
|
6893
6910
|
* This method has a synonym with singular name: `expectGlobal`
|
6894
6911
|
*
|
6895
|
-
* @param {String} name1 The name of global property
|
6896
|
-
* @param {String} name2 The name of global property
|
6897
|
-
* @param {String} nameN The name of global property
|
6912
|
+
* @param {String/RegExp} name1 The name of global property or the regular expression to match several properties
|
6913
|
+
* @param {String/RegExp} name2 The name of global property or the regular expression to match several properties
|
6914
|
+
* @param {String/RegExp} nameN The name of global property or the regular expression to match several properties
|
6898
6915
|
*/
|
6899
6916
|
expectGlobals : function () {
|
6900
6917
|
this.expectedGlobals.push.apply(this.expectedGlobals, arguments)
|
@@ -6908,9 +6925,9 @@ Role('Siesta.Test.More', {
|
|
6908
6925
|
*
|
6909
6926
|
* You can enable this assertion to automatically happen at the end of each test, using {@link Siesta.Harness#autoCheckGlobals autoCheckGlobals} option of the harness.
|
6910
6927
|
*
|
6911
|
-
* @param {String} name1 The name of global property
|
6912
|
-
* @param {String} name2 The name of global property
|
6913
|
-
* @param {String} nameN The name of global property
|
6928
|
+
* @param {String/RegExp} name1 The name of global property or the regular expression to match several properties
|
6929
|
+
* @param {String/RegExp} name2 The name of global property or the regular expression to match several properties
|
6930
|
+
* @param {String/RegExp} nameN The name of global property or the regular expression to match several properties
|
6914
6931
|
*/
|
6915
6932
|
verifyGlobals : function () {
|
6916
6933
|
if (this.disableGlobalsCheck) {
|
@@ -6922,16 +6939,33 @@ Role('Siesta.Test.More', {
|
|
6922
6939
|
this.expectGlobals.apply(this, arguments)
|
6923
6940
|
|
6924
6941
|
var me = this
|
6925
|
-
var
|
6926
|
-
var
|
6942
|
+
var expectedStrings = {}
|
6943
|
+
var expectedRegExps = []
|
6927
6944
|
|
6928
|
-
Joose.A.each(this.expectedGlobals.concat(this.browserGlobals), function (
|
6945
|
+
Joose.A.each(this.expectedGlobals.concat(this.browserGlobals), function (value) {
|
6946
|
+
if (me.typeOf(value) == 'RegExp')
|
6947
|
+
expectedRegExps.push(value)
|
6948
|
+
else
|
6949
|
+
expectedStrings[ value ] = true
|
6950
|
+
})
|
6929
6951
|
|
6930
6952
|
this.diag('Global variables')
|
6931
6953
|
|
6954
|
+
var failed = false
|
6955
|
+
|
6932
6956
|
for (var name in this.global) {
|
6957
|
+
if (expectedStrings[ name ]) continue
|
6933
6958
|
|
6934
|
-
|
6959
|
+
var isExpected = false
|
6960
|
+
|
6961
|
+
for (var i = 0; i < expectedRegExps.length; i++) {
|
6962
|
+
if (expectedRegExps[ i ].test(name)) {
|
6963
|
+
isExpected = true
|
6964
|
+
break
|
6965
|
+
}
|
6966
|
+
}
|
6967
|
+
|
6968
|
+
if (!isExpected) {
|
6935
6969
|
me.fail('Unexpected global found', 'Global name: ' + name + ', value: ' + Siesta.Util.Serializer.stringify(this.global[name]))
|
6936
6970
|
|
6937
6971
|
failed = true
|
@@ -6968,7 +7002,7 @@ Role('Siesta.Test.More', {
|
|
6968
7002
|
else
|
6969
7003
|
this.fail(desc, annotation, result);
|
6970
7004
|
},
|
6971
|
-
|
7005
|
+
|
6972
7006
|
|
6973
7007
|
/**
|
6974
7008
|
* Waits for passed checker method to return true (or any non-false value, like for example DOM element or array), and calls the callback when this happens.
|
@@ -6980,8 +7014,9 @@ Role('Siesta.Test.More', {
|
|
6980
7014
|
* @param {Function} callback A function to call when the condition has been met. Will receive a result from checker function.
|
6981
7015
|
* @param {Object} scope The scope for the callback
|
6982
7016
|
* @param {Int} timeout The maximum amount of time (in milliseconds) to wait for the condition to be fulfilled. Defaults to the {@link Siesta.Test.ExtJS#waitForTimeout} value.
|
7017
|
+
* @param {Int} interval The polling interval (in milliseconds)
|
6983
7018
|
*/
|
6984
|
-
waitFor : function (method, callback, scope, timeout) {
|
7019
|
+
waitFor : function (method, callback, scope, timeout, interval) {
|
6985
7020
|
var description = this.typeOf(method) == 'Number' ? (method + ' ms') : ' condition to be fullfilled';
|
6986
7021
|
var assertionName = 'waitFor';
|
6987
7022
|
|
@@ -6992,11 +7027,17 @@ Role('Siesta.Test.More', {
|
|
6992
7027
|
callback = options.callback;
|
6993
7028
|
scope = options.scope;
|
6994
7029
|
timeout = options.timeout;
|
7030
|
+
interval = options.interval
|
7031
|
+
|
6995
7032
|
description = options.description;
|
6996
7033
|
assertionName = options.assertionName || assertionName;
|
7034
|
+
|
6997
7035
|
}
|
6998
7036
|
|
6999
|
-
|
7037
|
+
interval = interval || this.waitForPollInterval
|
7038
|
+
timeout = timeout || this.waitForTimeout
|
7039
|
+
|
7040
|
+
var async = this.beginAsync(timeout + 2 * interval),
|
7000
7041
|
me = this;
|
7001
7042
|
|
7002
7043
|
var sourceLine = me.getSourceLine();
|
@@ -7015,13 +7056,12 @@ Role('Siesta.Test.More', {
|
|
7015
7056
|
if (this.typeOf(method) == 'Number') {
|
7016
7057
|
pollTimeout = originalSetTimeout(function() {
|
7017
7058
|
me.endAsync(async);
|
7018
|
-
|
7059
|
+
me.processCallbackFromTest(callback, [], scope || me)
|
7060
|
+
|
7019
7061
|
}, method);
|
7020
7062
|
|
7021
7063
|
me.finalizeWaiting(waitAssertion, true, 'Waited ' + method + ' ms');
|
7022
7064
|
} else {
|
7023
|
-
|
7024
|
-
timeout = timeout || this.waitForTimeout
|
7025
7065
|
|
7026
7066
|
var startDate = new Date()
|
7027
7067
|
|
@@ -7058,9 +7098,10 @@ Role('Siesta.Test.More', {
|
|
7058
7098
|
me.endAsync(async);
|
7059
7099
|
|
7060
7100
|
me.finalizeWaiting(waitAssertion, true, 'Waited ' + time + ' ms for ' + description);
|
7061
|
-
|
7101
|
+
|
7102
|
+
me.processCallbackFromTest(callback, [ result ], scope || me)
|
7062
7103
|
} else
|
7063
|
-
pollTimeout = originalSetTimeout(pollFunc,
|
7104
|
+
pollTimeout = originalSetTimeout(pollFunc, interval)
|
7064
7105
|
}
|
7065
7106
|
|
7066
7107
|
pollFunc()
|
@@ -7072,8 +7113,8 @@ Role('Siesta.Test.More', {
|
|
7072
7113
|
// returns "true" if "next" is used,
|
7073
7114
|
analyzeChainStep : function (func) {
|
7074
7115
|
var sources = func.toString()
|
7075
|
-
var firstArg = sources.match(/function\s*[^(]*\((.*?)(?:,|\))/)[ 1 ]
|
7076
|
-
|
7116
|
+
var firstArg = sources.match(/function\s*[^(]*\(\s*(.*?)\s*(?:,|\))/)[ 1 ]
|
7117
|
+
|
7077
7118
|
if (!firstArg) return false
|
7078
7119
|
|
7079
7120
|
var body = sources.match(/\{([\s\S]*)\}/)[ 1 ]
|
@@ -7158,11 +7199,13 @@ Role('Siesta.Test.More', {
|
|
7158
7199
|
observeTest : this
|
7159
7200
|
})
|
7160
7201
|
|
7202
|
+
var sourceLine = me.getSourceLine();
|
7203
|
+
|
7161
7204
|
// inline any arrays in the arguments into one array
|
7162
|
-
var steps
|
7205
|
+
var steps = Array.prototype.concat.apply([], arguments)
|
7163
7206
|
|
7164
|
-
var len
|
7165
|
-
var args
|
7207
|
+
var len = steps.length
|
7208
|
+
var args = []
|
7166
7209
|
|
7167
7210
|
Joose.A.each(steps, function (step, index) {
|
7168
7211
|
|
@@ -7170,10 +7213,29 @@ Role('Siesta.Test.More', {
|
|
7170
7213
|
|
7171
7214
|
queue.addAsyncStep({
|
7172
7215
|
processor : function (data) {
|
7173
|
-
var
|
7216
|
+
var isWaitStep = step.action == 'wait' || step.waitFor
|
7217
|
+
|
7218
|
+
if (!isWaitStep) {
|
7219
|
+
var timeout = step.timeout || me.defaultTimeout
|
7220
|
+
|
7221
|
+
// + 100 to allow `waitFor` steps (which will be waiting the `timeout` time) to
|
7222
|
+
// generate their own failures
|
7223
|
+
var async = me.beginAsync(timeout + 100, function () {
|
7224
|
+
me.fail(
|
7225
|
+
'The step in `t.chain()` call did not complete within required timeframe, chain can not proceed',
|
7226
|
+
{
|
7227
|
+
sourceLine : sourceLine,
|
7228
|
+
annotation : 'Step number: ' + (index + 1) + ' (1-based)' + (sourceLine ? '\nAt line : ' + sourceLine : ''),
|
7229
|
+
ownTextOnly : true
|
7230
|
+
}
|
7231
|
+
)
|
7232
|
+
|
7233
|
+
return true
|
7234
|
+
})
|
7235
|
+
}
|
7174
7236
|
|
7175
7237
|
var nextFunc = function () {
|
7176
|
-
me.endAsync(async)
|
7238
|
+
if (!isWaitStep) me.endAsync(async)
|
7177
7239
|
|
7178
7240
|
args = Array.prototype.slice.call(arguments);
|
7179
7241
|
|
@@ -7194,9 +7256,23 @@ Role('Siesta.Test.More', {
|
|
7194
7256
|
// and finalize the async frame manually, as the "nextFunc" for last step will never be called
|
7195
7257
|
isLast && me.endAsync(async)
|
7196
7258
|
|
7259
|
+
} else if (me.typeOf(step) == 'String') {
|
7260
|
+
var action = new Siesta.Test.Action.Eval({
|
7261
|
+
actionString : step,
|
7262
|
+
next : nextFunc,
|
7263
|
+
test : me
|
7264
|
+
})
|
7265
|
+
|
7266
|
+
action.process()
|
7267
|
+
|
7197
7268
|
} else {
|
7198
7269
|
if (!step.args) step.args = args
|
7199
7270
|
|
7271
|
+
// Don't pass target to next step if it is a waitFor action, it does not make sense and messes up the arguments
|
7272
|
+
if (!isLast && (steps[ index + 1 ].waitFor || steps[ index + 1 ].action == 'wait')) {
|
7273
|
+
step.passTargetToNext = false;
|
7274
|
+
}
|
7275
|
+
|
7200
7276
|
step.next = nextFunc
|
7201
7277
|
step.test = me
|
7202
7278
|
|
@@ -7303,6 +7379,9 @@ Class('Siesta.Test', {
|
|
7303
7379
|
results : Joose.I.Array,
|
7304
7380
|
|
7305
7381
|
run : { required : true },
|
7382
|
+
startTestAnchor : null,
|
7383
|
+
exceptionCatcher : null,
|
7384
|
+
testErrorClass : null,
|
7306
7385
|
|
7307
7386
|
harness : { required : true },
|
7308
7387
|
|
@@ -7428,9 +7507,16 @@ Class('Siesta.Test', {
|
|
7428
7507
|
* @return {Object} Object with properties `{ ready : true/false, reason : 'description' }`
|
7429
7508
|
*/
|
7430
7509
|
isReady: function() {
|
7510
|
+
// this should allow us to wait until the presense of "run" function
|
7511
|
+
// it will become available after call to StartTest method
|
7512
|
+
// which some users may call asynchronously, after some delay
|
7513
|
+
// see https://www.assembla.com/spaces/bryntum/tickets/379
|
7514
|
+
// in this case test can not be configured using object as 1st argument for StartTest
|
7515
|
+
this.run = this.run || this.getStartTestAnchor().args && this.getStartTestAnchor().args[ 0 ]
|
7516
|
+
|
7431
7517
|
return {
|
7432
|
-
ready :
|
7433
|
-
reason : ''
|
7518
|
+
ready : this.typeOf(this.run) == 'Function',
|
7519
|
+
reason : 'No code provided to test'
|
7434
7520
|
}
|
7435
7521
|
},
|
7436
7522
|
|
@@ -7561,7 +7647,7 @@ Class('Siesta.Test', {
|
|
7561
7647
|
var gotDesc = params.gotDesc || 'Got'
|
7562
7648
|
var needDesc = params.needDesc || 'Need'
|
7563
7649
|
|
7564
|
-
if (assertionName || sourceLine) strings.push(
|
7650
|
+
if (!params.ownTextOnly && (assertionName || sourceLine)) strings.push(
|
7565
7651
|
'Failed assertion ' + (assertionName ? '[' + assertionName + '] ' : '') + this.formatSourceLine(sourceLine)
|
7566
7652
|
)
|
7567
7653
|
|
@@ -7630,23 +7716,83 @@ Class('Siesta.Test', {
|
|
7630
7716
|
},
|
7631
7717
|
|
7632
7718
|
|
7719
|
+
getStartTestAnchor : function () {
|
7720
|
+
return this.startTestAnchor
|
7721
|
+
},
|
7722
|
+
|
7723
|
+
|
7724
|
+
getExceptionCatcher : function () {
|
7725
|
+
return this.exceptionCatcher
|
7726
|
+
},
|
7727
|
+
|
7728
|
+
|
7729
|
+
getTestErrorClass : function () {
|
7730
|
+
return this.testErrorClass
|
7731
|
+
},
|
7732
|
+
|
7733
|
+
|
7734
|
+
processCallbackFromTest : function (callback, args, scope) {
|
7735
|
+
var me = this
|
7736
|
+
|
7737
|
+
if (this.transparentEx) {
|
7738
|
+
callback.apply(scope || this.global, args || [])
|
7739
|
+
} else {
|
7740
|
+
var e = this.getExceptionCatcher()(function(){
|
7741
|
+
callback.apply(scope || me.global, args || [])
|
7742
|
+
})
|
7743
|
+
|
7744
|
+
if (e) {
|
7745
|
+
this.failWithException(e)
|
7746
|
+
|
7747
|
+
// flow should be interrupted - exception detected
|
7748
|
+
return false
|
7749
|
+
}
|
7750
|
+
}
|
7751
|
+
|
7752
|
+
// flow can be continued
|
7753
|
+
return true
|
7754
|
+
},
|
7755
|
+
|
7756
|
+
|
7633
7757
|
getStackTrace : function (e) {
|
7634
7758
|
if (Object(e) !== e) return null
|
7635
7759
|
if (!e.stack) return null
|
7636
7760
|
|
7637
|
-
var text = e.stack
|
7638
|
-
var
|
7761
|
+
var text = e.stack + '';
|
7762
|
+
var isFirefox = /^@/.test(text)
|
7763
|
+
var lines = text.split('\n')
|
7764
|
+
|
7765
|
+
var result = []
|
7639
7766
|
var match
|
7640
7767
|
|
7641
|
-
var
|
7768
|
+
for (var i = 0; i < lines.length; i++) {
|
7769
|
+
if (!lines[ i ]) continue
|
7770
|
+
|
7771
|
+
if (!i) {
|
7772
|
+
if (isFirefox)
|
7773
|
+
result.push(e + '')
|
7774
|
+
else {
|
7775
|
+
result.push(lines[ i ])
|
7776
|
+
continue;
|
7777
|
+
}
|
7778
|
+
}
|
7642
7779
|
|
7643
|
-
|
7644
|
-
|
7645
|
-
|
7646
|
-
|
7647
|
-
|
7648
|
-
|
7649
|
-
result.push(
|
7780
|
+
if (isFirefox) {
|
7781
|
+
match = /@(.*?):(\d+)/.exec(lines[ i ]);
|
7782
|
+
|
7783
|
+
// the format of stack trace in Firefox has changed, 080_exception_parsing should fail
|
7784
|
+
if (!match) return null
|
7785
|
+
|
7786
|
+
result.push(' at line ' + match[ 2 ] + ' of ' + match[ 1 ])
|
7787
|
+
} else {
|
7788
|
+
match = /\s*at\s(.*?):(\d+):(\d+)/.exec(lines[ i ]);
|
7789
|
+
|
7790
|
+
// the format of stack trace in Chrome has changed, 080_exception_parsing should fail
|
7791
|
+
if (!match) return null
|
7792
|
+
|
7793
|
+
result.push(' at line ' + match[ 2 ] + ', character ' + match[ 3 ] + ', of ' + match[ 1 ])
|
7794
|
+
}
|
7795
|
+
}
|
7650
7796
|
|
7651
7797
|
if (!result.length) return null
|
7652
7798
|
|
@@ -7730,7 +7876,7 @@ Class('Siesta.Test', {
|
|
7730
7876
|
* @param {String} desc The description of the assertion
|
7731
7877
|
*/
|
7732
7878
|
is : function (got, expected, desc) {
|
7733
|
-
if (got instanceof this.global.Date) {
|
7879
|
+
if (expected && got instanceof this.global.Date) {
|
7734
7880
|
this.isDateEqual(got, expected, desc);
|
7735
7881
|
} else if (got == expected)
|
7736
7882
|
this.pass(desc)
|
@@ -7863,7 +8009,7 @@ Class('Siesta.Test', {
|
|
7863
8009
|
|
7864
8010
|
/**
|
7865
8011
|
* This method starts the "asynchronous frame". The test will wait for all asynchronous frames to complete before it will finalize.
|
7866
|
-
* The frame
|
8012
|
+
* The frame should be finished with the {@link #endAsync} call within the provided `time`, otherwise a failure will be reported.
|
7867
8013
|
*
|
7868
8014
|
* For example:
|
7869
8015
|
*
|
@@ -7878,27 +8024,42 @@ Class('Siesta.Test', {
|
|
7878
8024
|
*
|
7879
8025
|
*
|
7880
8026
|
* @param {Number} time The maximum time (in ms) to wait until force the finalization of this async frame. Optional. Default time is 15000 ms.
|
8027
|
+
* @param {Function} errback Optional. The function to call in case the call to {@link #endAsync} was not detected withing `time`. If function
|
8028
|
+
* will return any "truthy" value, the failure will not be reported (you can report own failure with this errback).
|
8029
|
+
*
|
7881
8030
|
* @return {Object} The frame object, which can be used in {@link #endAsync} call
|
7882
8031
|
*/
|
7883
|
-
beginAsync : function (time) {
|
8032
|
+
beginAsync : function (time, errback) {
|
8033
|
+
time = time || this.defaultTimeout
|
8034
|
+
|
7884
8035
|
var me = this
|
7885
8036
|
var originalSetTimeout = this.originalSetTimeout
|
7886
8037
|
|
8038
|
+
var index = this.timeoutsCount++
|
8039
|
+
|
7887
8040
|
// in NodeJS `setTimeout` returns an object and not a simple ID, so we try hard to store that object under unique index
|
7888
8041
|
// also using `setTimeout` from the scope of test - as timeouts in different scopes in browsers are mis-synchronized
|
7889
8042
|
// can't just use `this.originalSetTimeout` because of scoping issues
|
7890
|
-
var timeoutId
|
7891
|
-
|
7892
|
-
|
7893
|
-
|
7894
|
-
|
8043
|
+
var timeoutId = originalSetTimeout(function () {
|
8044
|
+
|
8045
|
+
if (me.hasAsyncFrame(index)) {
|
8046
|
+
if (!errback || !errback.call(me, me)) me.fail('No matching `endAsync` call within ' + time + 'ms')
|
8047
|
+
|
8048
|
+
me.endAsync(index)
|
8049
|
+
}
|
8050
|
+
}, time)
|
7895
8051
|
|
7896
|
-
this.timeoutIds[ index ]
|
8052
|
+
this.timeoutIds[ index ] = timeoutId
|
7897
8053
|
|
7898
8054
|
return index
|
7899
8055
|
},
|
7900
8056
|
|
7901
8057
|
|
8058
|
+
hasAsyncFrame : function (index) {
|
8059
|
+
return this.timeoutIds.hasOwnProperty(index)
|
8060
|
+
},
|
8061
|
+
|
8062
|
+
|
7902
8063
|
/**
|
7903
8064
|
* This method finalize the "asynchronous frame" started with {@link #beginAsync}.
|
7904
8065
|
*
|
@@ -7931,7 +8092,6 @@ Class('Siesta.Test', {
|
|
7931
8092
|
|
7932
8093
|
|
7933
8094
|
clearTimeouts : function () {
|
7934
|
-
var me = this
|
7935
8095
|
var originalClearTimeout = this.originalClearTimeout
|
7936
8096
|
|
7937
8097
|
Joose.O.each(this.timeoutIds, function (value, id) {
|
@@ -8008,10 +8168,14 @@ Class('Siesta.Test', {
|
|
8008
8168
|
originalClearTimeout : this.originalClearTimeout
|
8009
8169
|
})
|
8010
8170
|
|
8011
|
-
var exception = this.
|
8171
|
+
var exception = this.getExceptionCatcher()(function(){
|
8012
8172
|
code(todo)
|
8013
8173
|
})
|
8014
8174
|
|
8175
|
+
todo.global = null
|
8176
|
+
todo.originalSetTimeout = null
|
8177
|
+
todo.originalClearTimeout = null
|
8178
|
+
|
8015
8179
|
if (exception !== undefined) this.diag("TODO section threw an exception: [" + exception + "]")
|
8016
8180
|
},
|
8017
8181
|
|
@@ -8049,7 +8213,8 @@ Class('Siesta.Test', {
|
|
8049
8213
|
this.harness.onTestStart(this)
|
8050
8214
|
|
8051
8215
|
/**
|
8052
|
-
* This event is fired when the individual test case starts. When started
|
8216
|
+
* This event is fired when the individual test case starts. When *started*, test may still be waiting for the {@link #isReady} conditions
|
8217
|
+
* to be fullfilled. Once all conditions will be fullfilled, test will be *launched*.
|
8053
8218
|
*
|
8054
8219
|
* This event bubbles up to the {@link Siesta.Harness harness}, you can observe it on harness as well.
|
8055
8220
|
*
|
@@ -8061,7 +8226,7 @@ Class('Siesta.Test', {
|
|
8061
8226
|
this.fireEvent('teststart', this);
|
8062
8227
|
|
8063
8228
|
if (alreadyFailedWithException) {
|
8064
|
-
this.failWithException(alreadyFailedWithException)
|
8229
|
+
this.failWithException(alreadyFailedWithException)
|
8065
8230
|
|
8066
8231
|
return
|
8067
8232
|
}
|
@@ -8141,7 +8306,7 @@ Class('Siesta.Test', {
|
|
8141
8306
|
else
|
8142
8307
|
// in browser (where `timeoutId` is a number) - to the `idsToIndex` hash
|
8143
8308
|
me.idsToIndex[ timeoutId ] = index
|
8144
|
-
|
8309
|
+
|
8145
8310
|
return me.timeoutIds[ index ] = timeoutId
|
8146
8311
|
}
|
8147
8312
|
|
@@ -8181,10 +8346,13 @@ Class('Siesta.Test', {
|
|
8181
8346
|
global.clearTimeout = originalClearTimeout
|
8182
8347
|
}
|
8183
8348
|
|
8184
|
-
originalSetTimeout = me.originalSetTimeout
|
8185
|
-
originalClearTimeout = me.originalClearTimeout
|
8349
|
+
originalSetTimeout = me.originalSetTimeout = null
|
8350
|
+
originalClearTimeout = me.originalClearTimeout = null
|
8186
8351
|
|
8187
|
-
me.global = global
|
8352
|
+
me.global = global = null
|
8353
|
+
me.run = run = null
|
8354
|
+
me.exceptionCatcher = me.testErrorClass = null
|
8355
|
+
me.startTestAnchor = null
|
8188
8356
|
}
|
8189
8357
|
|
8190
8358
|
var run = this.run
|
@@ -8192,7 +8360,7 @@ Class('Siesta.Test', {
|
|
8192
8360
|
if (this.transparentEx)
|
8193
8361
|
run(me)
|
8194
8362
|
else
|
8195
|
-
var e =
|
8363
|
+
var e = this.getExceptionCatcher()(function(){
|
8196
8364
|
run(me)
|
8197
8365
|
})
|
8198
8366
|
|
@@ -8214,11 +8382,12 @@ Class('Siesta.Test', {
|
|
8214
8382
|
if (force) this.clearTimeouts()
|
8215
8383
|
|
8216
8384
|
if (!Joose.O.isEmpty(this.timeoutIds)) {
|
8217
|
-
if (
|
8218
|
-
|
8219
|
-
|
8385
|
+
if (
|
8386
|
+
!this.__timeoutWarning && this.overrideSetTimeout && this.lastActivityDate &&
|
8387
|
+
new Date() - this.lastActivityDate > this.defaultTimeout * 2
|
8388
|
+
) {
|
8220
8389
|
this.diag('Your test is still considered to be running, if this is unexpected please see console for more information');
|
8221
|
-
this.warn('
|
8390
|
+
this.warn('Your test [' + this.url + '] has not finalized, most likely since a timer (setTimeout) is still active. ' +
|
8222
8391
|
'If this is the expected behavior, try setting "overrideSetTimeout : false" on your Harness configuration.');
|
8223
8392
|
this.__timeoutWarning = true;
|
8224
8393
|
}
|
@@ -8259,25 +8428,6 @@ Class('Siesta.Test', {
|
|
8259
8428
|
this.fireEvent('testfinalize', this);
|
8260
8429
|
|
8261
8430
|
this.callback && this.callback()
|
8262
|
-
|
8263
|
-
// // attempting to clear all references to scope, but with delay, to allow
|
8264
|
-
// // other potentially delayed actions to access `global`
|
8265
|
-
// var me = this
|
8266
|
-
//
|
8267
|
-
// var originalSetTimeout = me.originalSetTimeout
|
8268
|
-
//
|
8269
|
-
// // setTimeout from the scope of harness
|
8270
|
-
// originalSetTimeout(function () {
|
8271
|
-
// if (me.overrideSetTimeout) {
|
8272
|
-
// me.global.setTimeout = me.originalSetTimeout
|
8273
|
-
// me.global.clearTimeout = me.originalClearTimeout
|
8274
|
-
// }
|
8275
|
-
//
|
8276
|
-
// originalSetTimeout = me.originalSetTimeout = null
|
8277
|
-
// me.originalClearTimeout = null
|
8278
|
-
//
|
8279
|
-
// me.global = null
|
8280
|
-
// }, 700)
|
8281
8431
|
},
|
8282
8432
|
|
8283
8433
|
|
@@ -8454,9 +8604,10 @@ Class('Siesta.Test', {
|
|
8454
8604
|
|
8455
8605
|
|
8456
8606
|
warn : function (message) {
|
8457
|
-
|
8458
|
-
|
8459
|
-
|
8607
|
+
this.addResult(new Siesta.Result.Diagnostic({
|
8608
|
+
description : message,
|
8609
|
+
isWarning : true
|
8610
|
+
}))
|
8460
8611
|
}
|
8461
8612
|
}
|
8462
8613
|
|
@@ -8471,6 +8622,21 @@ Role('Siesta.Test.Todo', {
|
|
8471
8622
|
|
8472
8623
|
methods : {
|
8473
8624
|
|
8625
|
+
getExceptionCatcher : function () {
|
8626
|
+
return this.parent.getExceptionCatcher()
|
8627
|
+
},
|
8628
|
+
|
8629
|
+
|
8630
|
+
getTestErrorClass : function () {
|
8631
|
+
return this.parent.getTestErrorClass()
|
8632
|
+
},
|
8633
|
+
|
8634
|
+
|
8635
|
+
getStartTestAnchor : function () {
|
8636
|
+
return this.parent.getStartTestAnchor()
|
8637
|
+
},
|
8638
|
+
|
8639
|
+
|
8474
8640
|
addResult : function (result) {
|
8475
8641
|
if (result instanceof Siesta.Result.Assertion) result.isTodo = true
|
8476
8642
|
|
@@ -8539,6 +8705,10 @@ Class('Siesta.Test.Action', {
|
|
8539
8705
|
has : {
|
8540
8706
|
args : null,
|
8541
8707
|
|
8708
|
+
/**
|
8709
|
+
* @cfg {String} desc When provided, once step is completed, a passing assertion with this text will be added to a test.
|
8710
|
+
* This configuration option can be useful to indicate the progress of "wait" steps
|
8711
|
+
*/
|
8542
8712
|
desc : null,
|
8543
8713
|
test : { required : true },
|
8544
8714
|
next : { required : true },
|
@@ -8598,6 +8768,8 @@ Class('Siesta.Test.Action.Done', {
|
|
8598
8768
|
|
8599
8769
|
process : function () {
|
8600
8770
|
this.test.done(this.delay)
|
8771
|
+
|
8772
|
+
this.next()
|
8601
8773
|
}
|
8602
8774
|
}
|
8603
8775
|
});
|
@@ -8673,14 +8845,14 @@ Class('Siesta.Test.Action.Wait', {
|
|
8673
8845
|
*
|
8674
8846
|
* A number of milliseconds to wait before continuing.
|
8675
8847
|
*/
|
8676
|
-
delay
|
8848
|
+
delay : 1000,
|
8677
8849
|
|
8678
8850
|
/**
|
8679
8851
|
* @cfg {Number} timeout
|
8680
8852
|
*
|
8681
8853
|
* The maximum amount of time to wait for the condition to be fulfilled. Defaults to the {@link Siesta.Test.ExtJS#waitForTimeout} value.
|
8682
8854
|
*/
|
8683
|
-
timeout
|
8855
|
+
timeout : null,
|
8684
8856
|
|
8685
8857
|
/**
|
8686
8858
|
* @cfg {Array} args
|
@@ -8725,25 +8897,24 @@ Class('Siesta.Test.Action.Wait', {
|
|
8725
8897
|
this.args = [ waitFor ];
|
8726
8898
|
waitFor = '';
|
8727
8899
|
}
|
8728
|
-
|
8900
|
+
|
8901
|
+
if (waitFor == null) {
|
8902
|
+
this.args = [ this.delay ];
|
8903
|
+
waitFor = '';
|
8904
|
+
}
|
8905
|
+
|
8729
8906
|
if (this.test.typeOf(this.args) !== "Array") {
|
8730
8907
|
this.args = [ this.args ];
|
8731
8908
|
}
|
8732
8909
|
|
8733
|
-
|
8734
|
-
|
8735
|
-
|
8736
|
-
var methodName = 'waitFor' + Joose.S.uppercaseFirst(waitFor);
|
8737
|
-
|
8738
|
-
if (!test[methodName]){
|
8739
|
-
throw 'Could not find a waitFor method named ' + methodName;
|
8740
|
-
}
|
8741
|
-
test[methodName].apply(test, this.args.concat(this.next, test, this.timeout || test.waitForTimeout));
|
8742
|
-
} else {
|
8743
|
-
var originalSetTimeout = test.originalSetTimeout;
|
8910
|
+
// also allow full method names
|
8911
|
+
waitFor = waitFor.replace(/^waitFor/, '')
|
8912
|
+
var methodName = 'waitFor' + Joose.S.uppercaseFirst(waitFor);
|
8744
8913
|
|
8745
|
-
|
8914
|
+
if (!test[methodName]){
|
8915
|
+
throw 'Could not find a waitFor method named ' + methodName;
|
8746
8916
|
}
|
8917
|
+
test[methodName].apply(test, this.args.concat(this.next, test, this.timeout || test.waitForTimeout));
|
8747
8918
|
}
|
8748
8919
|
}
|
8749
8920
|
});
|
@@ -8753,6 +8924,115 @@ Joose.A.each(['wait', 'delay'], function(name) {
|
|
8753
8924
|
});;
|
8754
8925
|
/**
|
8755
8926
|
|
8927
|
+
@class Siesta.Test.Action.Eval
|
8928
|
+
@extends Siesta.Test.Action
|
8929
|
+
|
8930
|
+
This action can be included in the `t.chain` steps only with a plain string. Siesta will examine the passed string,
|
8931
|
+
and call an apropriate method of the test class. String should have the following format:
|
8932
|
+
|
8933
|
+
methodName(params)
|
8934
|
+
|
8935
|
+
Method name is anything until the first parenthes. Method name may have an optional prefix `t.`.
|
8936
|
+
Everything in between of outermost parentheses will be treated as parameters for method call. For example:
|
8937
|
+
|
8938
|
+
t.chain(
|
8939
|
+
// string should look like a usual method call,
|
8940
|
+
// but arguments can't reference any variables
|
8941
|
+
// strings should be quoted, to include quoting symbol in string use double slash: \\
|
8942
|
+
't.click("combo[type=some\\"Type] => .x-form-trigger")',
|
8943
|
+
|
8944
|
+
// leading "t." is optional, but quoting is not
|
8945
|
+
'waitForComponent("combo[type=someType]")',
|
8946
|
+
|
8947
|
+
// JSON objects are ok, but they should be a valid JSON - ie object properties should be quoted
|
8948
|
+
'myClick([ 10, 10 ], { "foo" : "bar" })',
|
8949
|
+
)
|
8950
|
+
|
8951
|
+
* **Note** You can pass the JSON objects as arguments, but they should be serialized as valid JSON - ie object properties should be quoted.
|
8952
|
+
|
8953
|
+
* **Note** A callback for next step in chain will be always appended to provided parameters. Make sure it is placed in a correct spot!
|
8954
|
+
For example if method signature is `t.someMethod(param1, param2, callback)` and you are calling this method as:
|
8955
|
+
|
8956
|
+
t.chain(
|
8957
|
+
`t.someMethod("text")`
|
8958
|
+
)
|
8959
|
+
it will fail - callback will be provided in place of `param2`. Instead call it as:
|
8960
|
+
|
8961
|
+
t.chain(
|
8962
|
+
`t.someMethod("text", null)`
|
8963
|
+
)
|
8964
|
+
|
8965
|
+
This action may save you few keystrokes, when you need to perform some action with static arguments (known prior the action).
|
8966
|
+
|
8967
|
+
*/
|
8968
|
+
Class('Siesta.Test.Action.Eval', {
|
8969
|
+
|
8970
|
+
isa : Siesta.Test.Action,
|
8971
|
+
|
8972
|
+
has : {
|
8973
|
+
/**
|
8974
|
+
* @cfg {Object} options
|
8975
|
+
*
|
8976
|
+
* Any options that will be used when simulating the event. For information about possible
|
8977
|
+
* config options, please see: https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent
|
8978
|
+
*/
|
8979
|
+
actionString : null
|
8980
|
+
},
|
8981
|
+
|
8982
|
+
|
8983
|
+
methods : {
|
8984
|
+
|
8985
|
+
process : function () {
|
8986
|
+
var test = this.test
|
8987
|
+
var parsed = this.parseActionString(this.actionString)
|
8988
|
+
|
8989
|
+
if (parsed.error) {
|
8990
|
+
test.fail(parsed.error)
|
8991
|
+
this.next()
|
8992
|
+
return
|
8993
|
+
}
|
8994
|
+
|
8995
|
+
var methodName = parsed.methodName
|
8996
|
+
|
8997
|
+
if (!methodName || test.typeOf(test[ methodName ]) != 'Function') {
|
8998
|
+
test.fail("Invalid method name: " + methodName)
|
8999
|
+
this.next()
|
9000
|
+
return
|
9001
|
+
}
|
9002
|
+
|
9003
|
+
parsed.params.push(this.next)
|
9004
|
+
|
9005
|
+
test[ methodName ].apply(test, parsed.params)
|
9006
|
+
},
|
9007
|
+
|
9008
|
+
|
9009
|
+
parseActionString : function (actionString) {
|
9010
|
+
var match = /^\s*(.+?)\(\s*(.*)\s*\)\s*$/.exec(actionString)
|
9011
|
+
|
9012
|
+
if (!match) return {
|
9013
|
+
error : "Wrong format of the action string: " + actionString
|
9014
|
+
}
|
9015
|
+
|
9016
|
+
var methodName = match[ 1 ].replace(/^t\./, '')
|
9017
|
+
|
9018
|
+
try {
|
9019
|
+
var params = JSON.parse('[' + match[ 2 ] + ']')
|
9020
|
+
} catch (e) {
|
9021
|
+
return {
|
9022
|
+
error : "Can't parse arguments: " + match[ 2 ]
|
9023
|
+
}
|
9024
|
+
}
|
9025
|
+
|
9026
|
+
return {
|
9027
|
+
methodName : methodName,
|
9028
|
+
params : params
|
9029
|
+
}
|
9030
|
+
}
|
9031
|
+
}
|
9032
|
+
});
|
9033
|
+
;
|
9034
|
+
/**
|
9035
|
+
|
8756
9036
|
@class Siesta.Harness
|
8757
9037
|
|
8758
9038
|
`Siesta.Harness` is an abstract base harness class in Siesta hierarchy. This class provides no UI,
|
@@ -8836,7 +9116,7 @@ Class('Siesta.Harness', {
|
|
8836
9116
|
|
8837
9117
|
has : {
|
8838
9118
|
/**
|
8839
|
-
* @cfg {String} title The title of the test suite. Can contain HTML.
|
9119
|
+
* @cfg {String} title The title of the test suite. Can contain HTML. When provided in the test file descriptor - will change the name of test in the harness UI.
|
8840
9120
|
*/
|
8841
9121
|
title : null,
|
8842
9122
|
|
@@ -8849,8 +9129,6 @@ Class('Siesta.Harness', {
|
|
8849
9129
|
testClass : Siesta.Test,
|
8850
9130
|
contentManagerClass : Siesta.Content.Manager,
|
8851
9131
|
|
8852
|
-
testsByURL : Joose.I.Object,
|
8853
|
-
|
8854
9132
|
// fields of test descriptor:
|
8855
9133
|
// - id - either `url` or wbs + group - computed
|
8856
9134
|
// - url
|
@@ -8872,7 +9150,12 @@ Class('Siesta.Harness', {
|
|
8872
9150
|
descriptors : Joose.I.Array,
|
8873
9151
|
descriptorsById : Joose.I.Object,
|
8874
9152
|
|
9153
|
+
launchCounter : 0,
|
9154
|
+
|
9155
|
+
launches : Joose.I.Object,
|
9156
|
+
|
8875
9157
|
scopesByURL : Joose.I.Object,
|
9158
|
+
testsByURL : Joose.I.Object,
|
8876
9159
|
|
8877
9160
|
/**
|
8878
9161
|
* @cfg {Boolean} transparentEx When set to `true` harness will not try to catch any exception, thrown from the test code.
|
@@ -8935,7 +9218,7 @@ Class('Siesta.Harness', {
|
|
8935
9218
|
* This option can be also specified in the test file descriptor.
|
8936
9219
|
*/
|
8937
9220
|
expectedGlobals : Joose.I.Array,
|
8938
|
-
// will be populated by `
|
9221
|
+
// will be populated by `populateCleanScopeGlobals`
|
8939
9222
|
cleanScopeGlobals : Joose.I.Array,
|
8940
9223
|
|
8941
9224
|
/**
|
@@ -9035,6 +9318,17 @@ Class('Siesta.Harness', {
|
|
9035
9318
|
*/
|
9036
9319
|
keepResults : true,
|
9037
9320
|
|
9321
|
+
/**
|
9322
|
+
* @cfg {Number} keepNLastResults
|
9323
|
+
*
|
9324
|
+
* Only meaningful when {@link #keepResults} is set to `false`. Indicates the number of the test results which still should be kept, for user examination.
|
9325
|
+
* Results are cleared when their total number exceed this value, based on FIFO order.
|
9326
|
+
*/
|
9327
|
+
keepNLastResults : 2,
|
9328
|
+
|
9329
|
+
lastResultsURLs : Joose.I.Array,
|
9330
|
+
lastResultsByURL : Joose.I.Object,
|
9331
|
+
|
9038
9332
|
/**
|
9039
9333
|
* @cfg {Boolean} overrideSetTimeout When set to `false`, the tests will not override "setTimeout" from the context of each test
|
9040
9334
|
* for asynchronous code tracking. User will need to use `beginAsync/endAsync` calls to indicate that test is still running.
|
@@ -9225,13 +9519,14 @@ Class('Siesta.Harness', {
|
|
9225
9519
|
},
|
9226
9520
|
|
9227
9521
|
/**
|
9228
|
-
* This method will launch a test suite. It accepts a variable number of *test file descriptors
|
9522
|
+
* This method will launch a test suite. It accepts a variable number of *test file descriptors* or an array of such. A test file descritor is one of the following:
|
9229
9523
|
*
|
9230
9524
|
* - a string, containing a test file url
|
9231
9525
|
* - an object containing the `url` property `{ url : '...', option1 : 'value1', option2 : 'value2' }`. The `url` property should point to the test file.
|
9232
9526
|
* Other properties can contain values of some configuration options of the harness (marked accordingly). In this case, they will **override** the corresponding values,
|
9233
9527
|
* provided to harness or parent descriptor.
|
9234
|
-
* - an object `{ group : 'groupName', items : [], expanded : true, option1 : 'value1' }` specifying the folder of test files. The `
|
9528
|
+
* - an object `{ group : 'groupName', items : [], expanded : true, option1 : 'value1' }` specifying the folder of test files. The `expanded` property
|
9529
|
+
* sets the initial state of the folder - "collapsed/expanded". The `items` property can contain an array of test file descriptors.
|
9235
9530
|
* Other properties will override the applicable harness options **for all child descriptors**.
|
9236
9531
|
*
|
9237
9532
|
* Groups (folder) may contain nested groups. Number of nesting levels is not limited.
|
@@ -9294,19 +9589,19 @@ Class('Siesta.Harness', {
|
|
9294
9589
|
*
|
9295
9590
|
* Values from this object takes the highest priority and will override any other configuration.
|
9296
9591
|
*
|
9297
|
-
* @param {Mixed} descriptor1
|
9592
|
+
* @param {Array/Mixed} descriptor1 or an array of descriptors
|
9298
9593
|
* @param {Mixed} descriptor2
|
9299
9594
|
* @param {Mixed} descriptorN
|
9300
9595
|
*/
|
9301
9596
|
start : function () {
|
9302
9597
|
// a bit hackish - used by Selenium reporter..
|
9303
|
-
var me =
|
9598
|
+
var me = Siesta.my.activeHarness = this
|
9304
9599
|
|
9305
9600
|
this.mainPreset = new Siesta.Content.Preset({
|
9306
9601
|
preload : this.processPreloadArray(this.preload)
|
9307
9602
|
})
|
9308
9603
|
|
9309
|
-
var descriptors = this.descriptors = Joose.A.map(arguments, function (desc, index) {
|
9604
|
+
var descriptors = this.descriptors = Joose.A.map(Array.prototype.concat.apply([], arguments), function (desc, index) {
|
9310
9605
|
return me.normalizeDescriptor(desc, me, index)
|
9311
9606
|
})
|
9312
9607
|
|
@@ -9334,6 +9629,8 @@ Class('Siesta.Harness', {
|
|
9334
9629
|
if (desc.preset != me.mainPreset) presets.push(desc.preset)
|
9335
9630
|
|
9336
9631
|
testScriptsPreset.addResource(desc.url)
|
9632
|
+
|
9633
|
+
me.deleteTestByURL(desc.url)
|
9337
9634
|
})
|
9338
9635
|
|
9339
9636
|
// cache either everything (this.cachePreload) or only the test files (to be able to show missing files / show content)
|
@@ -9359,8 +9656,9 @@ Class('Siesta.Harness', {
|
|
9359
9656
|
|
9360
9657
|
// if testConfig contains the "preload" or "alsoPreload" key - then we need to update the preset of the descriptor
|
9361
9658
|
if (testConfig && (testConfig.preload || testConfig.alsoPreload)) desc.preset = me.getDescriptorPreset(desc)
|
9362
|
-
} else
|
9363
|
-
|
9659
|
+
} else
|
9660
|
+
// allow subclasses to define there own logic when found missing test file
|
9661
|
+
me.markMissingFile(desc)
|
9364
9662
|
|
9365
9663
|
me.normalizeScopeProvider(desc)
|
9366
9664
|
})
|
@@ -9377,6 +9675,11 @@ Class('Siesta.Harness', {
|
|
9377
9675
|
},
|
9378
9676
|
|
9379
9677
|
|
9678
|
+
markMissingFile : function (desc) {
|
9679
|
+
desc.isMissing = true
|
9680
|
+
},
|
9681
|
+
|
9682
|
+
|
9380
9683
|
flattenDescriptors : function (descriptors, includeFolders) {
|
9381
9684
|
var flatten = []
|
9382
9685
|
var me = this
|
@@ -9568,10 +9871,10 @@ Class('Siesta.Harness', {
|
|
9568
9871
|
|
9569
9872
|
|
9570
9873
|
getSeedingCode : function (desc) {
|
9571
|
-
return 'StartTest = function () { StartTest.args = arguments };' +
|
9874
|
+
return 'StartTest = startTest = function () { StartTest.args = arguments };' +
|
9572
9875
|
// for older IE - the try/catch should be from the same context as the exception
|
9573
9876
|
'StartTest.exceptionCatcher = function (func) { var ex; try { func() } catch (e) { ex = e; }; return ex; };' +
|
9574
|
-
'StartTest.
|
9877
|
+
'StartTest.testErrorClass = Error;'
|
9575
9878
|
},
|
9576
9879
|
|
9577
9880
|
|
@@ -9584,12 +9887,54 @@ Class('Siesta.Harness', {
|
|
9584
9887
|
},
|
9585
9888
|
|
9586
9889
|
|
9890
|
+
keepTestResult : function (url) {
|
9891
|
+
// already keeping
|
9892
|
+
if (this.lastResultsByURL[ url ]) {
|
9893
|
+
var indexOf = -1
|
9894
|
+
|
9895
|
+
Joose.A.each(this.lastResultsURLs, function (resultUrl, i) {
|
9896
|
+
if (resultUrl == url) { indexOf = i; return false }
|
9897
|
+
})
|
9898
|
+
|
9899
|
+
this.lastResultsURLs.splice(indexOf, 1)
|
9900
|
+
this.lastResultsURLs.push(url)
|
9901
|
+
|
9902
|
+
return
|
9903
|
+
}
|
9904
|
+
|
9905
|
+
this.lastResultsURLs.push(url)
|
9906
|
+
this.lastResultsByURL[ url ] = true
|
9907
|
+
|
9908
|
+
if (this.lastResultsURLs.length > this.keepNLastResults) this.releaseTestResult()
|
9909
|
+
},
|
9910
|
+
|
9911
|
+
|
9912
|
+
releaseTestResult : function () {
|
9913
|
+
if (this.lastResultsURLs.length <= this.keepNLastResults) return
|
9914
|
+
|
9915
|
+
var url = this.lastResultsURLs.shift()
|
9916
|
+
|
9917
|
+
delete this.lastResultsByURL[ url ]
|
9918
|
+
|
9919
|
+
var test = this.getTestByURL(url)
|
9920
|
+
|
9921
|
+
if (test && test.isFinished()) this.cleanupScopeForURL(url)
|
9922
|
+
},
|
9923
|
+
|
9924
|
+
|
9925
|
+
isKeepingResultForURL : function (url) {
|
9926
|
+
return this.lastResultsByURL[ url ]
|
9927
|
+
},
|
9928
|
+
|
9929
|
+
|
9587
9930
|
setupScope : function (desc) {
|
9588
9931
|
var url = desc.url
|
9589
9932
|
var scopeProvideClass = eval(desc.scopeProvider)
|
9590
9933
|
|
9591
9934
|
this.cleanupScopeForURL(url)
|
9592
9935
|
|
9936
|
+
this.keepTestResult(url)
|
9937
|
+
|
9593
9938
|
return this.scopesByURL[ url ] = new scopeProvideClass(this.getScopeProviderConfigFor(desc))
|
9594
9939
|
},
|
9595
9940
|
|
@@ -9705,7 +10050,7 @@ Class('Siesta.Harness', {
|
|
9705
10050
|
var args = startTestAnchor && startTestAnchor.args
|
9706
10051
|
|
9707
10052
|
// pick either 1st or 2nd argument depending which one is a function
|
9708
|
-
var runFunc = args && (typeof args[ 0 ] == 'function'
|
10053
|
+
var runFunc = args && (typeof args[ 0 ] == 'function' ? args[ 0 ] : args[ 1 ])
|
9709
10054
|
|
9710
10055
|
me.launchTest({
|
9711
10056
|
testHolder : testHolder,
|
@@ -9716,6 +10061,8 @@ Class('Siesta.Harness', {
|
|
9716
10061
|
preloadErrors : preloadErrors,
|
9717
10062
|
onErrorHandler : onErrorHandler,
|
9718
10063
|
|
10064
|
+
startTestAnchor : startTestAnchor,
|
10065
|
+
|
9719
10066
|
runFunc : runFunc
|
9720
10067
|
}, callback)
|
9721
10068
|
});
|
@@ -9736,15 +10083,18 @@ Class('Siesta.Harness', {
|
|
9736
10083
|
// after the scope setup, the `onerror` handler might be cleared - installing it again
|
9737
10084
|
if (!this.getDescriptorConfig(desc, 'transparentEx')) scopeProvider.addOnErrorHandler(options.onErrorHandler)
|
9738
10085
|
|
9739
|
-
var testConfig = me.getNewTestConfiguration(desc, scopeProvider, options.contentManager, options.urlOptions, options.runFunc)
|
10086
|
+
var testConfig = me.getNewTestConfiguration(desc, scopeProvider, options.contentManager, options.urlOptions, options.runFunc, options.startTestAnchor)
|
9740
10087
|
|
9741
10088
|
testConfig.callback = function () {
|
9742
|
-
if (!me.keepResults)
|
10089
|
+
if (!me.keepResults) {
|
10090
|
+
if (!me.isKeepingResultForURL(url)) me.cleanupScopeForURL(url)
|
10091
|
+
}
|
9743
10092
|
|
9744
10093
|
callback && callback()
|
9745
10094
|
}
|
9746
10095
|
|
9747
|
-
var test = options.testHolder.test =
|
10096
|
+
var test = options.testHolder.test = new testClass(testConfig)
|
10097
|
+
this.saveTestWithURL(url, test)
|
9748
10098
|
|
9749
10099
|
scopeProvider.scope.setTimeout(function() {
|
9750
10100
|
//console.timeEnd('launch')
|
@@ -9755,7 +10105,7 @@ Class('Siesta.Harness', {
|
|
9755
10105
|
},
|
9756
10106
|
|
9757
10107
|
|
9758
|
-
getNewTestConfiguration : function (desc, scopeProvider, contentManager, options, runFunc) {
|
10108
|
+
getNewTestConfiguration : function (desc, scopeProvider, contentManager, options, runFunc, startTestAnchor) {
|
9759
10109
|
var scope = scopeProvider.scope
|
9760
10110
|
|
9761
10111
|
var config = {
|
@@ -9763,6 +10113,11 @@ Class('Siesta.Harness', {
|
|
9763
10113
|
|
9764
10114
|
harness : this,
|
9765
10115
|
run : runFunc,
|
10116
|
+
|
10117
|
+
startTestAnchor : startTestAnchor,
|
10118
|
+
|
10119
|
+
exceptionCatcher : startTestAnchor.exceptionCatcher,
|
10120
|
+
testErrorClass : startTestAnchor.testErrorClass,
|
9766
10121
|
|
9767
10122
|
expectedGlobals : this.cleanScopeGlobals.concat(this.getDescriptorConfig(desc, 'expectedGlobals')),
|
9768
10123
|
autoCheckGlobals : this.getDescriptorConfig(desc, 'autoCheckGlobals'),
|
@@ -9797,18 +10152,34 @@ Class('Siesta.Harness', {
|
|
9797
10152
|
},
|
9798
10153
|
|
9799
10154
|
|
10155
|
+
getTestByURL : function (url) {
|
10156
|
+
return this.testsByURL[ url ]
|
10157
|
+
},
|
10158
|
+
|
10159
|
+
|
10160
|
+
saveTestWithURL : function (url, test) {
|
10161
|
+
this.testsByURL[ url ] = test
|
10162
|
+
},
|
10163
|
+
|
10164
|
+
|
10165
|
+
deleteTestByURL : function (url) {
|
10166
|
+
delete this.testsByURL[ url ]
|
10167
|
+
},
|
10168
|
+
|
10169
|
+
|
9800
10170
|
allPassed : function () {
|
9801
10171
|
var allPassed = true
|
9802
10172
|
var me = this
|
9803
10173
|
|
9804
10174
|
Joose.A.each(this.flattenDescriptors(this.descriptors), function (descriptor) {
|
9805
|
-
|
10175
|
+
// if at least one test is missing then something is wrong
|
10176
|
+
if (descriptor.isMissing) { allPassed = false; return false }
|
10177
|
+
|
10178
|
+
var test = me.getTestByURL(descriptor.url)
|
9806
10179
|
|
9807
10180
|
// ignore missing tests (could be skipped by test filtering
|
9808
10181
|
if (!test) return
|
9809
10182
|
|
9810
|
-
if (descriptor.isMissing) { allPassed = false; return false }
|
9811
|
-
|
9812
10183
|
allPassed = allPassed && test.isPassed()
|
9813
10184
|
})
|
9814
10185
|
|
@@ -9825,6 +10196,11 @@ Class('Siesta.Harness', {
|
|
9825
10196
|
if (!this[ methodName ]) throw "Can't generate report - missing the `" + methodName + "` method"
|
9826
10197
|
|
9827
10198
|
return this[ methodName ](options)
|
10199
|
+
},
|
10200
|
+
|
10201
|
+
|
10202
|
+
typeOf : function (object) {
|
10203
|
+
return Object.prototype.toString.call(object).replace(/^\[object /, '').replace(/\]$/, '')
|
9828
10204
|
}
|
9829
10205
|
}
|
9830
10206
|
// eof methods
|
@@ -18824,6 +19200,15 @@ delegate = function (event) {
|
|
18824
19200
|
}
|
18825
19201
|
};
|
18826
19202
|
})(window);
|
19203
|
+
|
19204
|
+
jQuery.fn.center = function () {
|
19205
|
+
this.css("position","absolute");
|
19206
|
+
this.css("top", Math.max(0, (($(window).height() - this.outerHeight()) / 2) +
|
19207
|
+
$(window).scrollTop()) + "px");
|
19208
|
+
this.css("left", Math.max(0, (($(window).width() - this.outerWidth()) / 2) +
|
19209
|
+
$(window).scrollLeft()) + "px");
|
19210
|
+
return this;
|
19211
|
+
}
|
18827
19212
|
;
|
18828
19213
|
Class("JooseX.SimpleRequest", {
|
18829
19214
|
|
@@ -19046,6 +19431,8 @@ Role('Siesta.Test.Action.Role.HasTarget', {
|
|
19046
19431
|
*/
|
19047
19432
|
target : { required : false },
|
19048
19433
|
|
19434
|
+
normalizedTarget : null,
|
19435
|
+
|
19049
19436
|
/**
|
19050
19437
|
* @cfg {Object} el
|
19051
19438
|
*
|
@@ -19053,7 +19440,7 @@ Role('Siesta.Test.Action.Role.HasTarget', {
|
|
19053
19440
|
*/
|
19054
19441
|
|
19055
19442
|
/**
|
19056
|
-
* @cfg {Boolean} passTargetToNext Whether to pass
|
19443
|
+
* @cfg {Boolean} passTargetToNext Whether to pass the target further on chain as the first argument
|
19057
19444
|
*/
|
19058
19445
|
passTargetToNext : true
|
19059
19446
|
},
|
@@ -19066,12 +19453,12 @@ Role('Siesta.Test.Action.Role.HasTarget', {
|
|
19066
19453
|
var me = this
|
19067
19454
|
var prevNext = this.next
|
19068
19455
|
|
19069
|
-
// Needs to be 'resolved'
|
19070
|
-
// e.g. unchecking a checkbox
|
19071
|
-
var realTarget = me.test.normalizeActionTarget(me.getTarget());
|
19456
|
+
// // Needs to be 'resolved' at action instantiate time since the action may cause the selector not to be found
|
19457
|
+
// // e.g. unchecking a checkbox
|
19458
|
+
// var realTarget = me.test.normalizeActionTarget(me.getTarget());
|
19072
19459
|
|
19073
19460
|
this.next = function () {
|
19074
|
-
prevNext.call(this,
|
19461
|
+
prevNext.call(this, me.normalizedTarget);
|
19075
19462
|
}
|
19076
19463
|
}
|
19077
19464
|
},
|
@@ -19093,11 +19480,11 @@ Role('Siesta.Test.Action.Role.HasTarget', {
|
|
19093
19480
|
var test = this.test;
|
19094
19481
|
var target = this.target || test.getElementAtCursor();
|
19095
19482
|
|
19096
|
-
if (test.typeOf(target) === 'Function')
|
19097
|
-
|
19098
|
-
|
19483
|
+
if (test.typeOf(target) === 'Function') target = target.call(test, this);
|
19484
|
+
|
19485
|
+
this.normalizedTarget = test.normalizeActionTarget(target)
|
19099
19486
|
|
19100
|
-
return this.__cachedTarget__
|
19487
|
+
return this.__cachedTarget__ = target
|
19101
19488
|
}
|
19102
19489
|
}
|
19103
19490
|
});
|
@@ -19189,19 +19576,100 @@ Siesta.Test.ActionRegistry.registerAction('longpress', Siesta.Test.Action.LongPr
|
|
19189
19576
|
;
|
19190
19577
|
/**
|
19191
19578
|
|
19192
|
-
@class Siesta.Test.Action.
|
19579
|
+
@class Siesta.Test.Action.Tap
|
19193
19580
|
@extends Siesta.Test.Action
|
19194
19581
|
@mixin Siesta.Test.Action.Role.HasTarget
|
19195
19582
|
|
19196
|
-
This action can be included in
|
19583
|
+
This action can be included in the `t.chain` call with "tap" shortcut:
|
19197
19584
|
|
19198
19585
|
t.chain(
|
19199
19586
|
{
|
19200
|
-
action : '
|
19587
|
+
action : 'tap',
|
19201
19588
|
target : someDOMElement
|
19202
19589
|
}
|
19203
19590
|
)
|
19204
19591
|
|
19592
|
+
This action will perform a {@link Siesta.Test.Browser#tap tap} on the provided {@link #target}.
|
19593
|
+
|
19594
|
+
*/
|
19595
|
+
Class('Siesta.Test.Action.Tap', {
|
19596
|
+
|
19597
|
+
isa : Siesta.Test.Action,
|
19598
|
+
|
19599
|
+
does : Siesta.Test.Action.Role.HasTarget,
|
19600
|
+
|
19601
|
+
has : {
|
19602
|
+
requiredTestMethod : 'tap'
|
19603
|
+
},
|
19604
|
+
|
19605
|
+
|
19606
|
+
methods : {
|
19607
|
+
|
19608
|
+
process : function () {
|
19609
|
+
this.test.tap(this.getTarget(), this.next)
|
19610
|
+
}
|
19611
|
+
}
|
19612
|
+
});
|
19613
|
+
|
19614
|
+
|
19615
|
+
Siesta.Test.ActionRegistry.registerAction('tap', Siesta.Test.Action.Tap);
|
19616
|
+
/**
|
19617
|
+
|
19618
|
+
@class Siesta.Test.Action.DoubleTap
|
19619
|
+
@extends Siesta.Test.Action
|
19620
|
+
@mixin Siesta.Test.Action.Role.HasTarget
|
19621
|
+
|
19622
|
+
This action will perform a {@link Siesta.Test.Browser#doubleClick double tap} on the provided {@link #target}.
|
19623
|
+
|
19624
|
+
This action can be included in the `t.chain` call with "doubletap" or "doubleTap" shortcuts:
|
19625
|
+
|
19626
|
+
t.chain(
|
19627
|
+
{
|
19628
|
+
action : 'doubletap',
|
19629
|
+
target : someDOMElement
|
19630
|
+
}
|
19631
|
+
)
|
19632
|
+
|
19633
|
+
|
19634
|
+
*/
|
19635
|
+
Class('Siesta.Test.Action.DoubleTap', {
|
19636
|
+
|
19637
|
+
isa : Siesta.Test.Action,
|
19638
|
+
|
19639
|
+
does : Siesta.Test.Action.Role.HasTarget,
|
19640
|
+
|
19641
|
+
has : {
|
19642
|
+
requiredTestMethod : 'doubleTap'
|
19643
|
+
},
|
19644
|
+
|
19645
|
+
|
19646
|
+
methods : {
|
19647
|
+
|
19648
|
+
process : function () {
|
19649
|
+
this.test.doubleTap(this.getTarget(), this.next)
|
19650
|
+
}
|
19651
|
+
}
|
19652
|
+
});
|
19653
|
+
|
19654
|
+
|
19655
|
+
Siesta.Test.ActionRegistry.registerAction('doubletap', Siesta.Test.Action.DoubleTap)
|
19656
|
+
;
|
19657
|
+
/**
|
19658
|
+
|
19659
|
+
@class Siesta.Test.Action.MouseDown
|
19660
|
+
@extends Siesta.Test.Action
|
19661
|
+
@mixin Siesta.Test.Action.Role.HasTarget
|
19662
|
+
|
19663
|
+
This action can be included in a `t.chain` call with "mouseDown" shortcut:
|
19664
|
+
|
19665
|
+
t.chain(
|
19666
|
+
{
|
19667
|
+
action : 'mouseDown',
|
19668
|
+
target : someDOMElement,
|
19669
|
+
options : { shiftKey : true } // Optionally hold shiftkey
|
19670
|
+
}
|
19671
|
+
)
|
19672
|
+
|
19205
19673
|
This action will perform a {@link Siesta.Test.Browser#MouseDown MouseDown} on the provided {@link #target}.
|
19206
19674
|
|
19207
19675
|
*/
|
@@ -19212,7 +19680,15 @@ Class('Siesta.Test.Action.MouseDown', {
|
|
19212
19680
|
does : Siesta.Test.Action.Role.HasTarget,
|
19213
19681
|
|
19214
19682
|
has : {
|
19215
|
-
requiredTestMethod : 'mouseDown'
|
19683
|
+
requiredTestMethod : 'mouseDown',
|
19684
|
+
|
19685
|
+
/**
|
19686
|
+
* @cfg {Object} options
|
19687
|
+
*
|
19688
|
+
* Any options that will be used when simulating the event. For information about possible
|
19689
|
+
* config options, please see: https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent
|
19690
|
+
*/
|
19691
|
+
options : null
|
19216
19692
|
},
|
19217
19693
|
|
19218
19694
|
|
@@ -19220,7 +19696,7 @@ Class('Siesta.Test.Action.MouseDown', {
|
|
19220
19696
|
|
19221
19697
|
process : function () {
|
19222
19698
|
// This method is synchronous
|
19223
|
-
this.test.mouseDown(this.getTarget());
|
19699
|
+
this.test.mouseDown(this.getTarget(), this.options);
|
19224
19700
|
|
19225
19701
|
setTimeout(this.next, 100);
|
19226
19702
|
}
|
@@ -19242,7 +19718,8 @@ This action can be included in a `t.chain` call with "mouseUp" shortcut:
|
|
19242
19718
|
t.chain(
|
19243
19719
|
{
|
19244
19720
|
action : 'mouseUp',
|
19245
|
-
target : someDOMElement
|
19721
|
+
target : someDOMElement,
|
19722
|
+
options : { shiftKey : true } // Optionally hold shiftkey
|
19246
19723
|
}
|
19247
19724
|
)
|
19248
19725
|
|
@@ -19256,7 +19733,15 @@ Class('Siesta.Test.Action.MouseUp', {
|
|
19256
19733
|
does : Siesta.Test.Action.Role.HasTarget,
|
19257
19734
|
|
19258
19735
|
has : {
|
19259
|
-
requiredTestMethod : 'mouseUp'
|
19736
|
+
requiredTestMethod : 'mouseUp',
|
19737
|
+
|
19738
|
+
/**
|
19739
|
+
* @cfg {Object} options
|
19740
|
+
*
|
19741
|
+
* Any options that will be used when simulating the event. For information about possible
|
19742
|
+
* config options, please see: https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent
|
19743
|
+
*/
|
19744
|
+
options : null
|
19260
19745
|
},
|
19261
19746
|
|
19262
19747
|
|
@@ -19264,7 +19749,7 @@ Class('Siesta.Test.Action.MouseUp', {
|
|
19264
19749
|
|
19265
19750
|
process : function () {
|
19266
19751
|
// This method is synchronous
|
19267
|
-
this.test.mouseUp(this.getTarget());
|
19752
|
+
this.test.mouseUp(this.getTarget(), this.options);
|
19268
19753
|
|
19269
19754
|
setTimeout(this.next, 100);
|
19270
19755
|
}
|
@@ -19286,7 +19771,8 @@ This action can be included in the `t.chain` call with "click" shortcut:
|
|
19286
19771
|
t.chain(
|
19287
19772
|
{
|
19288
19773
|
action : 'click',
|
19289
|
-
target : someDOMElement
|
19774
|
+
target : someDOMElement,
|
19775
|
+
options : { shiftKey : true } // Optionally hold shiftkey
|
19290
19776
|
}
|
19291
19777
|
)
|
19292
19778
|
|
@@ -19300,21 +19786,29 @@ Class('Siesta.Test.Action.Click', {
|
|
19300
19786
|
does : Siesta.Test.Action.Role.HasTarget,
|
19301
19787
|
|
19302
19788
|
has : {
|
19303
|
-
requiredTestMethod : 'click'
|
19789
|
+
requiredTestMethod : 'click',
|
19790
|
+
|
19791
|
+
/**
|
19792
|
+
* @cfg {Object} options
|
19793
|
+
*
|
19794
|
+
* Any options that will be used when simulating the event. For information about possible
|
19795
|
+
* config options, please see: https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent
|
19796
|
+
*/
|
19797
|
+
options : null
|
19304
19798
|
},
|
19305
19799
|
|
19306
19800
|
|
19307
19801
|
methods : {
|
19308
19802
|
|
19309
19803
|
process : function () {
|
19310
|
-
this.test.click(this.getTarget(), this.next)
|
19804
|
+
this.test.click(this.getTarget(), this.next, null, this.options);
|
19311
19805
|
}
|
19312
19806
|
}
|
19313
19807
|
});
|
19314
19808
|
|
19315
19809
|
|
19316
|
-
Siesta.Test.ActionRegistry.registerAction('click', Siesta.Test.Action.Click)
|
19317
|
-
|
19810
|
+
Siesta.Test.ActionRegistry.registerAction('click', Siesta.Test.Action.Click);
|
19811
|
+
;
|
19318
19812
|
/**
|
19319
19813
|
|
19320
19814
|
@class Siesta.Test.Action.DoubleClick
|
@@ -19327,8 +19821,9 @@ This action can be included in the `t.chain` call with "doubleclick" or "doubleC
|
|
19327
19821
|
|
19328
19822
|
t.chain(
|
19329
19823
|
{
|
19330
|
-
action : '
|
19331
|
-
target : someDOMElement
|
19824
|
+
action : 'doubleclick',
|
19825
|
+
target : someDOMElement,
|
19826
|
+
options : { shiftKey : true } // Optionally hold shiftkey
|
19332
19827
|
}
|
19333
19828
|
)
|
19334
19829
|
|
@@ -19341,21 +19836,28 @@ Class('Siesta.Test.Action.DoubleClick', {
|
|
19341
19836
|
does : Siesta.Test.Action.Role.HasTarget,
|
19342
19837
|
|
19343
19838
|
has : {
|
19344
|
-
requiredTestMethod : 'doubleClick'
|
19839
|
+
requiredTestMethod : 'doubleClick',
|
19840
|
+
|
19841
|
+
/**
|
19842
|
+
* @cfg {Object} options
|
19843
|
+
*
|
19844
|
+
* Any options that will be used when simulating the event. For information about possible
|
19845
|
+
* config options, please see: https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent
|
19846
|
+
*/
|
19847
|
+
options : null
|
19345
19848
|
},
|
19346
19849
|
|
19347
19850
|
|
19348
19851
|
methods : {
|
19349
19852
|
|
19350
19853
|
process : function () {
|
19351
|
-
this.test.doubleClick(this.getTarget(), this.next)
|
19854
|
+
this.test.doubleClick(this.getTarget(), this.next, null, this.options)
|
19352
19855
|
}
|
19353
19856
|
}
|
19354
19857
|
});
|
19355
19858
|
|
19356
19859
|
|
19357
19860
|
Siesta.Test.ActionRegistry.registerAction('doubleclick', Siesta.Test.Action.DoubleClick)
|
19358
|
-
Siesta.Test.ActionRegistry.registerAction('doubletap', Siesta.Test.Action.DoubleClick)
|
19359
19861
|
;
|
19360
19862
|
/**
|
19361
19863
|
|
@@ -19402,6 +19904,7 @@ Class('Siesta.Test.Action.Type', {
|
|
19402
19904
|
// By default use the current focused element as target
|
19403
19905
|
this.target = this.target || this.test.global.document.activeElement;
|
19404
19906
|
|
19907
|
+
// additional "getTarget" to allow functions as "target" value
|
19405
19908
|
this.test.type(this.getTarget(), this.text, this.next)
|
19406
19909
|
}
|
19407
19910
|
}
|
@@ -19788,7 +20291,7 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
19788
20291
|
|
19789
20292
|
// Normalize target
|
19790
20293
|
if (!this.isArray(target)) {
|
19791
|
-
target = this.detectCenter(this.normalizeElement(target));
|
20294
|
+
target = this.detectCenter(this.normalizeElement(target), 'moveMouseTo');
|
19792
20295
|
}
|
19793
20296
|
this.moveMouse(this.currentPosition, target, callback, scope);
|
19794
20297
|
},
|
@@ -19900,12 +20403,12 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
19900
20403
|
queue.run(function () {
|
19901
20404
|
me.endAsync(a);
|
19902
20405
|
|
19903
|
-
callback &&
|
20406
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
19904
20407
|
})
|
19905
20408
|
},
|
19906
20409
|
|
19907
20410
|
|
19908
|
-
normalizeClickTarget : function (el) {
|
20411
|
+
normalizeClickTarget : function (el, clickMethod) {
|
19909
20412
|
var doc = this.global.document
|
19910
20413
|
var xy
|
19911
20414
|
|
@@ -19914,13 +20417,12 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
19914
20417
|
if (this.isArray(el)) {
|
19915
20418
|
xy = el;
|
19916
20419
|
el = doc.elementFromPoint(xy[0], xy[1]) || doc.body;
|
19917
|
-
options = { clientX : xy[0], clientY : xy[1] };
|
19918
20420
|
} else {
|
19919
20421
|
el = this.normalizeElement(el)
|
19920
20422
|
doc = el.ownerDocument
|
19921
|
-
xy = this.detectCenter(el);
|
20423
|
+
xy = this.detectCenter(el, clickMethod);
|
19922
20424
|
el = doc.elementFromPoint(xy[0], xy[1]) || doc.body;
|
19923
|
-
|
20425
|
+
el && this.$(el).is(':visible');
|
19924
20426
|
}
|
19925
20427
|
|
19926
20428
|
if (!el) {
|
@@ -19935,14 +20437,18 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
19935
20437
|
},
|
19936
20438
|
|
19937
20439
|
|
19938
|
-
genericMouseClick : function (el, callback, scope, clickMethod) {
|
20440
|
+
genericMouseClick : function (el, callback, scope, options, clickMethod) {
|
19939
20441
|
if (jQuery.isFunction(el)) {
|
19940
20442
|
scope = callback;
|
19941
20443
|
callback = el;
|
19942
20444
|
el = null;
|
19943
20445
|
}
|
19944
20446
|
|
19945
|
-
var data = this.normalizeClickTarget(el)
|
20447
|
+
var data = this.normalizeClickTarget(el, clickMethod);
|
20448
|
+
|
20449
|
+
data.options = data.options || {};
|
20450
|
+
|
20451
|
+
$.extend(data.options, options);
|
19946
20452
|
|
19947
20453
|
// the asynchronous case
|
19948
20454
|
if (this.moveCursorBetweenPoints && callback) {
|
@@ -19973,10 +20479,11 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
19973
20479
|
*
|
19974
20480
|
* @param {Siesta.Test.ActionTarget} (optional) el One of the {@link Siesta.Test.ActionTarget} values to convert to DOM element
|
19975
20481
|
* @param {Function} callback (optional) A function to call when the condition has been met.
|
19976
|
-
* @param {Object} scope (optional) The scope for the callback
|
20482
|
+
* @param {Object} scope (optional) The scope for the callback
|
20483
|
+
* @param {Object} options (optional) Any options to use for the simulated DOM event
|
19977
20484
|
*/
|
19978
|
-
click: function (el, callback, scope) {
|
19979
|
-
this.genericMouseClick(el, callback, scope, 'simulateMouseClick')
|
20485
|
+
click: function (el, callback, scope, options) {
|
20486
|
+
this.genericMouseClick(el, callback, scope, options, 'simulateMouseClick')
|
19980
20487
|
},
|
19981
20488
|
|
19982
20489
|
|
@@ -20000,10 +20507,11 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20000
20507
|
*
|
20001
20508
|
* @param {Siesta.Test.ActionTarget} (optional) el One of the {@link Siesta.Test.ActionTarget} values to convert to DOM element
|
20002
20509
|
* @param {Function} callback (optional) A function to call when the condition has been met.
|
20003
|
-
* @param {Object} scope (optional) The scope for the callback
|
20510
|
+
* @param {Object} scope (optional) The scope for the callback
|
20511
|
+
* @param {Object} options (optional) Any options to use for the simulated DOM event
|
20004
20512
|
*/
|
20005
|
-
rightClick: function (el, callback, scope) {
|
20006
|
-
this.genericMouseClick(el, callback, scope, 'simulateRightClick')
|
20513
|
+
rightClick: function (el, callback, scope, options) {
|
20514
|
+
this.genericMouseClick(el, callback, scope, options, 'simulateRightClick')
|
20007
20515
|
},
|
20008
20516
|
|
20009
20517
|
|
@@ -20027,10 +20535,11 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20027
20535
|
*
|
20028
20536
|
* @param {Siesta.Test.ActionTarget} (optional) el One of the {@link Siesta.Test.ActionTarget} values to convert to DOM element
|
20029
20537
|
* @param {Function} callback (optional) A function to call when the condition has been met.
|
20030
|
-
* @param {Object} scope (optional) The scope for the callback
|
20538
|
+
* @param {Object} scope (optional) The scope for the callback
|
20539
|
+
* @param {Object} options (optional) Any options to use for the simulated DOM event
|
20031
20540
|
*/
|
20032
|
-
doubleClick: function (el, callback, scope) {
|
20033
|
-
this.genericMouseClick(el, callback, scope, 'simulateDoubleClick')
|
20541
|
+
doubleClick: function (el, callback, scope, options) {
|
20542
|
+
this.genericMouseClick(el, callback, scope, options, 'simulateDoubleClick')
|
20034
20543
|
},
|
20035
20544
|
|
20036
20545
|
/**
|
@@ -20130,7 +20639,7 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20130
20639
|
queue.run(function () {
|
20131
20640
|
me.endAsync(async);
|
20132
20641
|
|
20133
|
-
callback &&
|
20642
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
20134
20643
|
})
|
20135
20644
|
},
|
20136
20645
|
|
@@ -20169,7 +20678,7 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20169
20678
|
queue.run(function () {
|
20170
20679
|
me.endAsync(async);
|
20171
20680
|
|
20172
|
-
callback &&
|
20681
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
20173
20682
|
})
|
20174
20683
|
},
|
20175
20684
|
|
@@ -20212,7 +20721,7 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20212
20721
|
queue.run(function () {
|
20213
20722
|
me.endAsync(async);
|
20214
20723
|
|
20215
|
-
callback &&
|
20724
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
20216
20725
|
})
|
20217
20726
|
},
|
20218
20727
|
|
@@ -20285,7 +20794,7 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20285
20794
|
if (this.isArray(source)) {
|
20286
20795
|
sourceXY = source;
|
20287
20796
|
} else {
|
20288
|
-
sourceXY = this.detectCenter(this.normalizeElement(source));
|
20797
|
+
sourceXY = this.detectCenter(this.normalizeElement(source), 'dragTo');
|
20289
20798
|
}
|
20290
20799
|
|
20291
20800
|
// Normalize target
|
@@ -20328,7 +20837,7 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20328
20837
|
if (this.isArray(source)) {
|
20329
20838
|
sourceXY = source;
|
20330
20839
|
} else {
|
20331
|
-
sourceXY = this.detectCenter(this.normalizeElement(source));
|
20840
|
+
sourceXY = this.detectCenter(this.normalizeElement(source), 'dragBy');
|
20332
20841
|
}
|
20333
20842
|
targetXY = [ sourceXY[0] + delta[0], sourceXY[1] + delta[1] ];
|
20334
20843
|
|
@@ -20422,16 +20931,21 @@ Role('Siesta.Test.Simulate.Mouse', {
|
|
20422
20931
|
queue.run(function () {
|
20423
20932
|
me.endAsync(async)
|
20424
20933
|
|
20425
|
-
callback &&
|
20934
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
20426
20935
|
});
|
20427
20936
|
},
|
20428
20937
|
|
20429
|
-
detectCenter : function(el) {
|
20938
|
+
detectCenter : function (el, actionName, skipWarning) {
|
20430
20939
|
var hidden = !this.isElementVisible(el);
|
20431
20940
|
|
20432
20941
|
// Trigger mouseover in case source is hidden, possibly shown only when hovering over it (its x/y cannot be determined if display:none)
|
20433
20942
|
if (hidden) {
|
20434
|
-
this.simulateEvent(el, "mouseover", { clientX: 0, clientY: 0});
|
20943
|
+
this.simulateEvent(el, "mouseover", { clientX: 0, clientY: 0 });
|
20944
|
+
|
20945
|
+
if (!skipWarning && !this.isElementVisible(el)) this.fail(
|
20946
|
+
(actionName ? "Target element of action [" + actionName + "]" : "Target element of some action") +
|
20947
|
+
" is not visible: " + (el.id ? '#' + el.id : el)
|
20948
|
+
)
|
20435
20949
|
}
|
20436
20950
|
var center = this.findCenter(el);
|
20437
20951
|
if (hidden) {
|
@@ -20774,21 +21288,22 @@ Role('Siesta.Test.Simulate.Keyboard', {
|
|
20774
21288
|
* @param {Object} scope (optional) the scope for the callback
|
20775
21289
|
*/
|
20776
21290
|
type: function (el, text, callback, scope) {
|
20777
|
-
el = this.normalizeElement(el || this.
|
21291
|
+
el = this.normalizeElement(el || this.global.document.activeElement);
|
20778
21292
|
|
20779
21293
|
// Some browsers (IE/FF) do not overwrite selected text, do it manually.
|
20780
21294
|
var selText = this.getSelectedText(el);
|
21295
|
+
|
20781
21296
|
if (selText) {
|
20782
21297
|
el.value = el.value.replace(selText, '');
|
20783
21298
|
}
|
20784
21299
|
|
21300
|
+
var me = this
|
21301
|
+
|
20785
21302
|
if (el.readOnly || el.disabled) {
|
20786
|
-
callback &&
|
21303
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
20787
21304
|
|
20788
21305
|
return;
|
20789
21306
|
}
|
20790
|
-
|
20791
|
-
var me = this
|
20792
21307
|
|
20793
21308
|
// Extract normal chars, or special keys in brackets such as [TAB], [RIGHT] or [ENTER]
|
20794
21309
|
var keys = (text + '').match(/\[([^\])]+\])|([^\[])/g) || [];
|
@@ -20838,7 +21353,7 @@ Role('Siesta.Test.Simulate.Keyboard', {
|
|
20838
21353
|
queue.run(function () {
|
20839
21354
|
me.endAsync(async)
|
20840
21355
|
|
20841
|
-
callback &&
|
21356
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
20842
21357
|
})
|
20843
21358
|
},
|
20844
21359
|
|
@@ -21125,6 +21640,37 @@ Role('Siesta.Test.ExtJSCore', {
|
|
21125
21640
|
return {
|
21126
21641
|
ready : true
|
21127
21642
|
}
|
21643
|
+
},
|
21644
|
+
|
21645
|
+
// Overridden to deal with the different event firing mechanisms in Ext JS 3 vs 4
|
21646
|
+
// This code is required because in IE are simulated using fireEvent instead of dispatchEvent and it seems fireEvent will
|
21647
|
+
// will not update a checkbox 'checked' state properly so we're forcing the toggle to solve this situation.
|
21648
|
+
// This issue is only relevant in IE + Ext.
|
21649
|
+
//
|
21650
|
+
// Test case: 507_form_checkbox.t.js
|
21651
|
+
simulateMouseClick: function (el, callback, scope) {
|
21652
|
+
|
21653
|
+
// Force check toggle for input checkboxes
|
21654
|
+
if (this.simulateEventsWith === 'fireEvent' && (el.type === 'checkbox' || el.type === 'radio') && !el.disabled && !el.readOnly) {
|
21655
|
+
var oldState = el.checked;
|
21656
|
+
|
21657
|
+
if (callback) {
|
21658
|
+
this.SUPER(el, function() {
|
21659
|
+
if (el.checked === oldState) {
|
21660
|
+
el.checked = !oldState;
|
21661
|
+
}
|
21662
|
+
callback.call(scope || this);
|
21663
|
+
});
|
21664
|
+
} else {
|
21665
|
+
this.SUPER(el);
|
21666
|
+
|
21667
|
+
if (el.checked === oldState) {
|
21668
|
+
el.checked = !oldState;
|
21669
|
+
}
|
21670
|
+
}
|
21671
|
+
} else {
|
21672
|
+
this.SUPERARG(arguments);
|
21673
|
+
}
|
21128
21674
|
}
|
21129
21675
|
},
|
21130
21676
|
|
@@ -21228,11 +21774,33 @@ Role('Siesta.Test.ExtJSCore', {
|
|
21228
21774
|
|
21229
21775
|
return component;
|
21230
21776
|
},
|
21231
|
-
|
21232
|
-
|
21233
|
-
|
21777
|
+
|
21778
|
+
/**
|
21779
|
+
* @private
|
21780
|
+
* @param {Ext.Component} comp the Ext.Component
|
21781
|
+
* @param {Boolean} locateInputEl For form fields, try to find the inner input element by default.
|
21782
|
+
* If you want to target the containing Component element, pass false instead.
|
21783
|
+
* @return {*}
|
21784
|
+
*/
|
21785
|
+
compToEl : function (comp, locateInputEl) {
|
21786
|
+
var Ext = this.Ext();
|
21787
|
+
|
21234
21788
|
if (!comp) return null
|
21235
|
-
|
21789
|
+
|
21790
|
+
locateInputEl = locateInputEl !== false;
|
21791
|
+
|
21792
|
+
// Ext JS
|
21793
|
+
if (Ext && Ext.form && Ext.form.Field && locateInputEl) {
|
21794
|
+
if (comp instanceof Ext.form.Field && comp.inputEl){
|
21795
|
+
return comp.inputEl;
|
21796
|
+
}
|
21797
|
+
}
|
21798
|
+
|
21799
|
+
// Sencha Touch: Form fields can have a child input component
|
21800
|
+
if (Ext && Ext.field && Ext.field.Field && comp instanceof Ext.field.Field && locateInputEl) {
|
21801
|
+
comp = comp.getComponent();
|
21802
|
+
}
|
21803
|
+
|
21236
21804
|
// Ext JS vs Sencha Touch
|
21237
21805
|
return comp.getEl ? comp.getEl() : (comp.el || comp.element);
|
21238
21806
|
},
|
@@ -21262,17 +21830,14 @@ Role('Siesta.Test.ExtJSCore', {
|
|
21262
21830
|
}
|
21263
21831
|
}
|
21264
21832
|
|
21265
|
-
if (
|
21266
|
-
el = el
|
21267
|
-
|
21268
|
-
|
21269
|
-
|
21270
|
-
|
21271
|
-
|
21272
|
-
|
21273
|
-
}
|
21274
|
-
|
21275
|
-
// ExtJS Element
|
21833
|
+
if (Ext && Ext.Component && el instanceof Ext.Component) {
|
21834
|
+
el = this.compToEl(el);
|
21835
|
+
var center = this.findCenter(el);
|
21836
|
+
|
21837
|
+
el = this.elementFromPoint(center[0], center[1]) || el;
|
21838
|
+
}
|
21839
|
+
|
21840
|
+
// ExtJS Element
|
21276
21841
|
if (el && el.dom) return el.dom
|
21277
21842
|
|
21278
21843
|
// will also handle the case of conversion of array with coordinates to el
|
@@ -21373,7 +21938,7 @@ Role('Siesta.Test.ExtJSCore', {
|
|
21373
21938
|
me.fail("Class: " + className + " was loaded")
|
21374
21939
|
})
|
21375
21940
|
|
21376
|
-
callback && callback
|
21941
|
+
callback && me.processCallbackFromTest(callback)
|
21377
21942
|
}
|
21378
21943
|
|
21379
21944
|
var timeout = Ext.isIE ? 120000 : 30000,
|
@@ -21487,8 +22052,9 @@ Role('Siesta.Test.ExtJSCore', {
|
|
21487
22052
|
cmp = cmp[0];
|
21488
22053
|
|
21489
22054
|
if (!cmp.rendered) throw 'The source component of the composite query: ' + cmp.id + ' is not yet rendered';
|
21490
|
-
|
21491
|
-
|
22055
|
+
|
22056
|
+
|
22057
|
+
return this.compToEl(cmp, false).query(result[1]);
|
21492
22058
|
},
|
21493
22059
|
|
21494
22060
|
/**
|
@@ -21766,7 +22332,7 @@ Role('Siesta.Test.ExtJS.Observable', {
|
|
21766
22332
|
annotation : n + " '" + event + "' events were expected, but " + counter + ' were fired'
|
21767
22333
|
});
|
21768
22334
|
|
21769
|
-
callback && callback
|
22335
|
+
callback && me.processCallbackFromTest(callback);
|
21770
22336
|
|
21771
22337
|
}, timeOut);
|
21772
22338
|
|
@@ -22302,7 +22868,9 @@ Role('Siesta.Test.ExtJS.Component', {
|
|
22302
22868
|
* @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.
|
22303
22869
|
*/
|
22304
22870
|
waitForComponent: function (component, rendered, callback, scope, timeout) {
|
22305
|
-
var Ext
|
22871
|
+
var Ext = this.getExt();
|
22872
|
+
var xtype
|
22873
|
+
|
22306
22874
|
if (Ext.isString(component)) {
|
22307
22875
|
xtype = Ext.ClassManager.get(component).xtype;
|
22308
22876
|
} else {
|
@@ -22340,6 +22908,75 @@ Role('Siesta.Test.ExtJS.Component', {
|
|
22340
22908
|
hasPosition: function (component, x, y, description) {
|
22341
22909
|
component = this.normalizeComponent(component);
|
22342
22910
|
this.isDeeply(component.getPosition(), [x, y], description);
|
22911
|
+
},
|
22912
|
+
|
22913
|
+
|
22914
|
+
/**
|
22915
|
+
* This assertion accepts variable number of Ext.Component instances (can be also provided as component query string).
|
22916
|
+
* Then it calls their "destroy" method and verifies that:
|
22917
|
+
* - there were no exceptions during destroy
|
22918
|
+
* - that each component was actually destoyed (since destroy can be canceled in the "beforedestroy" event listener)
|
22919
|
+
*
|
22920
|
+
* @param {Ext.Component/Array[Ext.Component]/String} components A single instance of Ext.Component, an array of such or a string with component query
|
22921
|
+
* @param {String} description The description of the assertion
|
22922
|
+
*/
|
22923
|
+
destroysOk : function (components, description) {
|
22924
|
+
var Ext = this.Ext();
|
22925
|
+
|
22926
|
+
if (this.typeOf(components) != 'Array') {
|
22927
|
+
if (this.typeOf(components) == 'String')
|
22928
|
+
components = this.Ext().ComponentQuery.query(components);
|
22929
|
+
else
|
22930
|
+
components = [ components ]
|
22931
|
+
}
|
22932
|
+
|
22933
|
+
if (!components.length) {
|
22934
|
+
this.fail(description, {
|
22935
|
+
assertionName : 'destroysOk',
|
22936
|
+
annotation : 'No components provided, or component query returned empty result'
|
22937
|
+
})
|
22938
|
+
|
22939
|
+
return
|
22940
|
+
}
|
22941
|
+
|
22942
|
+
var currentComp
|
22943
|
+
|
22944
|
+
var e = this.getExceptionCatcher()(function () {
|
22945
|
+
Joose.A.each(components, function (component) {
|
22946
|
+
currentComp = component
|
22947
|
+
|
22948
|
+
component.destroy()
|
22949
|
+
})
|
22950
|
+
})
|
22951
|
+
|
22952
|
+
if (e !== undefined) {
|
22953
|
+
this.fail(description, {
|
22954
|
+
assertionName : 'destroysOk',
|
22955
|
+
got : e,
|
22956
|
+
gotDesc : 'Exception',
|
22957
|
+
annotation : 'Exception thrown while calling "destroy" method of ' + currentComp.id
|
22958
|
+
})
|
22959
|
+
|
22960
|
+
return
|
22961
|
+
}
|
22962
|
+
|
22963
|
+
var me = this
|
22964
|
+
|
22965
|
+
var allDestroyed = Joose.A.each(components, function (component) {
|
22966
|
+
// ExtJS ST
|
22967
|
+
if (!(component.isDestroyed || component.destroy == Ext.emptyFn)) {
|
22968
|
+
me.fail(description, {
|
22969
|
+
assertionName : 'destroysOk',
|
22970
|
+
annotation : 'Component [' + component.id + '] was not destroyed (probably destroy was canceled in the `beforedestroy` listener)'
|
22971
|
+
})
|
22972
|
+
|
22973
|
+
return false
|
22974
|
+
}
|
22975
|
+
})
|
22976
|
+
|
22977
|
+
if (allDestroyed === false) return
|
22978
|
+
|
22979
|
+
this.pass(description)
|
22343
22980
|
}
|
22344
22981
|
}
|
22345
22982
|
});
|
@@ -22568,13 +23205,14 @@ Role('Siesta.Test.Element', {
|
|
22568
23205
|
|
22569
23206
|
|
22570
23207
|
/**
|
22571
|
-
* Returns true if the element is visible.
|
23208
|
+
* Returns true if the element is visible, checking jQuery :visible selector + style visibilty value.
|
22572
23209
|
* @param {Siesta.Test.ActionTarget} el The element
|
22573
23210
|
* @return {Boolean}
|
22574
23211
|
*/
|
22575
23212
|
isElementVisible : function(el) {
|
22576
23213
|
el = this.normalizeElement(el);
|
22577
|
-
|
23214
|
+
// Jquery :visible doesn't take visibility into account
|
23215
|
+
return !!el && this.$(el).is(':visible') && el.style.visibility !== 'hidden';
|
22578
23216
|
},
|
22579
23217
|
|
22580
23218
|
/**
|
@@ -22750,7 +23388,7 @@ Role('Siesta.Test.Element', {
|
|
22750
23388
|
assertionChecker()
|
22751
23389
|
}
|
22752
23390
|
|
22753
|
-
callback &&
|
23391
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
22754
23392
|
});
|
22755
23393
|
},
|
22756
23394
|
|
@@ -23170,11 +23808,11 @@ Role('Siesta.Test.Element', {
|
|
23170
23808
|
this.fail(description, {
|
23171
23809
|
assertionName : 'elementIsAt',
|
23172
23810
|
got : { x: xy[0], y : xy[1] },
|
23173
|
-
gotDesc : '
|
23811
|
+
gotDesc : 'Position',
|
23174
23812
|
annotation : 'No element found at the specified position'
|
23175
23813
|
});
|
23176
23814
|
} else if (allowChildren) {
|
23177
|
-
if (foundEl === el || $(foundEl).closest(el)) {
|
23815
|
+
if (foundEl === el || $(foundEl).closest(el).length > 0) {
|
23178
23816
|
this.pass(description);
|
23179
23817
|
} else {
|
23180
23818
|
this.fail(description, {
|
@@ -23272,21 +23910,14 @@ Role('Siesta.Test.Element', {
|
|
23272
23910
|
|
23273
23911
|
var foundEl = this.$(doc.elementFromPoint(xy[0], xy[1]) || doc.body);
|
23274
23912
|
|
23275
|
-
if (!foundEl) {
|
23276
|
-
this.fail(description, {
|
23277
|
-
assertionName : 'selectorIsAt',
|
23278
|
-
got : { x: xy[0], y : xy[1] },
|
23279
|
-
gotDesc : 'Postion',
|
23280
|
-
annotation : 'No element matching the passed selector found at the specified position'
|
23281
|
-
});
|
23282
|
-
}
|
23283
|
-
|
23284
23913
|
if (foundEl.has(selector).length > 0 || foundEl.closest(selector).length > 0) {
|
23285
23914
|
this.pass(description);
|
23286
23915
|
} else {
|
23287
23916
|
this.fail(description, {
|
23917
|
+
got : foundEl[0].outerHTML ? foundEl[0].outerHTML : foundEl[0].innerHTML,
|
23918
|
+
need : 'Element matching ' + selector,
|
23288
23919
|
assertionName : 'selectorIsAt',
|
23289
|
-
annotation : 'Passed selector does not match
|
23920
|
+
annotation : 'Passed selector does not match any selector at [' + xy + ']'
|
23290
23921
|
});
|
23291
23922
|
}
|
23292
23923
|
},
|
@@ -23413,7 +24044,11 @@ Role('Siesta.Test.Element', {
|
|
23413
24044
|
})
|
23414
24045
|
})
|
23415
24046
|
|
23416
|
-
|
24047
|
+
var me = this
|
24048
|
+
|
24049
|
+
if (callback) steps.push(function () {
|
24050
|
+
me.processCallbackFromTest(callback)
|
24051
|
+
})
|
23417
24052
|
|
23418
24053
|
this.chain.apply(this, steps)
|
23419
24054
|
},
|
@@ -23430,7 +24065,7 @@ Role('Siesta.Test.Element', {
|
|
23430
24065
|
*
|
23431
24066
|
* t.clickSelector('.my-grid .x-grid-row', function () {})
|
23432
24067
|
*
|
23433
|
-
* The provided callback will receive
|
24068
|
+
* The provided callback will receive an array with DOM elements - result of query.
|
23434
24069
|
*
|
23435
24070
|
*
|
23436
24071
|
* @param {String} selector The selector/xpath query
|
@@ -23726,7 +24361,7 @@ Class('Siesta.Test.Browser', {
|
|
23726
24361
|
annotation : n + " '" + event + "' events were expected, but " + counter + ' were fired'
|
23727
24362
|
});
|
23728
24363
|
|
23729
|
-
callback && callback
|
24364
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
23730
24365
|
|
23731
24366
|
}, timeOut);
|
23732
24367
|
|
@@ -23893,7 +24528,47 @@ Class('Siesta.Test.SenchaTouch', {
|
|
23893
24528
|
},
|
23894
24529
|
|
23895
24530
|
methods : {
|
23896
|
-
|
24531
|
+
getTouchBundlePath : function() {
|
24532
|
+
var path;
|
24533
|
+
var testDescriptor = this.harness.getScriptDescriptor(this.url)
|
24534
|
+
|
24535
|
+
while (testDescriptor && !path) {
|
24536
|
+
if (testDescriptor.preload) {
|
24537
|
+
Joose.A.each(testDescriptor.preload, function (url) {
|
24538
|
+
if (url.match && url.match(/(.*sencha-touch-\d\.\d+\.\d+.*?)\/sencha-touch(.*)\.js/)) {
|
24539
|
+
path = url;
|
24540
|
+
return false;
|
24541
|
+
}
|
24542
|
+
});
|
24543
|
+
}
|
24544
|
+
testDescriptor = testDescriptor.parent;
|
24545
|
+
}
|
24546
|
+
|
24547
|
+
return path;
|
24548
|
+
},
|
24549
|
+
|
24550
|
+
|
24551
|
+
getTouchBundleFolder : function() {
|
24552
|
+
var folder;
|
24553
|
+
var testDescriptor = this.harness.getScriptDescriptor(this.url)
|
24554
|
+
|
24555
|
+
while (testDescriptor && !folder) {
|
24556
|
+
if (testDescriptor.preload) {
|
24557
|
+
Joose.A.each(testDescriptor.preload, function (url) {
|
24558
|
+
var regex = /(.*sencha-touch-\d\.\d+\.\d+.*?)\/sencha-touch(.*)\.js/;
|
24559
|
+
var match = regex.exec(url);
|
24560
|
+
|
24561
|
+
if (match) {
|
24562
|
+
folder = match[1];
|
24563
|
+
}
|
24564
|
+
});
|
24565
|
+
}
|
24566
|
+
testDescriptor = testDescriptor.parent;
|
24567
|
+
}
|
24568
|
+
|
24569
|
+
return folder;
|
24570
|
+
},
|
24571
|
+
|
23897
24572
|
/**
|
23898
24573
|
* This method taps the passed target, which can be of several different types, see {@link Siesta.Test.ActionTarget}
|
23899
24574
|
*
|
@@ -23902,7 +24577,33 @@ Class('Siesta.Test.SenchaTouch', {
|
|
23902
24577
|
* @param {Object} scope (optional) The scope for the callback
|
23903
24578
|
*/
|
23904
24579
|
tap: function (target, callback, scope) {
|
23905
|
-
|
24580
|
+
var me = this;
|
24581
|
+
|
24582
|
+
target = this.normalizeElement(target);
|
24583
|
+
|
24584
|
+
var queue = new Siesta.Util.Queue({
|
24585
|
+
deferer : this.originalSetTimeout,
|
24586
|
+
deferClearer : this.originalClearTimeout,
|
24587
|
+
|
24588
|
+
interval : callback ? 30 : 0,
|
24589
|
+
|
24590
|
+
observeTest : this,
|
24591
|
+
|
24592
|
+
processor : function (data) {
|
24593
|
+
me.simulateEvent.apply(me, data);
|
24594
|
+
}
|
24595
|
+
})
|
24596
|
+
|
24597
|
+
queue.addStep([ target, "mousedown", {}, false ])
|
24598
|
+
queue.addStep([ target, "mouseup", {}, true ])
|
24599
|
+
|
24600
|
+
var async = me.beginAsync();
|
24601
|
+
|
24602
|
+
queue.run(function () {
|
24603
|
+
me.endAsync(async);
|
24604
|
+
|
24605
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
24606
|
+
})
|
23906
24607
|
},
|
23907
24608
|
|
23908
24609
|
/**
|
@@ -23913,7 +24614,36 @@ Class('Siesta.Test.SenchaTouch', {
|
|
23913
24614
|
* @param {Object} scope (optional) The scope for the callback
|
23914
24615
|
*/
|
23915
24616
|
doubleTap: function (target, callback, scope) {
|
23916
|
-
|
24617
|
+
var me = this;
|
24618
|
+
|
24619
|
+
target = this.normalizeElement(target);
|
24620
|
+
|
24621
|
+
var queue = new Siesta.Util.Queue({
|
24622
|
+
deferer : this.originalSetTimeout,
|
24623
|
+
deferClearer : this.originalClearTimeout,
|
24624
|
+
|
24625
|
+
interval : callback ? 30 : 0,
|
24626
|
+
|
24627
|
+
observeTest : this,
|
24628
|
+
|
24629
|
+
processor : function (data) {
|
24630
|
+
me.simulateEvent.apply(me, data);
|
24631
|
+
}
|
24632
|
+
})
|
24633
|
+
|
24634
|
+
queue.addStep([ target, "mousedown", {}, false ])
|
24635
|
+
queue.addStep([ target, "mouseup", {}, true ])
|
24636
|
+
|
24637
|
+
queue.addStep([ target, "mousedown", {}, false ])
|
24638
|
+
queue.addStep([ target, "mouseup", {}, true ])
|
24639
|
+
|
24640
|
+
var async = me.beginAsync();
|
24641
|
+
|
24642
|
+
queue.run(function () {
|
24643
|
+
me.endAsync(async);
|
24644
|
+
|
24645
|
+
callback && me.processCallbackFromTest(callback, null, scope || me)
|
24646
|
+
})
|
23917
24647
|
},
|
23918
24648
|
|
23919
24649
|
/**
|
@@ -23925,11 +24655,17 @@ Class('Siesta.Test.SenchaTouch', {
|
|
23925
24655
|
*/
|
23926
24656
|
longpress: function (target, callback, scope) {
|
23927
24657
|
var Ext = this.Ext();
|
24658
|
+
var me = this;
|
23928
24659
|
|
23929
24660
|
this.simulateEvent(target, 'mousedown');
|
23930
24661
|
|
23931
24662
|
var amount = Ext.event.recognizer.LongPress.prototype.config.minDuration;
|
23932
|
-
|
24663
|
+
|
24664
|
+
this.waitFor(amount, function() {
|
24665
|
+
me.simulateEvent(target, 'mouseup');
|
24666
|
+
|
24667
|
+
callback.call(scope || me);
|
24668
|
+
});
|
23933
24669
|
},
|
23934
24670
|
|
23935
24671
|
/**
|
@@ -23948,30 +24684,41 @@ Class('Siesta.Test.SenchaTouch', {
|
|
23948
24684
|
start,
|
23949
24685
|
end,
|
23950
24686
|
edgeOffsetRatio = 10;
|
24687
|
+
|
24688
|
+
// Since this method accepts elements as target, we need to assure that we swipe at least about 150px
|
24689
|
+
// using Math.max below etc
|
23951
24690
|
|
23952
24691
|
switch(direction) {
|
23953
24692
|
case 'u':
|
23954
24693
|
case 'up':
|
23955
|
-
start
|
23956
|
-
end
|
24694
|
+
start = [box.x + box.width/2, (box.y + box.height*9/edgeOffsetRatio)];
|
24695
|
+
end = [box.x + box.width/2, box.y + box.height/edgeOffsetRatio];
|
24696
|
+
|
24697
|
+
end[1] = Math.min(start[1] - 100, end[1]);
|
23957
24698
|
break;
|
23958
24699
|
|
23959
24700
|
case 'd':
|
23960
24701
|
case 'down':
|
23961
|
-
start
|
23962
|
-
end
|
23963
|
-
break;
|
24702
|
+
start = [box.x + box.width/2, (box.y + box.height/edgeOffsetRatio)];
|
24703
|
+
end = [box.x + box.width/2, (box.y + box.height*9/edgeOffsetRatio)];
|
23964
24704
|
|
23965
|
-
|
23966
|
-
case 'left':
|
23967
|
-
start = [box.x + (box.width /edgeOffsetRatio), (box.y + box.height/2)];
|
23968
|
-
end = [box.x + (box.width * 9/edgeOffsetRatio), (box.y + box.height/2)];
|
24705
|
+
end[1] = Math.max(start[1] + 100, end[1]);
|
23969
24706
|
break;
|
23970
24707
|
|
23971
24708
|
case 'r':
|
23972
24709
|
case 'right':
|
23973
|
-
start
|
23974
|
-
end
|
24710
|
+
start = [box.x + (box.width /edgeOffsetRatio), (box.y + box.height/2)];
|
24711
|
+
end = [box.x + (box.width * 9/edgeOffsetRatio), (box.y + box.height/2)];
|
24712
|
+
|
24713
|
+
end[0] = Math.max(start[0] + 100, end[0]);
|
24714
|
+
break;
|
24715
|
+
|
24716
|
+
case 'l':
|
24717
|
+
case 'left':
|
24718
|
+
start = [box.x + (box.width * 9/edgeOffsetRatio), (box.y + box.height/2)];
|
24719
|
+
end = [box.x + (box.width /edgeOffsetRatio), (box.y + box.height/2)];
|
24720
|
+
|
24721
|
+
end[0] = Math.min(start[0] - 100, end[0]);
|
23975
24722
|
break;
|
23976
24723
|
|
23977
24724
|
default:
|
@@ -23981,6 +24728,42 @@ Class('Siesta.Test.SenchaTouch', {
|
|
23981
24728
|
this.dragTo(start, end, callback, scope);
|
23982
24729
|
},
|
23983
24730
|
|
24731
|
+
/**
|
24732
|
+
* This method will simulate a finger move to an xy-coordinate or an element (the center of it)
|
24733
|
+
*
|
24734
|
+
* @param {Siesta.Test.ActionTarget} target Target point to move the mouse to.
|
24735
|
+
* @param {Function} callback (optional) To run this method async, provide a callback method to be called after the operation is completed.
|
24736
|
+
* @param {Object} scope (optional) the scope for the callback
|
24737
|
+
*/
|
24738
|
+
moveFingerTo : function(target, callback, scope) {
|
24739
|
+
if (!target) {
|
24740
|
+
throw 'Trying to call moveFingerTo without a target';
|
24741
|
+
}
|
24742
|
+
|
24743
|
+
// Normalize target
|
24744
|
+
if (!this.isArray(target)) {
|
24745
|
+
target = this.detectCenter(this.normalizeElement(target), 'moveFingerTo');
|
24746
|
+
}
|
24747
|
+
this.moveMouse(this.currentPosition, target, callback, scope);
|
24748
|
+
},
|
24749
|
+
|
24750
|
+
/**
|
24751
|
+
* This method will simulate a finger move from current position relative by the x and y distances provided.
|
24752
|
+
*
|
24753
|
+
* @param {Siesta.Test.ActionTarget} target Target point to move the mouse to.
|
24754
|
+
* @param {Function} callback (optional) To run this method async, provide a callback method to be called after the operation is completed.
|
24755
|
+
* @param {Object} scope (optional) the scope for the callback
|
24756
|
+
*/
|
24757
|
+
moveFingerBy : function(delta, callback, scope) {
|
24758
|
+
if (!delta) {
|
24759
|
+
throw 'Trying to call moveFingerBy without relative distances';
|
24760
|
+
}
|
24761
|
+
|
24762
|
+
var targetXY = [ this.currentPosition[0] + delta[0], this.currentPosition[1] + delta[1] ];
|
24763
|
+
|
24764
|
+
this.moveMouseTo(targetXY, callback, scope);
|
24765
|
+
},
|
24766
|
+
|
23984
24767
|
// /**
|
23985
24768
|
// * This method will simulate a swipe operation between either two points or on a single DOM element.
|
23986
24769
|
// *
|
@@ -24038,7 +24821,7 @@ Class('Siesta.Test.SenchaTouch', {
|
|
24038
24821
|
var inner = function() {
|
24039
24822
|
if (checkerFn.call(scope || me, target)) {
|
24040
24823
|
// We're done
|
24041
|
-
|
24824
|
+
me.processCallbackFromTest(callback, null, scope || me)
|
24042
24825
|
} else {
|
24043
24826
|
me.swipe(target, direction, function() {
|
24044
24827
|
var as = me.beginAsync();
|
@@ -24443,7 +25226,9 @@ Class('Siesta.Harness.Browser', {
|
|
24443
25226
|
*/
|
24444
25227
|
viewportHeight : 768,
|
24445
25228
|
|
24446
|
-
needUI : true
|
25229
|
+
needUI : true,
|
25230
|
+
|
25231
|
+
isAutomated : false
|
24447
25232
|
},
|
24448
25233
|
|
24449
25234
|
|
@@ -24486,6 +25271,10 @@ Class('Siesta.Harness.Browser', {
|
|
24486
25271
|
|
24487
25272
|
onTestUpdate : function (test, result) {
|
24488
25273
|
if (this.viewport) this.viewport.onTestUpdate(test, result)
|
25274
|
+
|
25275
|
+
if ((result instanceof Siesta.Result.Diagnostic) && result.isWarning && this.needUI) {
|
25276
|
+
if (typeof console != 'undefined' && console.warn) console.warn(result + '')
|
25277
|
+
}
|
24489
25278
|
},
|
24490
25279
|
|
24491
25280
|
|
@@ -24522,11 +25311,6 @@ Class('Siesta.Harness.Browser', {
|
|
24522
25311
|
},
|
24523
25312
|
|
24524
25313
|
|
24525
|
-
isAutomated : function () {
|
24526
|
-
return false
|
24527
|
-
},
|
24528
|
-
|
24529
|
-
|
24530
25314
|
configure : function() {
|
24531
25315
|
this.SUPERARG(arguments);
|
24532
25316
|
|
@@ -24568,7 +25352,7 @@ Class('Siesta.Harness.Browser', {
|
|
24568
25352
|
|
24569
25353
|
// if we here, then we were requested to show the UI for automated launch
|
24570
25354
|
// auto-launch the test suite in this case
|
24571
|
-
if (me.isAutomated
|
25355
|
+
if (me.isAutomated) SUPER.apply(me, args)
|
24572
25356
|
};
|
24573
25357
|
|
24574
25358
|
if (Ext.setup) {
|
@@ -24603,7 +25387,7 @@ Class('Siesta.Harness.Browser', {
|
|
24603
25387
|
var sup = this.SUPER
|
24604
25388
|
|
24605
25389
|
// delay the super setup until dom ready
|
24606
|
-
if (!this.isAutomated
|
25390
|
+
if (!this.isAutomated) {
|
24607
25391
|
Ext.onReady(function () {
|
24608
25392
|
Siesta.supports.init();
|
24609
25393
|
|
@@ -24743,16 +25527,28 @@ Class('Siesta.Harness.Browser', {
|
|
24743
25527
|
|
24744
25528
|
|
24745
25529
|
showForcedIFrame : function (iframe, test) {
|
24746
|
-
|
24747
|
-
|
25530
|
+
$.rebindWindowContext(window);
|
25531
|
+
$(iframe).addClass('tr-iframe-forced')
|
25532
|
+
$(iframe).removeClass('tr-iframe-hidden')
|
24748
25533
|
|
24749
|
-
|
25534
|
+
$(iframe).center()
|
24750
25535
|
},
|
24751
25536
|
|
24752
25537
|
|
24753
25538
|
hideForcedIFrame : function (iframe) {
|
24754
|
-
|
24755
|
-
|
25539
|
+
$.rebindWindowContext(window);
|
25540
|
+
$(iframe).removeClass('tr-iframe-forced')
|
25541
|
+
$(iframe).addClass('tr-iframe-hidden')
|
25542
|
+
},
|
25543
|
+
|
25544
|
+
getQueryParam : function (paramName) {
|
25545
|
+
var regex = new RegExp('(?:\\?|&)' + paramName + '=(.*?)(?:\\?|&|$)', 'i')
|
25546
|
+
|
25547
|
+
var match = regex.exec(window.location.search)
|
25548
|
+
|
25549
|
+
if (!match) return null
|
25550
|
+
|
25551
|
+
return match[ 1 ]
|
24756
25552
|
}
|
24757
25553
|
}
|
24758
25554
|
|
@@ -24931,160 +25727,179 @@ Ext.Container.override({
|
|
24931
25727
|
}
|
24932
25728
|
})
|
24933
25729
|
;
|
24934
|
-
|
24935
|
-
|
25730
|
+
(function () {
|
25731
|
+
var config = {
|
25732
|
+
idProperty : 'id',
|
24936
25733
|
|
24937
|
-
|
24938
|
-
|
24939
|
-
|
24940
|
-
|
24941
|
-
|
24942
|
-
|
24943
|
-
|
24944
|
-
|
24945
|
-
|
24946
|
-
|
24947
|
-
|
24948
|
-
|
24949
|
-
|
24950
|
-
|
24951
|
-
|
24952
|
-
|
25734
|
+
fields : [
|
25735
|
+
'id',
|
25736
|
+
'url',
|
25737
|
+
|
25738
|
+
'title',
|
25739
|
+
|
25740
|
+
{ name : 'passCount', type : 'int', defaultValue : 0 },
|
25741
|
+
{ name : 'failCount', type : 'int', defaultValue : 0 },
|
25742
|
+
{ name : 'todoPassCount', type : 'int', defaultValue : 0 },
|
25743
|
+
{ name : 'todoFailCount', type : 'int', defaultValue : 0 },
|
25744
|
+
|
25745
|
+
{ name : 'time', type : 'int', defaultValue : 0 },
|
25746
|
+
|
25747
|
+
{
|
25748
|
+
name : 'checked',
|
25749
|
+
defaultValue : false
|
25750
|
+
},
|
25751
|
+
|
25752
|
+
{
|
25753
|
+
name : 'folderStatus',
|
25754
|
+
defaultValue : 'yellow'
|
25755
|
+
},
|
25756
|
+
|
25757
|
+
// will be set to true for all tests, once the users clicks "run"
|
25758
|
+
'isStarting',
|
25759
|
+
// will be set to true, right before the scope preload begin
|
25760
|
+
'isStarted',
|
25761
|
+
// will be set to true, after preload ends and tests launch
|
25762
|
+
{ name : 'isRunning', type : 'boolean', defaultValue : false },
|
25763
|
+
{ name : 'isMissing', type : 'boolean', defaultValue : false },
|
25764
|
+
{ name : 'isFailed', type : 'boolean', defaultValue : false },
|
25765
|
+
|
25766
|
+
// composite objects
|
25767
|
+
'assertionsStore',
|
25768
|
+
'test',
|
25769
|
+
'descriptor'
|
25770
|
+
]
|
25771
|
+
};
|
25772
|
+
|
25773
|
+
Ext.define('Siesta.Harness.Browser.Model.TestFile', Ext.apply({
|
25774
|
+
|
25775
|
+
extend : 'Ext.data.Model',
|
25776
|
+
|
25777
|
+
init : function () {
|
25778
|
+
this.internalId = this.getId() || this.internalId
|
24953
25779
|
},
|
24954
|
-
|
24955
|
-
{
|
24956
|
-
name : 'folderStatus',
|
24957
|
-
defaultValue : 'yellow'
|
24958
|
-
},
|
24959
|
-
|
24960
|
-
// will be set to true for all tests, once the users clicks "run"
|
24961
|
-
'isStarting',
|
24962
|
-
// will be set to true, right before the scope preload begin
|
24963
|
-
'isStarted',
|
24964
|
-
// will be set to true, after preload ends and tests launch
|
24965
|
-
{ name : 'isRunning', type : 'boolean', defaultValue : false },
|
24966
|
-
{ name : 'isMissing', type : 'boolean', defaultValue : false },
|
24967
|
-
{ name : 'isFailed', type : 'boolean', defaultValue : false },
|
24968
|
-
|
24969
|
-
// composite objects
|
24970
|
-
'assertionsStore',
|
24971
|
-
'test',
|
24972
|
-
'descriptor'
|
24973
|
-
]
|
24974
|
-
};
|
24975
25780
|
|
24976
|
-
Ext.define('Siesta.Harness.Browser.Model.TestFile', Ext.apply({
|
24977
25781
|
|
24978
|
-
|
25782
|
+
computeFolderStatus : function () {
|
25783
|
+
if (!this.childNodes.length) return 'yellow'
|
24979
25784
|
|
24980
|
-
|
24981
|
-
|
24982
|
-
|
25785
|
+
var isWorking = false
|
25786
|
+
var hasFailed = false
|
25787
|
+
var allGreen = true
|
24983
25788
|
|
25789
|
+
Joose.A.each(this.childNodes, function (childNode) {
|
24984
25790
|
|
24985
|
-
|
24986
|
-
|
24987
|
-
|
24988
|
-
|
24989
|
-
|
24990
|
-
|
24991
|
-
|
24992
|
-
|
24993
|
-
|
24994
|
-
|
24995
|
-
|
24996
|
-
|
24997
|
-
|
24998
|
-
allGreen
|
24999
|
-
|
25000
|
-
|
25001
|
-
|
25002
|
-
|
25003
|
-
|
25004
|
-
|
25005
|
-
|
25006
|
-
|
25007
|
-
|
25008
|
-
|
25009
|
-
|
25010
|
-
|
25011
|
-
|
25012
|
-
|
25013
|
-
|
25014
|
-
|
25015
|
-
|
25016
|
-
|
25017
|
-
|
25018
|
-
|
25019
|
-
|
25020
|
-
|
25021
|
-
if (status == 'working') {
|
25022
|
-
isWorking = true
|
25023
|
-
|
25024
|
-
// stop iteration
|
25025
|
-
return false
|
25791
|
+
if (childNode.isLeaf()) {
|
25792
|
+
var test = childNode.get('test')
|
25793
|
+
|
25794
|
+
if (test && test.isFailed()) {
|
25795
|
+
allGreen = false
|
25796
|
+
hasFailed = true
|
25797
|
+
|
25798
|
+
// stop iteration
|
25799
|
+
return false
|
25800
|
+
}
|
25801
|
+
|
25802
|
+
if (!test && childNode.get('isStarting')) isWorking = true
|
25803
|
+
if (test && !test.isFinished()) isWorking = true
|
25804
|
+
if (test && !test.isPassed()) allGreen = false
|
25805
|
+
if (!test) allGreen = false
|
25806
|
+
|
25807
|
+
} else {
|
25808
|
+
var status = childNode.computeFolderStatus()
|
25809
|
+
|
25810
|
+
if (status == 'red') {
|
25811
|
+
allGreen = false
|
25812
|
+
hasFailed = true
|
25813
|
+
|
25814
|
+
// stop iteration
|
25815
|
+
return false
|
25816
|
+
}
|
25817
|
+
|
25818
|
+
if (status == 'working') {
|
25819
|
+
isWorking = true
|
25820
|
+
|
25821
|
+
// stop iteration
|
25822
|
+
return false
|
25823
|
+
}
|
25824
|
+
|
25825
|
+
if (status == 'yellow') allGreen = false
|
25026
25826
|
}
|
25027
|
-
|
25028
|
-
if (status == 'yellow') allGreen = false
|
25029
|
-
}
|
25030
|
-
})
|
25031
|
-
|
25032
|
-
if (isWorking) return 'working'
|
25033
|
-
if (hasFailed) return 'red'
|
25034
|
-
if (allGreen) return 'green'
|
25035
|
-
|
25036
|
-
return 'yellow'
|
25037
|
-
},
|
25827
|
+
})
|
25038
25828
|
|
25829
|
+
if (isWorking) return 'working'
|
25830
|
+
if (hasFailed) return 'red'
|
25831
|
+
if (allGreen) return 'green'
|
25039
25832
|
|
25040
|
-
|
25041
|
-
|
25042
|
-
|
25043
|
-
|
25044
|
-
|
25045
|
-
|
25046
|
-
},
|
25833
|
+
return 'yellow'
|
25834
|
+
},
|
25835
|
+
|
25836
|
+
|
25837
|
+
updateFolderStatus : function () {
|
25838
|
+
this.set('folderStatus', this.computeFolderStatus())
|
25047
25839
|
|
25048
|
-
|
25049
|
-
var failed = [];
|
25050
|
-
var as = this.get('assertionsStore');
|
25840
|
+
var parentNode = this.parentNode
|
25051
25841
|
|
25052
|
-
|
25053
|
-
|
25054
|
-
|
25055
|
-
|
25842
|
+
if (parentNode && !parentNode.isRoot()) parentNode.updateFolderStatus()
|
25843
|
+
},
|
25844
|
+
|
25845
|
+
getFailedAssertions : function () {
|
25846
|
+
var failed = [];
|
25847
|
+
var as = this.get('assertionsStore');
|
25848
|
+
|
25849
|
+
if (as) {
|
25850
|
+
as.each(function (assertion) {
|
25851
|
+
if (assertion.get('passed') === false) {
|
25852
|
+
failed.push(assertion);
|
25853
|
+
}
|
25854
|
+
});
|
25855
|
+
}
|
25856
|
+
|
25857
|
+
return failed;
|
25858
|
+
}
|
25859
|
+
}, (Ext.getVersion && Ext.getVersion('touch')) ? { config : config } : config), function () {
|
25860
|
+
var isSenchaTouch = Ext.getVersion && Ext.getVersion('touch')
|
25861
|
+
|
25862
|
+
if (!isSenchaTouch) {
|
25863
|
+
Ext.data.NodeInterface.decorate(this);
|
25864
|
+
|
25865
|
+
this.override({
|
25866
|
+
expand : function () {
|
25867
|
+
Ext.suspendLayouts();
|
25868
|
+
this.callParent(arguments);
|
25869
|
+
Ext.resumeLayouts();
|
25056
25870
|
}
|
25057
25871
|
});
|
25058
25872
|
}
|
25059
|
-
|
25060
|
-
|
25061
|
-
}
|
25062
|
-
}, (Ext.getVersion && Ext.getVersion('touch')) ? { config : config } : config ))
|
25873
|
+
})
|
25874
|
+
})();
|
25063
25875
|
;
|
25064
|
-
|
25065
|
-
|
25066
|
-
|
25067
|
-
|
25068
|
-
|
25069
|
-
|
25070
|
-
|
25071
|
-
|
25072
|
-
|
25073
|
-
|
25074
|
-
|
25075
|
-
|
25076
|
-
|
25077
|
-
|
25078
|
-
|
25079
|
-
|
25080
|
-
|
25081
|
-
|
25082
|
-
|
25083
|
-
|
25876
|
+
(function () {
|
25877
|
+
var config = {
|
25878
|
+
idProperty : 'index',
|
25879
|
+
|
25880
|
+
fields : [
|
25881
|
+
'index',
|
25882
|
+
'summaryFailure',
|
25883
|
+
{ name : 'passed', type : 'boolean', defaultValue : false },
|
25884
|
+
{ name : 'isTodo', type : 'boolean', defaultValue : false },
|
25885
|
+
{ name : 'isWaitFor', type : 'boolean', defaultValue : false },
|
25886
|
+
{ name : 'completed', type : 'boolean', defaultValue : false },
|
25887
|
+
'description',
|
25888
|
+
'annotation',
|
25889
|
+
'type',
|
25890
|
+
'sourceLine',
|
25891
|
+
'isWarning',
|
25892
|
+
|
25893
|
+
// For logging simulated events (will also have a type as for diagnostic messages)
|
25894
|
+
{ name : 'isSimulatedEvent', type : 'boolean', defaultValue : false },
|
25895
|
+
'eventType'
|
25896
|
+
]
|
25897
|
+
};
|
25084
25898
|
|
25085
|
-
Ext.define('Siesta.Harness.Browser.Model.Assertion', Ext.apply({
|
25086
|
-
|
25087
|
-
}, (Ext.getVersion && Ext.getVersion('touch')) ? { config : config } : config
|
25899
|
+
Ext.define('Siesta.Harness.Browser.Model.Assertion', Ext.apply({
|
25900
|
+
extend : 'Ext.data.Model'
|
25901
|
+
}, (Ext.getVersion && Ext.getVersion('touch')) ? { config : config } : config));
|
25902
|
+
})();
|
25088
25903
|
;
|
25089
25904
|
Ext.define('Siesta.Harness.Browser.UI.MouseVisualizer', {
|
25090
25905
|
|
@@ -25494,6 +26309,7 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.MainPanel', {
|
|
25494
26309
|
|
25495
26310
|
Joose.A.each(harness.flattenDescriptors(descriptors), function (descriptor) {
|
25496
26311
|
var test = flatStore.getById(descriptor.id);
|
26312
|
+
|
25497
26313
|
me.lastTests.push(test);
|
25498
26314
|
|
25499
26315
|
test.set({
|
@@ -25533,7 +26349,11 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.MainPanel', {
|
|
25533
26349
|
var testRecord = flatStore.getById(descriptor.id);
|
25534
26350
|
|
25535
26351
|
if (testRecord.isLeaf()) testRecord.get('assertionsStore').removeAll(true)
|
26352
|
+
|
25536
26353
|
testRecord.reject(true);
|
26354
|
+
|
26355
|
+
// HACK mark record as not having any test results
|
26356
|
+
testRecord.isCleared = true
|
25537
26357
|
});
|
25538
26358
|
},
|
25539
26359
|
|
@@ -25545,6 +26365,7 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.MainPanel', {
|
|
25545
26365
|
Ext.select('.ghost-cursor-click-indicator').each(function(el) { el.destroy(); });
|
25546
26366
|
},
|
25547
26367
|
|
26368
|
+
|
25548
26369
|
toggleResults : function() {
|
25549
26370
|
if (this.lastTests.length > 1) {
|
25550
26371
|
var store = this.createFailedAssertionsStore(this.lastTests);
|
@@ -25559,6 +26380,7 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.MainPanel', {
|
|
25559
26380
|
}
|
25560
26381
|
},
|
25561
26382
|
|
26383
|
+
|
25562
26384
|
createFailedAssertionsStore : function(tests) {
|
25563
26385
|
var store = new Ext.data.Store({
|
25564
26386
|
model : 'Siesta.Harness.Browser.Model.Assertion'
|
@@ -25667,6 +26489,8 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.MainPanel', {
|
|
25667
26489
|
|
25668
26490
|
onTestStart : function (test) {
|
25669
26491
|
var testRecord = this.flatStore.getById(test.url)
|
26492
|
+
|
26493
|
+
testRecord.isCleared = false
|
25670
26494
|
|
25671
26495
|
testRecord.beginEdit()
|
25672
26496
|
|
@@ -25781,18 +26605,22 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.MainPanel', {
|
|
25781
26605
|
|
25782
26606
|
|
25783
26607
|
onItemDisclose : function (list, testModel, target, index) {
|
25784
|
-
if (testModel.
|
26608
|
+
if (testModel.isCleared) this.launchTest(testModel);
|
25785
26609
|
|
25786
26610
|
this.showResultPanel(testModel);
|
25787
26611
|
},
|
25788
26612
|
|
25789
26613
|
|
25790
|
-
showResultPanel : function() {
|
26614
|
+
showResultPanel : function (testModel) {
|
26615
|
+
var resultList = this.getResultList()
|
26616
|
+
|
26617
|
+
if (testModel) resultList.showTest(testModel);
|
26618
|
+
|
25791
26619
|
this.suiteBar.down("button[ui='back']").enable()
|
25792
26620
|
|
25793
26621
|
this.getLayout().getAnimation().setReverse(false)
|
25794
26622
|
|
25795
|
-
this.setActiveItem(
|
26623
|
+
this.setActiveItem(resultList);
|
25796
26624
|
},
|
25797
26625
|
|
25798
26626
|
|
@@ -25958,7 +26786,7 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.ResultList', {
|
|
25958
26786
|
|
25959
26787
|
config : {
|
25960
26788
|
itemTpl : new Ext.XTemplate(
|
25961
|
-
'<div class="{[this.getRowClass(values)]}">{description} {[values.annotation ? ("<br/>" + values.annotation) : ""]}</div>',
|
26789
|
+
'<div class="{[this.getRowClass(values)]}">{description} {[values.annotation ? ("<br/>" + Ext.String.htmlEncode(values.annotation)) : ""]}</div>',
|
25962
26790
|
{
|
25963
26791
|
getRowClass: function(data){
|
25964
26792
|
if (data.type === 'Siesta.Result.Diagnostic') {
|
@@ -25977,10 +26805,12 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.ResultList', {
|
|
25977
26805
|
testRecord : null
|
25978
26806
|
},
|
25979
26807
|
|
26808
|
+
|
25980
26809
|
constructor : function() {
|
25981
26810
|
this.callParent(arguments);
|
25982
26811
|
},
|
25983
26812
|
|
26813
|
+
|
25984
26814
|
getIFrame : function () {
|
25985
26815
|
if (this.testRecord) {
|
25986
26816
|
var test = this.testRecord.get('test');
|
@@ -25990,10 +26820,11 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.ResultList', {
|
|
25990
26820
|
return null;
|
25991
26821
|
},
|
25992
26822
|
|
26823
|
+
|
25993
26824
|
alignIFrame : function () {
|
25994
26825
|
var iframe = this.getIFrame();
|
25995
26826
|
|
25996
|
-
Ext.fly(iframe).addCls('active')
|
26827
|
+
iframe && Ext.fly(iframe).addCls('active')
|
25997
26828
|
|
25998
26829
|
var test = this.testRecord && this.testRecord.get('test')
|
25999
26830
|
|
@@ -26002,6 +26833,7 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.ResultList', {
|
|
26002
26833
|
}
|
26003
26834
|
},
|
26004
26835
|
|
26836
|
+
|
26005
26837
|
hideIFrame : function () {
|
26006
26838
|
var iframe = this.getIFrame()
|
26007
26839
|
|
@@ -26014,15 +26846,20 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.ResultList', {
|
|
26014
26846
|
}
|
26015
26847
|
},
|
26016
26848
|
|
26849
|
+
|
26017
26850
|
toggleFrameVisible : function() {
|
26018
26851
|
var iframe = this.getIFrame()
|
26019
26852
|
iframe && Ext.fly(iframe).toggleCls('active');
|
26020
26853
|
},
|
26021
26854
|
|
26855
|
+
|
26022
26856
|
isFrameVisible : function () {
|
26023
|
-
|
26857
|
+
var iframe = this.getIFrame()
|
26858
|
+
|
26859
|
+
return iframe && Ext.fly(iframe).hasCls('active') || false;
|
26024
26860
|
},
|
26025
26861
|
|
26862
|
+
|
26026
26863
|
showTest : function (testFile) {
|
26027
26864
|
this.addCls('result-list-running');
|
26028
26865
|
|
@@ -26032,8 +26869,9 @@ Ext.define('Siesta.Harness.Browser.UI_Mobile.ResultList', {
|
|
26032
26869
|
}
|
26033
26870
|
|
26034
26871
|
var url = testFile.get('url');
|
26035
|
-
|
26036
|
-
this
|
26872
|
+
|
26873
|
+
// Nickolay: Had to disable this line, do we need it?
|
26874
|
+
// this.container.innerElement.setHtml('');
|
26037
26875
|
this.setStore(testFile.get('assertionsStore'));
|
26038
26876
|
|
26039
26877
|
this.testUrl = url;
|
@@ -26083,53 +26921,55 @@ A Class representing the browser harness. This class provides a web-based UI and
|
|
26083
26921
|
The default value of the `testClass` configuration option in this class is {@link Siesta.Test.SenchaTouch}, which inherits from
|
26084
26922
|
{@link Siesta.Test.Browser} and contains various Sencha Touch-specific assertions. Use this harness class when testing Sencha Touch applications.
|
26085
26923
|
|
26924
|
+
* **Note** Make sure, you've checked the {@link #performSetup} configuration option.
|
26925
|
+
|
26086
26926
|
This file is for reference only, for a getting start guide and manual, please refer to <a href="#!/guide/siesta_getting_started">Getting Started Guide</a>.
|
26087
26927
|
|
26088
26928
|
Synopsys
|
26089
26929
|
========
|
26090
26930
|
|
26091
|
-
var Harness = Siesta.Harness.Browser.SenchaTouch;
|
26092
|
-
|
26093
|
-
Harness.configure({
|
26094
|
-
title : 'Awesome Sencha Touch Application Test Suite',
|
26931
|
+
var Harness = Siesta.Harness.Browser.SenchaTouch;
|
26095
26932
|
|
26096
|
-
|
26097
|
-
|
26098
|
-
|
26099
|
-
|
26100
|
-
|
26101
|
-
|
26102
|
-
|
26103
|
-
|
26104
|
-
|
26105
|
-
|
26106
|
-
// simple string - url relative to harness file
|
26107
|
-
'sanity.t.js',
|
26933
|
+
Harness.configure({
|
26934
|
+
title : 'Awesome Sencha Touch Application Test Suite',
|
26935
|
+
|
26936
|
+
transparentEx : true,
|
26937
|
+
|
26938
|
+
preload : [
|
26939
|
+
"http://cdn.sencha.io/ext-4.0.2a/ext-all-debug.js",
|
26940
|
+
"../awesome-project-all.js"
|
26941
|
+
]
|
26942
|
+
})
|
26108
26943
|
|
26109
|
-
// test file descriptor with own configuration options
|
26110
|
-
{
|
26111
|
-
url : 'basic.t.js',
|
26112
|
-
|
26113
|
-
// replace `preload` option of harness
|
26114
|
-
preload : [
|
26115
|
-
"http://cdn.sencha.io/ext-4.0.6/ext-all-debug.js",
|
26116
|
-
"../awesome-project-all.js"
|
26117
|
-
]
|
26118
|
-
},
|
26119
26944
|
|
26120
|
-
|
26121
|
-
|
26122
|
-
|
26123
|
-
|
26124
|
-
|
26125
|
-
|
26126
|
-
|
26127
|
-
|
26128
|
-
|
26129
|
-
|
26130
|
-
|
26131
|
-
|
26132
|
-
|
26945
|
+
Harness.start(
|
26946
|
+
// simple string - url relative to harness file
|
26947
|
+
'sanity.t.js',
|
26948
|
+
|
26949
|
+
// test file descriptor with own configuration options
|
26950
|
+
{
|
26951
|
+
url : 'basic.t.js',
|
26952
|
+
|
26953
|
+
// replace `preload` option of harness
|
26954
|
+
preload : [
|
26955
|
+
"http://cdn.sencha.io/ext-4.0.6/ext-all-debug.js",
|
26956
|
+
"../awesome-project-all.js"
|
26957
|
+
]
|
26958
|
+
},
|
26959
|
+
|
26960
|
+
// groups ("folders") of test files (possibly with own options)
|
26961
|
+
{
|
26962
|
+
group : 'Sanity',
|
26963
|
+
|
26964
|
+
autoCheckGlobals : false,
|
26965
|
+
|
26966
|
+
items : [
|
26967
|
+
'data/crud.t.js',
|
26968
|
+
...
|
26969
|
+
]
|
26970
|
+
},
|
26971
|
+
...
|
26972
|
+
)
|
26133
26973
|
|
26134
26974
|
|
26135
26975
|
*/
|
@@ -26143,17 +26983,31 @@ Class('Siesta.Harness.Browser.SenchaTouch', {
|
|
26143
26983
|
|
26144
26984
|
has: {
|
26145
26985
|
/**
|
26146
|
-
* @cfg {Class} testClass The test class which will be used for creating test instances, defaults to {@link Siesta.Test.
|
26147
|
-
* You can subclass {@link Siesta.Test.
|
26986
|
+
* @cfg {Class} testClass The test class which will be used for creating test instances, defaults to {@link Siesta.Test.SenchaTouch}.
|
26987
|
+
* You can subclass {@link Siesta.Test.SenchaTouch} and provide a new class.
|
26148
26988
|
*
|
26149
26989
|
* This option can be also specified in the test file descriptor.
|
26150
26990
|
*/
|
26151
|
-
testClass: Siesta.Test.SenchaTouch,
|
26991
|
+
testClass : Siesta.Test.SenchaTouch,
|
26152
26992
|
|
26993
|
+
/**
|
26994
|
+
* @cfg {Boolean} transparentEx
|
26995
|
+
*/
|
26153
26996
|
transparentEx : true,
|
26154
26997
|
keepResults : false,
|
26998
|
+
keepNLastResults : 0,
|
26999
|
+
|
27000
|
+
/**
|
27001
|
+
* @cfg {Boolean} performSetup When set to `true`, Siesta will perform a `Ext.setup()` call, so you can safely assume there's a viewport for example.
|
27002
|
+
* If, however your test code, performs `Ext.setup()` itself, you need to disable this option.
|
27003
|
+
*
|
27004
|
+
* This option can be also specified in the test file descriptor.
|
27005
|
+
*/
|
26155
27006
|
performSetup : true,
|
26156
27007
|
|
27008
|
+
/**
|
27009
|
+
* @cfg {String} runCore
|
27010
|
+
*/
|
26157
27011
|
runCore : 'sequential',
|
26158
27012
|
|
26159
27013
|
/**
|
@@ -26163,34 +27017,55 @@ Class('Siesta.Harness.Browser.SenchaTouch', {
|
|
26163
27017
|
*
|
26164
27018
|
* This option can be also specified in the test file descriptor.
|
26165
27019
|
*/
|
26166
|
-
loaderPath: null
|
27020
|
+
loaderPath : null,
|
27021
|
+
|
27022
|
+
isRunningOnMobile : true,
|
27023
|
+
useExtJSUI : true
|
26167
27024
|
},
|
26168
27025
|
|
26169
27026
|
|
26170
27027
|
methods: {
|
27028
|
+
|
27029
|
+
setup : function () {
|
27030
|
+
// TODO fix proper mobile detection, since Ext may be absent in "no-ui" harness
|
27031
|
+
this.isRunningOnMobile = typeof Ext !== 'undefined' && Ext.getVersion && Ext.getVersion('touch')
|
27032
|
+
|
27033
|
+
if (!this.isRunningOnMobile) this.keepNLastResults = 2
|
27034
|
+
|
27035
|
+
this.SUPERARG(arguments)
|
27036
|
+
},
|
27037
|
+
|
26171
27038
|
|
26172
27039
|
getNewTestConfiguration: function (desc, scopeProvider, contentManager, options, runFunc) {
|
26173
27040
|
var config = this.SUPERARG(arguments)
|
26174
27041
|
|
26175
|
-
config.performSetup
|
26176
|
-
config.loaderPath
|
27042
|
+
config.performSetup = this.getDescriptorConfig(desc, 'performSetup')
|
27043
|
+
config.loaderPath = this.getDescriptorConfig(desc, 'loaderPath')
|
26177
27044
|
|
26178
27045
|
return config
|
26179
27046
|
},
|
26180
27047
|
|
27048
|
+
|
26181
27049
|
createViewport: function (config) {
|
27050
|
+
if (!this.isRunningOnMobile && this.useExtJSUI) return Ext.create("Siesta.Harness.Browser.UI.ExtViewport", config);
|
27051
|
+
|
26182
27052
|
var mainPanel = Ext.create('Siesta.Harness.Browser.UI_Mobile.MainPanel', config);
|
27053
|
+
|
26183
27054
|
Ext.Viewport.add(mainPanel);
|
26184
27055
|
|
26185
27056
|
return mainPanel;
|
26186
27057
|
},
|
26187
27058
|
|
27059
|
+
|
26188
27060
|
showForcedIFrame : function (iframe, test) {
|
26189
|
-
|
27061
|
+
$.rebindWindowContext(window);
|
27062
|
+
|
27063
|
+
$(iframe).setStyle({
|
26190
27064
|
'z-index' : 100000
|
26191
27065
|
});
|
26192
27066
|
},
|
26193
27067
|
|
27068
|
+
|
26194
27069
|
onBeforeScopePreload : function (scopeProvider, url) {
|
26195
27070
|
var setupEventTranslation = function() {
|
26196
27071
|
Ext.event.publisher.TouchGesture.override({
|
@@ -26280,13 +27155,14 @@ Class('Siesta.Harness.Browser.SenchaTouch', {
|
|
26280
27155
|
;
|
26281
27156
|
;
|
26282
27157
|
Class('Siesta', {
|
26283
|
-
/*PKGVERSION*/VERSION : '1.1.
|
27158
|
+
/*PKGVERSION*/VERSION : '1.1.5',
|
26284
27159
|
|
26285
27160
|
// "my" should been named "static"
|
26286
27161
|
my : {
|
26287
27162
|
|
26288
27163
|
has : {
|
26289
|
-
config
|
27164
|
+
config : null,
|
27165
|
+
activeHarness : null
|
26290
27166
|
},
|
26291
27167
|
|
26292
27168
|
methods : {
|