2

I want to read the page's source code after it has changed due to some ajax requests. Since I'm running out of ideas, I tried JavaScript, but the executeScript() function always returns null. Any help would be much appreciated.

I use the FirefoxDriver. My code looks as follows:

Object test = ((JavascriptExecutor) firefox).executeScript("function getHTML(){ return document.body.innerHTML;} getHTML();");
System.out.println(test);
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
MightyMalcolm
  • 191
  • 1
  • 16

2 Answers2

4

You need to have something returned from the script:

Object test = ((JavascriptExecutor) firefox).executeScript("return document.body.innerHTML;");
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • I thought calling my function via getHTML() would be enough. But your solution works, so I am very grateful. Cheers! :) – MightyMalcolm Feb 05 '15 at 22:26
  • @alecxe Why OPS code doen't work. I can easily test that on Chrome and works – Saifur Feb 05 '15 at 22:29
  • @Saifur well, adding the `return` could also do the trick: `function getHTML(){ return document.body.innerHTML;} return getHTML();`. – alecxe Feb 05 '15 at 22:30
  • Hmm interesting. Thanks for the clarification. – Saifur Feb 05 '15 at 22:31
  • 1
    @Saifur yup, tested it using the python bindings: without the `return` I get nothing, with - I get the `innerHTML` of the body. Thanks. – alecxe Feb 05 '15 at 22:32
  • @alecxe hmm, it seems i was a bit too fast yesterday and my question isn't answered after all. the JavaScript execution now works, but it gives me the stale sourcecode that does not reflect the ajax changes. My issue seems to be similiar to [this one](http://stackoverflow.com/questions/25356440/need-to-dump-entire-dom-tree-with-element-id-from-selenium-server) that you answered as well, but it relies on the same method. – MightyMalcolm Feb 06 '15 at 09:49
1

I am assuming the dom is not in ready state and you are trying to fetch is too fast. I am modifying alecxe's answer a little bit to add additional explicit wait that will make sure the dom is in ready state. This program will wait until 10 s to make sure the dom is in ready state.

Wait<WebDriver> wait = new WebDriverWait(driver,10);
wait.until(new Function<WebDriver, Boolean>() {
    public Boolean apply(WebDriver driver) {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState;").equals("complete");
    }
});

Object test = ((JavascriptExecutor) driver).executeScript("return document.body.innerHTML;");
Saifur
  • 16,081
  • 6
  • 49
  • 73
  • @dadoosh modified. Take a look – Saifur Feb 07 '15 at 06:04
  • really appreciate your efforts, but they seem to make no difference. I am checking for some attribute values and the fun thing is, that `driver.findElement()` returns them correctly whilst yours and alecxe's does not. Still, every `findElement()` call takes about 0.1 secs and i have to check more than 10 elements in a time-critical moment. My code looks as follows, maybe i've done sth wrong? – MightyMalcolm Feb 07 '15 at 09:28
  • `Object test = stackOverflowMethod(firefox); Document doc = Jsoup.parse(test.toString()); debugger.println(doc.getElementById("input_field1").attr("value")); debugger.println(firefox.findElement(By.xpath(XPaths.INPUT_FIELD_1).getAttribute("value"));` The `stackOverfflowMethod()` obviously is 100% the code you posted. *EDIT: sry i am too stupid to use the code tag in comments appropriately it seems -.- – MightyMalcolm Feb 07 '15 at 09:37