Reputation: 619
I'm trying to test the visual state of a number of buttons -- hover, click, focus -- and was looking for a way to not copy basically the same casper.then()
command over and over. I thought I should be able to do this in a simple loop.
I made a small array of the (currently) 5 buttons and while-looped through them adding CasperJS steps for each of the states I'd like to record. Unfortunately, only the last of the steps is actually performed.
I've read a number of posts about looping, but they all seem to involve clicking links on a page or some other scenario that doesn't seem to match what I'm looking for.
Maybe I'm just being dense? Code below...
casper.thenOpen( 'docs/buttons/test.html' );
var buttonStyles = [
{ selector: '.grey0', title: 'Button - Grey 0' },
{ selector: '.grey25', title: 'Button - Grey 25' },
{ selector: '.grey50', title: 'Button - Grey 50' },
{ selector: '.grey75', title: 'Button - Grey 75' },
{ selector: '.grey100', title: 'Button - Grey 100' },
];
while (buttonStyles.length > 0) {
buttonStyle = buttonStyles.pop();
casper.then(function(){
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title);
});
casper.then(function(){
this.mouse.move(buttonStyle.selector);
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title + ' - Hover');
});
casper.then(function(){
this.mouse.down(buttonStyle.selector);
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title + ' - Down');
});
}
casper.test.done();
Upvotes: 4
Views: 4928
Reputation: 61952
The problem is that buttonStyle
is a global variable. When you iterate over the buttonStyles
array all 5 * 3 = 15 then
blocks are scheduled, but since buttonStyle
is the same reference inside of every then
block only the last buttonStyle
is actually checked 5 times.
Javascript doesn't have block level scope (inside while), but only function level scope. The solution would be to introduce a function to do this. You can use an IIFE or casper.repeat
like you did.
while (buttonStyles.length > 0) {
buttonStyle = buttonStyles.pop();
(function(buttonStyle){
casper.then(function(){
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title);
});
casper.then(function(){
this.mouse.move(buttonStyle.selector);
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title + ' - Hover');
});
casper.then(function(){
this.mouse.down(buttonStyle.selector);
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title + ' - Down');
});
})(buttonStyle);
}
Upvotes: 4
Reputation: 619
If I didn't see a number of other posts asking similar questions, I would have just deleted this. Instead, I'll post my 8-minute-later learnings here. I wonder why I can't come up with this before posting to SO?
The appropriately named "casper.repeat" did the trick for me:
casper.thenOpen( 'docs/buttons/test.html' );
var buttonStyles = [
{ selector: '.grey0', title: 'Button - Grey 0' },
{ selector: '.grey25', title: 'Button - Grey 25' },
{ selector: '.grey50', title: 'Button - Grey 50' },
{ selector: '.grey75', title: 'Button - Grey 75' },
{ selector: '.grey100', title: 'Button - Grey 100' },
];
var curIndex = 0;
casper.repeat(buttonStyles.length, function() {
buttonStyle = buttonStyles[curIndex];
casper.then(function(){
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title);
});
casper.then(function(){
this.mouse.move(buttonStyle.selector);
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title + ' - Hover');
});
casper.then(function(){
this.mouse.down(buttonStyle.selector);
phantomcss.screenshot(buttonStyle.selector, buttonStyle.title + ' - Down');
});
curIndex++;
});
casper.test.done();
Upvotes: -1