3

I am trying to write a really simple CasperJS script to test the login button on a website. After the click event, a modal window is opened on top of the website so you can fill in the login fields.

Using the website, this works pretty well. Using casperjs test my-script-file --engine=slimerjs also works perfectly fine. Without slimerjs, the code fails.

How the button is defined:

<button class="btn btn-strong-submit" data-action="join">Join</button>

My test:

casper.test.begin('testing', 3, function suite(test)
{
    casper.start();
    casper.thenOpen("http://the-website-to-test-url", function()
    {
        casper.wait(5000, function(){
            casper.thenClick("button.btn.btn-strong-submit");
        });
    });

    casper.then(function () {
        casper.wait(3000);
        casper.capture("screen.png");
    });

    casper.then(function(){
        casper.assertVisible("div.join_container");
    });

    casper.run(function()
    {
        test.done();
    })
});

On the website, clicking the button will go to http://the-website-to-test-url.com/#join since the way the website works is it waits for a click and catches is using jQuery and then finds the [data-action], forms #[data-action] and then builds the URL in that way.

But CasperJS does not seem to understand a click which then gets caught from jQuery on the background. Any ideas?

Update on terminal output:

[info] [phantom] Starting...
[info] [phantom] Running suite: 4 steps
[debug] [phantom] opening url: http://www.MYURL.com/, HTTP GET
[debug] [phantom] Navigation requested: url=http://www.MYURL.com/, type=Other, willNavigate=true, isMainFrame=true
[debug] [phantom] url changed to "http://www.MYURL.com/"
[debug] [phantom] Successfully injected Casper client-side utilities
[info] [phantom] Step anonymous 2/4 http://www.MYURL.com/ (HTTP 200)
[info] [phantom] Step anonymous 2/4: done in 721ms.
[info] [phantom] Step anonymous 3/4 http://www.MYURL.com/ (HTTP 200)
[info] [phantom] Step anonymous 3/4: done in 731ms.
[info] [phantom] Step _step 4/5 http://www.MYURL.com/ (HTTP 200)
[info] [phantom] Step _step 4/5: done in 752ms.
[info] [phantom] wait() finished waiting for 5000ms.
[debug] [phantom] Mouse event 'mousedown' on selector: .btn.btn-strong-submit
[debug] [phantom] Mouse event 'mouseup' on selector: .btn.btn-strong-submit
[debug] [phantom] Mouse event 'click' on selector: .btn.btn-strong-submit
[info] [phantom] Step anonymous 5/5 http://www.MYURL.com/ (HTTP 200) 

//After click URL should have changed to http://www.MYURL.com/#login

[info] [phantom] Step anonymous 5/5: done in 5772ms.
[info] [phantom] Step _step 6/6 http://www.MYURL/ (HTTP 200)
[info] [phantom] Step _step 6/6: done in 5792ms.
[info] [phantom] wait() finished waiting for 3000ms.
[debug] [phantom] Capturing page to /home/TEMP/screen.png
[info] [phantom] Capture saved to /home/TEMP/screen.png
[info] [phantom] Done 6 steps in 9367ms
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
teodr
  • 101
  • 2
  • 12
  • So, your script "works" with SlimerJS, but not with PhantomJS? What do you mean by that? How do you verify that it doesn't work? – Artjom B. Feb 02 '15 at 15:33
  • Well with slimerjs I can see it, but with casperjs/phantomjs assertVisible will fail. Sorry I removed it from my code after too many trials, forgot to put it there again. – teodr Feb 02 '15 at 15:45
  • and also, i tried to capture a screenshot after waiting for 5000 and there is still nothing visible – teodr Feb 02 '15 at 15:46
  • Do you mean an actual popup *window* or do you mean a modal? In case of a popup, you would need to use [`withPopup`](http://docs.casperjs.org/en/latest/modules/casper.html#withpopup), because popups are opened in child pages and are not visible/accessible from the main page. Please add the missing code. – Artjom B. Feb 02 '15 at 16:57
  • Edited. Sorry it took so long. Btw, it should be a modal, my mistake to call it a popup. It has a form in it to fill in the login info and press Login button afterwards. While this modal is up, the background main page goes darker. – teodr Feb 02 '15 at 17:23
  • 1
    `wait` is asynchronous whereas `capture` is not. Put capture in the callback and see if this changes anything: `wait(3000, function(){this.capture("screen.png")});`. If not, please register to the [`resource.error`](http://docs.casperjs.org/en/latest/events-filters.html#resource-error), [`casper.page.onResourceTimeout`](http://phantomjs.org/api/webpage/handler/on-resource-timeout.html), [`remote.message`](http://docs.casperjs.org/en/latest/events-filters.html#remote-message) and [`page.error`](http://docs.casperjs.org/en/latest/events-filters.html#page-error) events. Maybe there are errors. – Artjom B. Feb 02 '15 at 18:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/70119/discussion-between-teodr-and-artjom-b). – teodr Feb 03 '15 at 09:09

1 Answers1

1

Expanding on Artjom's comment, I think you should change this:

casper.then(function () {
    casper.wait(3000);
    casper.capture("screen.png");
});

to be:

casper.wait(3000, function () {
    casper.capture("screen.png");
});

This is a bit more descriptive, not just more compact: "Wait 3000ms then do ...".

(Aside: casper.then( doSomething ) and casper.wait(0, doSomething) are the same thing.)

NOTE: the downside of this approach is it adds a 3-second delay to your unit test. You could rewrite it as:

casper.waitUntilVisible('div.join_container', {
    casper.capture("screen.png");
});

Then as soon as it is visible it will take the screenshot, then progress to the next step. The downside of this way is that your assert always works; if there is a problem you get a time-out instead of a test failure. (That may or may not matter, it depends on what you are testing and why.)

Darren Cook
  • 27,837
  • 13
  • 117
  • 217