2

I want to write unit tests to download a file by clicking a form button using casperJS. I tried using document.getElementsByTagName to get to the button and clicked it in JavaScript's way. But I got an error message:

TypeError: 'undefined' is not a function (evaluating 'inputs[1].click()')

The segment of the code that didn't pass the test :

casper.then(function() {
    var inputs = document.getElementsByTagName('input');
    inputs[1].click();
});

When I tried executing the same code from the console in my browser, the button got clicked and the download window popped up.

I initially tried to check with the presence of the button with assertExists function in casperJS. The assertion passed, indicating that the button exists. Also, inputs array has 2 elements, one is hidden input of CSRF token (I'm using Django) and the other is the button that I want to click.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
Sentient07
  • 1,270
  • 1
  • 16
  • 24
  • inputs[1] === undefined indicates there is not an element at index 1, did you mean 0? – swornabsent May 21 '15 at 17:31
  • Try adding a breakpoint with the dev tools and see what's going on when you try to find the inputs. You can also pause on all exceptions so you don't even need to set a breakpoint. See here for more: https://developer.chrome.com/devtools/docs/javascript-debugging – ekuusela May 21 '15 at 17:33

1 Answers1

3

Clicking

PhantomJS (and by extension CasperJS) has two contexts. Only the page context (evaluate()) can access the DOM. The other problem is that most elements don't implement the element.click() function in PhantomJS, so you would need to use another type of click.

CasperJS provides a casper.click() function which works in almost all cases. It can select the element that you want to click either by CSS selectors or XPath expressions. Since you want to click the second input, it is not possible to define a general CSS selector that does this. An XPath expression must be used in this case. CasperJS provides an XPath utility:

var x = require('casper').selectXPath;
...
casper.then(function(){
    this.click(x("(//input)[2]"));
});

Please note that counting starts with 1 in XPath expressions and CSS selectors.


Downloading

PhantomJS (and by extension CasperJS) won't trigger a file download when you click on something. You will need to build and send the request yourself.

There are many ways of doing it. Here is one example. Actually, a better way would be to use a PhantomJS fork that natively supports file downloading as part of a new event. See this answer for more details.

Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Yes, thanks a ton, that worked! Button is getting clicked, but the file isn't downloading ? Do I need to add something more to this ? – Sentient07 May 21 '15 at 17:58
  • 1
    Note the second part of the question. Clicking alone won't get you far. I only noticed that you wanted to download a file after I've written my initial answer. – Artjom B. May 21 '15 at 17:59
  • Sure, not an issue. Thanks again ! – Sentient07 May 21 '15 at 18:01
  • Hey, i tried those link but I'm still having a problem to download the mime type from the resource. This is my issue, could you please have a look ? https://stackoverflow.com/questions/30405704/download-img-png-mime-type-casperjs – Sentient07 May 23 '15 at 20:51
  • @Sentient07 Yes, I've seen it, but it looks fine. I have no idea where the issue might be. – Artjom B. May 23 '15 at 20:54