Hi,
@Alon Nisser - Thanks for the tip about logging and .on('remote.message', func), I have that bit working now =). I had a look at your sample code, but that seemed to be using SinonJS's fakeserver, not spies, so not sure how applicable it would be to my use case?
@Nicolas Perriault - Yes, I did read the docs - they are helpful and good =) - but I suspect my lack of JS know-how is getting in the way.
So injectJs() is for injecting into a single page, whilst clientScripts is useful for injecting a script on all pages.
Got it, that makes sense =).
Also - at what point in time does the injection occur? For example, if I already have existing JavaScript on the page - will the injected code execute before or after that code?
With the GA, I tried using waitForResource() on dc.js (the remote Google Analytics JavaScript file), and it timed-out. My code:
casper.start(url, function() {
casper.waitForResource(/dc.gif/, function() {
this.echo('DoubleClick JS is loaded.');
});
test.assertTitleMatches(/foobar/);
this.log('Page title is "' + this.getTitle() + '".', 'debug');
Increased the wait to 10 seconds, same result:
[warning] [phantom] Casper.waitFor() timeout
FAIL /dc.gif/ did not load in 10000ms
# type: uncaughtError
# file: test_purchase.js
# error: /dc.gif/ did not load in 10000ms
# stack: not provided
I thought this was strange, because Chrome's Dev Console definitely showed dc.js being loaded.
I added the following before casper.test.begin:
casper.on('resource.received', function(resource) {
casper.echo(resource.url);
});
and I noticed that things like the Facebook all.js weren't being printed out, nor was Google Analytics dc.js.
I'm guessing it might have something to do with them being loaded asynchronously using parentNode.insertBefore() - but CasperJS should still load them, right?
This is the loading code for dc.js:
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
Also - if I am going to use the waitForResource() - does it matter where I put it? For example, should I put it right after casper.start()/casper.open()? Is there any way that the resource could get loaded before the call, and it doesn't detect it?
Finally, assuming I do manage to get waitForResource() to detect dc.js correctly, how exactly do I get it so that evaluate() will get called before anything happens?
For example, we have this at the bottom of the HTML page:
<script type="text/javascript">
var _gaq = _gaq || [];
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-foobar']);
_gaq.push(['_setDomainName', 'foobar.com']);
_gaq.push(['_setAllowLinker', true]);
if ($.cookies.get('www')) {
_gaq.push(['_setVar', 'www_' + $.cookies.get('www')]);
}
var g = getMemberGender();
if (g){
_gaq.push(['_setCustomVar', 2, 'Gender', g, 2]);
}
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
My understanding of the above is that it creates a _gaq array first, which the dc.js script will then replace with an object (which has it's own push() method), when that gets loaded - which means you can call _gaq.push() right from the get go.
So ideally I'd need to load the SinonJS spies at the very beginning, before anything on the page is executed. Will evaluate() do that? (I did check the docs, but it doesn't seem to mention when it gets executed, in relation to the page's JS - perhaps it's meant to be obvious?).
Also, for the spy, I'm hoping to use this:
spy = casper.evaluate(function() {