Foolishness
Normally, in CasperJS, we writethis.click('#myButton')
, where “#myButton” can be just about any CSS selector.Aside: it is normallyThis wasn’t working for me trying to click an SVGthis.click()
rather thancasper.click()
because it is normally in the handler function of acasper.waitXXX()
function.
<g>
tag, that starts a search running. I was taking a screenshot 0.5s later to check it had worked, and it showed the page had not changed.And that turned out to be foolish. The click was working, the search was working, d3 and SVG had nothing to do with anything. The problem was simply were no search results found, and so it never moved to the next page. When I changed the search string, suddenly
click()
was working.So my troubleshooting turned out to be barking up the wrong tree. But, still, I did learn a few things from it.
Using evaluate() With jQuery
Instead of callingthis.click()
you can do something like this:this.evaluate(function(){
$('#myButton').click();
};
This runs JavaScript from within the browser’s context. In this case I use jQuery. This works just as well as using Casper’s click()
outside the evaluate()
.Here there is no advantage. But, by being in a different scope, we have extra flexibility: we could call other functions, or add new event handlers, etc, etc.
Using evaluate() With d3
Here was another of my attempts, but this one does not work:this.evaluate(function(){
d3.select('#myButton').click();
};
The reason: a d3 selection does not have a ready-made click()
function.Making events happen
this.evaluate(function(){
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
return d3.select('#myButton').node().dispatchEvent(evt);
};
This is how you do a click with d3 (you could use this approach with jQuery too (see a helper function), but are unlikely to ever need to). The first lines create a (simulated) mouse click. The final line sends that event to the DOM item of interest.Aside: dispatchEvent() returns false if any of the event handlersI learned this here; that answer also says this should have worked:
cancelled it, true otherwise.
this.evaluate(function(){
d3.select('#myButton').on("click")()
};
This definitely does not work for me. Why? It is actually a cheat, trying to find and call the click handler for the button. In my case the click handler was attached to the parent object (a <g>
) not the object I was calling select
on. (Also, because it is a cheat, this approach does not work when you’ve attached multiple handlers.)By the way, if not using jQuery or d3, you can use
querySelector()
and do it this way:this.evaluate(function(){
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
return document.querySelector('#myButton').dispatchEvent(evt);
};
Summary
The real lesson here, for me, was when something doesn’t work, make sure you are judging success in the right way!Beyond that, it turns out there are a whole host of ways to click a button in a CasperJS script. Use the simplest when you can, bear the others in mind for special occasions.
Written with StackEdit.
No comments:
Post a Comment