1

Testing scenario is,

  1. creating a cell,
  2. Change the language from the drop down menu(from R to Python),
  3. Enter the code and execute it. HTML code for drop down menu is
<select class="form-control cell-control-select cell-control">
    <option>Markdown</option>
    <option>R</option>
    <option>Python</option>
    <option>RMarkdown</option>
</select>

and below is my casperjs code

casper.then(function(){
    this.mouse.click({ type: 'xpath' , path: "/html/body/div[3]/div/div[2]/div/div[3]/div[1]/div/select"});//x path for dropdown menu
    this.echo('clicking on dropdown menu');
    this.wait(3000);
});

casper.then(function(){
    var z = this.evaluate(function() {
    document.querySelector('.form-control').selectedIndex = 2;
    return true;
    });
    this.wait(3000);
});

it is selecting the Python language from the drop down menu but when we run the code it is showing Error in prompt cell. The same error we get when we run R code in python language cell.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
GANA
  • 138
  • 8
  • What's the error that you see? After you change the selected index, does it show that "Python" is selected when you take the screenshot? Is the select box maybe hidden and the actual dropdown is implemented with HTML+CSS+JS? – Artjom B. Apr 14 '15 at 08:14
  • ya it is showing 'Python' in drop down menu. i am using just simple python code which is a=50;print a. when it gets execute (Python is selected in drop down), it is showing 'Parse error: :1:12: unexpected symbol 1: a=50;print a' error. This error occurs when we run python code in R. – GANA Apr 14 '15 at 09:19

1 Answers1

1

The issue is probably that there is a change listener on the select box which doesn't get called, because setting the selectedIndex property doesn't trigger a change.

A reliable way to trigger this change is to use jQuery's change():

this.evaluate(function() {
    var form = document.querySelector('.form-control');
    form.selectedIndex = 2;
    $(form).change();
});

If you don't already have jQuery in the page, you can inject it like this if you have jQuery locally:

var casper = require('casper').create({
    clientScripts: [ "jquery.min.js" ]
});

or if you don't have it locally:

var casper = require('casper').create({
    remoteScripts: [ "http://code.jquery.com/jquery-2.1.3.min.js" ]
});
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • above solution worked...thanks., but after that when i execute the code, application becoming unresponsive...and without executing it is quitting the script. – GANA Apr 15 '15 at 04:35
  • thanks above solution worked only when i type some code, and the i change the drop down but when i change the drop down value before entering code, it starts to execute the empty cell. it is not going to the next line of the code which is adding code into the cell – GANA Apr 15 '15 at 05:16
  • What does *"code"* in *"solution worked only when i type some code"* mean? Are you talking about something that needs to be typed in on the page? If yes, then I can't help you, because I don't know the page you're talking about. – Artjom B. Apr 15 '15 at 06:26
  • Hey, can i use xpath for the above solution? if then how can i use that one? – GANA Apr 17 '15 at 09:15
  • Sure, simpy use `document.evaluate()` inside of `casper.evaluate()`: http://stackoverflow.com/questions/10596417/is-there-a-way-to-get-element-by-xpath-in-javascript – Artjom B. Apr 17 '15 at 09:19
  • casper.then(function(){ this.evaluate(function() { var form = document.getElementById({type:'xpath', path:"/html/body/div[3]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/select/option[3]"}); }); }); – GANA Apr 17 '15 at 09:36
  • `document.getElementById()` doesn't work like this, you need to use `document.evaluate()` to query elements based on XPaths. The link in my previous comment provides everything you need. – Artjom B. Apr 17 '15 at 09:37
  • i used the below code as you mentioned, casper.then(function(){ document.evaluate(function() { return document.getElementById({type:'xpath', path:"/html/body/div[3]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/select/option[3]"}); }); }); but it is throwing error TypeError: Not enough arguments to Document.evaluate. # type: uncaughtError # file: run_all/sample.js # error: {} # stack: not provided – GANA Apr 17 '15 at 09:47
  • This is completely wrong. You don't need to use `getElementById` at all. It seems you haven't read the [link](http://stackoverflow.com/a/14284815) properly. – Artjom B. Apr 17 '15 at 09:50
  • hey i gone through it but i am not getting it completely..i am using document.evaluate(".//*[@id='part1.R']/div[2]/div[2]/select", document, null, XPathResult.ANY_TYPE, null); but still not getting – GANA Apr 17 '15 at 10:17
  • Why do you use `XPathResult.ANY_TYPE` when you only expect one element? Use `XPathResult.FIRST_ORDERED_NODE_TYPE`. – Artjom B. Apr 17 '15 at 10:21
  • nope...still it is showing, Not enough arguments to Document.evaluate error.please look in to the code https://gist.github.com/tejas1493/18cedde89e7b09820446 – GANA Apr 17 '15 at 10:35
  • As I said before `document.evaluate()` works on the DOM, so it must be called inside of the page context (`casper.evaluate()`). – Artjom B. Apr 17 '15 at 10:44
  • ya i placed it under casper.evaluate(function(){ now but still, it is not switching – GANA Apr 17 '15 at 13:07
  • Not all CasperJS functions are asynchronous. `wait` and `then` are, but `evaluate` is not. You need to put the evaluate block into a step if the `wait(3000)` is important: `this.wait(3000, function(){ this.echo(this.evaluate(function(){ return !!document.evaluate("//*[@id='part1.R']/div[2]/div[2]/select", document, null,XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }); })) })` This should print true if the element is there. – Artjom B. Apr 17 '15 at 13:17