Jasmine specs fail with Velocity.js animations an $.Velocity.mock = true - javascript

I'm attempting to run some Jasmine specs on some functions that contain animations built with Velocity.js
The method looks like this:
#changeTitle = (e, data) ->
newTitle = data.title
$pageTitle = #select("pageTitleSelector")
$pageTitle.velocity
opacity: 0
,
duration: 750
complete: -> $pageTitle.text(newTitle)
.velocity
opacity: 1
duration: 800
I'm trying to tests that the page's title changes to the new title. Here is my Jasmine spec:
describe 'submit uiTitleChange', ->
it 'changes the title', ->
#clock = sinon.useFakeTimers()
#component.trigger "uiTitleChange", {title: "New Title"}
#clock.tick(16)
expect(#component.select("pageTitleSelector")).toContainHtml "New Title"
#clock.restore()
Now, I use requirejs, and have a shim that adds $.Velocity.mock = true before any test so that animation duration goes to zero (though actually it's more like 16ms to get the next animation frame).
I've verified that $.Velocity.mock is indeed true before the animation runs, and when running the spec file alone, this works just fine, but when running my entire suite, which tests a few different animations, several of them always fail.
I've tried using setTimeout instead of sinon's fake timers, I've tried setting the clock tick to a very large number (e.g. 100000), and I've also added $.Velocity.mock right before the animations in question, and none of these fix the problem.
The failure looks like this:
Failure/Error: Expected '<div class="page-title velocity-animating">Old Title</div>' to contain html 'New Title'.
The velocity-animating class is there, and the animation's complete callback was never called.

mock must be true not only before an animation runs, but also before any animation calls are made to begin with.
also, just for doubly good measure -- although you prob already know: the velocity calls are still async with mock (since it's on the next rAF tick)
beyond that, i'm not sure. if you showed me a stripped down codepen.io pen, i could be of more use :)
p.s. i don't use jasmine, but rather qunit

Related

NightwatchJS method .resizeWindow not working

A while back, I had an issue using the .maximizeWindow() from NightwatchJS. I was able to resolve this issue by using the following:
"chromeOptions" : {
"args" : ["start-maximized"]
},
However, this was more a work around than a fix. Currently, I need to resize the window, not just maximize it, and want to use the .resizeWindow() method. I also need this to work in browsers other than Chrome, so the above fix is inadequate. Below is my current setup in a test I am writing. This code worked fine in the past and just recently I noticed that the window was no longer resizing correctly. Any thoughts on why it might be failing? Note: this is written in Coffeescript, not JS.
module.exports = {
"Geoprocessing Commands and Assert Tests": (browser) ->
browser
.launchAs "anonymous"
.assert.title "<app name>"
.iFrameReady()
.frame 0, () ->
browser
.resizeWindow 1800, 1000
.pageDisplayed()
.pause 1000
...
.frameParent()
browser.end()
}

Step over EventEmitter to the listeners in debugger

Node has a class, EventEmitter, that is a pretty common fixture of node.js and electron programming. Unfortunately it's a PITA to debug. Imagine some code like this
import EventEmitter from `events`;
const emitter = new EventEmitter();
emitter.on('foobar', handleFoobar);
emitter.emit('foobar', 'foo', 'bar');
function handleFoobar(..args) {
console.log(...args);
}
Now I want to step through the code in the debugger. Of course in this small example I can put a breakpoint on handleFoobar but, in real code I just want to be able to step through the code, when I get to someEmitter.emit I want to be able to pick something along the lines of "Step Into Listeners".
Unfortunately no such feature exists AFAIK. The implementation of EventEmitter is fairly complex so stepping in to see get to the listeners requires stepping about 20-25 times. You can set breakpoints at all the exit points but there are at least 6 of them which is also annoying when you want to turn them all on/off.
Are there any other creative solutions to effectively implement something like "Step Into Listeners" when on a someEmitter.emit line?
One solution comes to mind which is to replace events.js with a simpler implementation. Without domain support and using ES6 features it could be much smaller implementation like
EventEmitter.prototype.emit(type, ...args) {
const listeners = this._listeners[type].slice();
listeners.forEach(listener => {
listener(...args);
}
return listeners > 0;
}
I suppose I could also patch that into the prototype if process.env.NODE_ENV === 'development'
Are there any other more generic solutions? Like maybe a debugger feature where I can pick code to never step into directly but picking step into in the debugger comes out of its exit points?
I found the solution. It's called blackblocking
You can set by script filenames which files not to step into so, adding events.js to the list does exactly what I want. When I'm on the someEmitter.emit and I press "Step Into" I come out the listeners immediately!

Mocha tests on focus-related behaviors (Backbone/CoffeeScript app)

I have a Backbone app written in CoffeeScript. I'm trying to use Mocha (with Chai and Sinon) to write tests for DOM-related behaviors, but it seems that hidden fixtures (I'm using js-fixtures now but I've also tried this unsuccessfully with a hidden '#fixtures' div) don't register certain DOM-related behaviors which makes testing certain types of DOM-related behaviors (seemingly) impossible.
For example, my main app view has several subviews which are never rendered at the same time: when the app view renders subview A, it remembers the focused element of the currently active subview B (#_visibleView), saves that information on subview B, closes the subview B, and then renders subview A.
_rememberFocusedElement: ->
focusedElement = $ document.activeElement
if focusedElement
focusedElementId = focusedElement.attr 'id'
if focusedElementId
#_visibleView?.focusedElementId = focusedElementId
This works when I test it manually, but when I try to write unit tests for this behavior they fail because I can't set focus (e.g., via $(selector).focus()) to an element in a hidden div/iframe. (I have the same issue with functionality which listens for window resize events.)
I thought that if I changed $ document.activeElement to #$ ':focus" I might get different results, but that doesn't fix the issue.
Here is what the relevant parts of my Mocha (BDD) tests look like. This spec will print TEXTAREA to the console and then undefined, indicating that there is a textarea with id='transcription' but I can't set focus to it.
beforeEach (done) ->
fixtures.path = 'fixtures'
callback = =>
#$fixture = fixtures.window().$ "<div id='js-fixtures-fixture'></div>"
#appView = new AppView el: #$fixture
done()
describe 'GUI stuff', ->
it 'remembers the currently focused element of a subview', (done) ->
#appView.mainMenuView.once 'request:formAdd', =>
#appView._visibleView.$('#transcription').focus()
console.log #appView._visibleView.$('#transcription').prop 'tagName'
console.log #appView._visibleView.$(':focus').prop 'tagName'
done()
#appView.mainMenuView.trigger 'request:formAdd'
Is there any way that I can write unit tests for these types of behaviors?
Ok, first off let me clarify something: the term "unit test" means man different things to many people. Often times it becomes synonymous with "any test written using a unit test framework (like Mocha)". When I use the term "unit test" that's not what I mean: what I mean is a test that tests only a single unit of work (which, in a JS environment, will usually be a single function, but might be a whole class).
Ok, with that out of the way, if you really are trying to unit test your code, you're sort of taking the wrong approach. A unit test really shouldn't rely on anything outside the context of the function being tested, and so relying on the (external) DOM is where your problem lies.
Let's assume your focus-handling code is in a function called handleFocus (I don't know the actual method name). Consider the following test, which I'll write using JavaScript since my CoffeScript is rusty:
describe('#handleFocus', function() {
it('remembers the currently focused element of a subview', function() {
var setFocusStub = sinon.stub($.fn, 'focus');
appView._visibleView.handleFocus();
expect(setFocusStub.calledOnce).to.be(true);
});
});
The above is a bit of an over-simplification, but hopefully it illustrates the point. What you're really trying to check isn't whether the DOM (fake or real) does X; what you're trying check is whether your function does X. By focusing on that in your test, and relying on a stub that checks whether "X" happened or not, you completely eliminate the need for the DOM to be involved.
Now of course you might wonder: "well great, that helps me in test-land, but how do I know it will work in a real environment?" My answer to that would be that your (probably Selenium-based) acceptance tests should cover that sort of thing. Acceptance tests should check whether your overall code works in the real world, while unit tests should ensure that individual pieces of that code work in a fake environment.
The former is great for ensuring your customers don't see bugs, while the latter is great for figuring out exactly where those bugs come from, and for making it possible for you to refactor safely.

CreateJS' PreloadJS progress event inaccurate

I'm trying to load some assets using the PreloadJS class from the CreateJS suite, but when very first progress event fired reports e.loaded and e.progress as 0.83, the numbers then decrease over the next few event before finally going back up again.
t.assets = new createjs.LoadQueue();
t.assets.installPlugin(createjs.Sound);
t.assets.setMaxConnections(10);
t.assets.addEventListener("progress", function(e){
console.log(e.loaded);
});
t.assets.addEventListener("complete", function(){
callback();
});
t.assets.loadManifest([
{ id: 'facebook_btn', src: 'img/ingame/facebook_white_btn.png' },
{ id: 'twitter_btn', src: 'img/ingame/twitter_white_btn.png' },
{ id: 'embed_btn', src: 'img/ingame/embed_white_btn.png' },
]);
I get these results in the console
0.8333333333333334
0.7142857142857143
0.625
0.5555555555555556
0.5
0.45454545454545453
0.4984983736293216
0.5894074645384125
0.6363636363636364
0.6663361591119469
0.7572452500210378
0.8261679748749072
0.9170770657839982
0.9390634318392196
1
Is this because it's working through the manifest initally and doesn't take into account everything right away?
Is checking the the progress is going the correct way before displaying these results in a preloader a good method of making sure it's sorted itself out?
Essentially the manifest is just providing a convienient way to deal with a batch of assets without you having to loop through them yourself. Have a look at the code, it's almost the same as the loadFile method, but loops through the array of objects. So it's not doing anything fancy in terms of better calculating the progress.
http://createjs.com/Docs/PreloadJS/files/.._src_preloadjs_LoadQueue.js.html#l898
You have a couple options though to make it look more accurate.
If you're not loading much and it's only going to take a few seconds you might just want to not use the progress event. Instead you can just catch load errors or other hangups.
If you are loading lots of things and it could take some time then consider waiting a few seconds before displaying the progress. That gives the manifest time to add enough stuff that it should just be moving in a positive direction towards 1.

What are the inner workings of the Selenium waitFor mechanism?

I am trying to customize the behavior of Selenium's click command, (via user-extentions.js), by intercepting calls to doClick(locator). Basically I need to delay click actions whenever our application's "busy indicator" is being displayed.
(Now the standard answer for this kind of thing is to insert a waitFor into the script for those situations. Indeed, we currently have zillions of them throughout our scripts. I'm trying to eliminate those.)
Detecting the page element is the trivial part. The tricky part is getting the script to actually wait. My promising looking, but failed attempt looks like this:
var nativeClick = Selenium.prototype.doClick;
Selenium.prototype.doClick = function(locator) {
this.doWaitForCondition("!selenium.browserbot.findElementOrNull('busy-indicator')", 5000);
return nativeClick.call(this, locator);
}
The doWaitForCondition gets called before every click, but it does not wait when the condition evaluates to false. nativeClick always gets called immediately, and so no delay is introduced. I suspect that the doWaitForCondition function doesn't actually do any waiting per se, but rather establishes the conditions for it within the command execution loop. And in this case the click command is already in play, and I'm trying to run a command within a command.
Can somebody shed some light on how Selenium command execution and waitFor works, or offer suggestions on how this might be done?
I have finally solved this. And with an approach that is much better than trying to intercept click processing in its various forms. My refined goal is: to delay execution of script command completion when our application is "busy".
How Selenium command processing works:
Upon completion, each selenium command returns an ActionResult object, (see ActionHandler.prototype.execute). The terminationCondition attribute on this object is a function that determines when it is okay for selenium to proceed to the next command, (TestLoop.prototype.continueTestWhenConditionIsTrue). Basically, selenium repeatedly executes the condition function until it yields true. The result object it quite trivial:
function ActionResult(terminationCondition) {
this.terminationCondition = terminationCondition;
}
Customizing it:
I want to delay execution any time myAppIsBusy() returns true. Of course all of the standard delays need to remain in place as well, like waiting for page loads, and explicit waitFor conditions as scripted. The solution is to redefine the selenium result object in my user-extensions.js, as follows:
function ActionResult(terminationCondition) {
this.terminationCondition = function() {
// a null terminationCondition means okay to continue
return (!terminationCondition || terminationCondition()) && !myAppIsBusy();
}
}
The great thing is that this is at a low enough level that it works for the IDE, as well as for RC.
Note that this does not affect Accessor or Assert command types, which return different result objects. But that should be fine, because those commands don't effect the state of the application.
Well, a look at the java drivers com.thoughtworks.selenium.Wait class reveals this:
public void wait(String message, long timeoutInMilliseconds, long intervalInMilliseconds) {
long start = System.currentTimeMillis();
long end = start + timeoutInMilliseconds;
while (System.currentTimeMillis() < end) {
if (until()) return;
try {
Thread.sleep(intervalInMilliseconds);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
throw new WaitTimedOutException(message);
}
I am not to deep into selenium but I excpect that every waitXXX Method points to this.
So, Selenium is working with Thread.sleep(). While this might not look like an ideal solution it shows at least that you cant make it worse by using Thread.sleep() on your own if neccessary. ;-)

Categories

Resources