ST.context = {}; // namespace ST._screenshotCount = 0; ST.context.Base = ST.define({ /** * @cfg {Boolean} eventTranslation * `false` to disable event translation. If `false` events that are not supported by * the browser's event APIs will simply be skipped. * NOTE: inherited from Player */ eventTranslation: true, /** * @cfg {Boolean} visualFeedback * `false` to disable visual feedback during event playback (mouse cursor, and "gesture" * indicator) * NOTE: inherited from Player */ visualFeedback: true, /** * @param {Array} playables Either a config for a playable or a Playable * @param done */ play: function (playables, done) { var me = this, player = ST.player(), options = ST.options, tail; if (done) { tail = { type: 'tail', remoteable: false, fn: function () { player.un('error', tail); if (done) { done(); } } }; playables.push(tail); } for( var i=0; i<playables.length; i++) { var p = playables[i]; p.context = this; if (typeof p.futureClsName === 'undefined') { p.futureClsName = 'ST.future.Element'; } p.args = p.args || {}; } me.eventDelay = player.eventDelay = options.eventDelay; me.typingDelay = player.typingDelay = options.typingDelay; me.visualFeedback = player.visualFeedback = options.visualFeedback; me.eventTranslation = player.eventTranslation = options.eventTranslation; if (me.injector) { me.injector.translate = options.eventTranslation; } player.add(playables); if (done) { playables.pop(); player.on('error', tail.fn); } player.start(); // does nothing if already started return playables; }, screenshot: function (name, tolerance, done) { var me = this; name = name || ST._screenshotCount++; tolerance = tolerance || 0; me._screenshot(name, function (err, comparison) { var expectation, passed; if (err) { expectation = { passed: false, message: err.stack || err.message || err }; } else if (comparison) { passed = comparison.diffCount <= tolerance; expectation = { passed: passed, message: 'Expected screenshot ' + name + ' to match baseline.', screenshot: comparison.path, baseline: comparison.baseline, diff: comparison.diff }; } else { expectation = { passed: true, message: 'Screenshot comparison unsupported for this session' }; } ST.status.addResult(expectation); done(comparison); }); }, _createInstance: function (className, config) { var fn = ST.clsFromString(className); if (!fn) { if (ST.LOGME) console.log('WARNING: no class for className='+className); fn = ST.playable.Playable; } return new fn(config); }, createPlayable: function (event) { var me = this, type = event.type, playableClsName, playable; playableClsName = event.futureClsName + '.prototype.playables.' + ST.capitalize(type); playable = me._createInstance(playableClsName, event); // allows for custom events such as the expandX methods for tap/type... if (!playable) { playable = new ST.playable.Playable(event); } playable.context = playable.context || me; if (ST.LOGME) console.log('Base.createPlayable() => '+playable); return playable; }, checkGlobalLeaks: function (done) { var me = this, results; if (ST.LOGME) console.log('Base.checkGlobalLeaks()'); me._checkGlobalLeaks(function (result) { var results = result.results, addedGlobals = result.addedGlobals; if (results && results.length) { for (var i=0; i<results.length; i++) { ST.status.addResult(results[i]); } } if (addedGlobals && addedGlobals.length) { ST.addGlobals(addedGlobals); } done(); }); }});