0

My problem lies on this page

There is a canvas element on this page which is an image having a number which changes whenever you refresh page or do anything on the page which requires reloading.

In the source code what I see is only this:

<div class="row">
      <div class="large-10 columns">
        <canvas id="canvas" width="599" height="200" style="border:1px dotted;"></canvas>
      </div>
    </div>

So in-short there is nothing I can do with this info on the outer html but when I went to network section and saw the response code in which I found this code which uses javascript:

    <script>var canvas_el = document.getElementById('canvas');
var canvas = canvas_el.getContext('2d');
canvas.font = '60px Arial';
canvas.strokeText('Answer: 19403',90,112);
</script>

Now my problem is how can I write javascript(I don't know that much of javascript) in selenium webdriver to get this details(Specifically strokeText) under the script tag which are otherwise not there on the source code. I am looking for some solution using JavascriptExecutor.

Cœur
  • 37,241
  • 25
  • 195
  • 267
MohitChouhan
  • 1
  • 1
  • 2
  • Just in case you are wondering what I have tried. I came across this answer: https://stackoverflow.com/questions/14904378/get-data-attribute-of-script-tag But in this case they are getting the data attributes which are linked to script tag itself unlike here where I want to get attributes which are inside of script tag. – MohitChouhan May 10 '18 at 15:07

1 Answers1

1

You had the right idea with using JavascriptExecutor. I found the basic strategy here.

final By SCRIPT = By.tagName("script");

List<WebElement> scripts = new WebDriverWait(driver, 5)
        .until(ExpectedConditions.presenceOfAllElementsLocatedBy(SCRIPT));

JavascriptExecutor js = (JavascriptExecutor) driver;
String query = "return document.getElementsByTagName(\"script\")[arguments[0]].innerHTML;";     
Pattern p = Pattern.compile("canvas.strokeText\\('Answer: \\d+'");
Pattern p2 = Pattern.compile("\\d+");

String number = IntStream.range(0, scripts.size())
        .mapToObj(i -> (String)js.executeScript(query, i))
        .map(string -> p.matcher(string))
        .filter(m -> m.find())
        .map(m -> p2.matcher(m.group()))
        .filter(m -> m.find())
        .map(m -> m.group())
        .findFirst()
        .orElse(null);
System.out.println(number);  // prints the number rendered on the page
Parabolord
  • 302
  • 3
  • 13
  • It works! but I have a query here what is that 'arguments[0]'. Does that mean you are getting the first script tag of all script tags present in the source code? – MohitChouhan Jun 02 '18 at 11:58
  • It's a way to supply arguments to the javascript script. Try this: `js.executeScript("alert(arguments[0])", "Mohit", "Chouhan");` and then this: `js.executeScript("alert(arguments[1])", "Mohit", "Chouhan");`. Explained [here](https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/JavascriptExecutor.html#executeScript-java.lang.String-java.lang.Object...-) – Parabolord Jun 02 '18 at 20:10