38

I have a html document in memory as a string. It contains a <script> tag with a little script that manipulates the dom. I now want to load that html page into selenium webdriver and get back the page after the script manipulates it. Since I have the html already in memory, I don't like the idea much of writing the html into a file and load it as file with driver.get("file://path/to/file"). So the question is, if there is a possibility to achieve what I want.

IF webdriver can't do it, maybe there is a possibility other than that?

Here comes an example:

<html><head>
<script type="text/javascript">
function fill(){
    var i = "secret"
    document.forms[0].elements[1].value=i
}
</script>
</head><body onload="fill()">
<form method="POST"><input type="hidden" name="he1" value="">
<input type="hidden" name="he2" value="">
</form></body></html>

Obviously, I want the webdriver to perform the dom manipulation and change the form according to the script.

Note this is just an example. The actual script I need to run does much more complicated things.

6 Answers 6

48

If you don't want to create a file or load a URL before being able to replace the content of the page, you can always leverage the Data URLs feature, which supports HTML, CSS and JavaScript:

ChromeDriver driver = new ChromeDriver();
html_content = """
<html>
     <head></head>
     <body>
         <div>
             Hello World =)
         </div>
     </body>
</html>
"""

driver.get("data:text/html;charset=utf-8," + html_content)
Sign up to request clarification or add additional context in comments.

4 Comments

So cool! After >4 years, finally comes someone with an answer that is doing the trick! Thanks :)
Javascript won't run.
I did not verify that this works. Could you elaborate Fan Jin?
This is very smart! And answering the other questions here, it fails because if you have any special characters like a ' it will break. The base64'd version from @moyang fixes this.
30

this code can load any html string which include js and css.

html_bs64 = base64.b64encode(innerHtml.encode('utf-8')).decode()
driver.get("data:text/html;base64," + html_bs64)

3 Comments

Thanks for answering. I can't test this at the moment. It looks similar to the solution that jolancornevin suggested in his answer 2 years ago. Anyone reading this and feels inclined to test it out, please report if this actually executes the Javascript as intended.
Hey @luksch I just tested and it indeed works, and better than the previous answer.
Working Java code: String encode = Base64.getEncoder().encodeToString(PAGE_AS_STRING.getBytes(StandardCharsets.UTF_8)); driver.get("data:text/html;base64," + encode);
21

You could load an empty page eg:

<html></html>

And then set it's innerHTML

ChromeDriver driver = new ChromeDriver();
driver.get("file://empty-page.html");
String innerHtml = "<head>...</head><body onload="...">...</body>";
driver.executeScript("document.innerHTML = " + innerHtml);

Then fire the load event on the body

driver.executeScript("$(document.body).trigger('load');");

Then get the resultant HTML

String result = driver.executeScript("document.body.innerHTML;");

5 Comments

awesome... great idea. I will try it asap.
This isn't guaranteed to work with IE. IE gets very emotional with local HTML files and throws it's toys out of the pram (because of it's security zones, there is a specific zone for local sites)
IE has one purpose... to download chrome ;)
It did not work - I now write the file and read it again. That works at least
All modern browsers support the about:blank URI schema. Just call driver.get('about:blank'); to load an empty HTML page.
6

Using Java Selenium 2.4.2 I use the following to replace inner html of an existing element. I use the Apache StringEscapeUtils.escapeJavaScript to escape the HTML because this is a JavaScript replace of the inner html.

    public void replaceHTML(By by, String html) {
      WebElement e = driver.findElement(by);
      ((JavascriptExecutor) driver).executeScript("arguments[0].innerHTML='" + StringEscapeUtils.escapeJavaScript(html) + "'", e);
    }

Example html String I passed in.

<button type="button" onclick="alert('Hello world!')">Click Me!</button>

Notes:

  • I couldn't get "Lance Java's" approach to work because of invalid escaped characters. Adding a single quote after the equal sign fixed this problem.

  • I tested "Kenneth Baltrinic's" suggestion of using driver.get('about:blank'); but I wasn't able to write to the screen interacting with the base document. In java I had to use double quotes driver.get("about:blank"). I tested this with Chrome.

1 Comment

I will test this. Thanks for the late response.
3

Just a small update: escapeEcmaScrip() replaces escapeJavaScript() in 2015.

public static void main(String[] args) throws InterruptedException{ 
    driver = new FirefoxDriver();
    driver.get("http://dhtmlx.com/docs/products/dhtmlxTree/");
    replaceHTML(By.xpath("//*/span[text()='Supported browsers:']"), "<button type=\"button\"  onclick=\"alert('Hello World!!')\">Click Me!</button>");
}

 private static void replaceHTML(By by, String html) {
      WebElement e = driver.findElement(by);
     ((JavascriptExecutor) driver).executeScript("arguments[0].innerHTML='" + StringEscapeUtils.escapeEcmaScript(html) + "'", e);

}

Comments

0

You could fire up jetty embedded. The jetty instance could then serve in memory html strings as web pages via a Servlet / Handler.

1 Comment

there is no kill like overkill :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.