Injecting javascript

1,998 views
Skip to first unread message

Larry Martell

unread,
Oct 4, 2013, 8:52:51 PM10/4/13
to seleniu...@googlegroups.com
For a test I need to inject some javascript. Googling this I found many examples of doing this with WebDriverBackedSelenium.getEval. I am using WebDriver, not WebDriverBackedSelenium and getEval doesn't seem to be available with that. Further googling showed that I should not use WebDriverBackedSelenium (https://groups.google.com/forum/#!topic/selenium-developers/vFD0KVGoarg). So how can I inject js with WebDriver?

Jim Evans

unread,
Oct 5, 2013, 12:04:47 AM10/5/13
to seleniu...@googlegroups.com
Cast your driver object to the JavascriptExecutor interface and use the executeScript method.

Larry Martell

unread,
Oct 6, 2013, 3:19:32 PM10/6/13
to seleniu...@googlegroups.com
On Friday, October 4, 2013 10:04:47 PM UTC-6, Jim Evans wrote:
Cast your driver object to the JavascriptExecutor interface and use the executeScript method.

I'm using python not java, but your reply led me to find execute_script.  Thanks.

What I'm trying to do is load a js function, and then execute it.

I'm doing it like this:

js_func = """
     function blah(a, b, c) {
        .
        .
        .
};
"""
self.selenium.execute_script(js_script)
self.selenium.execute_script("blah", 1,2,3)

I don't get any errors from the first one (creating the function), but the second one gives me:

*** WebDriverException: Message: u'blah is not defined'

Is what I'm doing valid? How I can tell if the function was successfully created? 

  

David

unread,
Oct 7, 2013, 2:37:19 PM10/7/13
to seleniu...@googlegroups.com
If I'm not mistaken, what you execute with JavascriptExecutor is not "globalized" or maintaining state. Therefore the previous function, blah, it's scope is within the context of the call of that first JavascriptExecutor. The 2nd call has no knowledge of blah since it did not persist. It's not the same like what you can do in a javascript/error console in browser developer tools which maintains state.

The safer way to ensure your javascript code will persist then is to inject the javacript by way of the DOM (i.e. DOM injection) via inserting a script tag element with the javascript inside it. Then it should persist afterwards (but will be lost on page refresh). You can also store the desired javascript code in a javascript file then link to it via the script tag when inserting rather than embedding the code within the script tag to save lines of code and improve readability. However that would mean you have to host the javascript file on a (test) web server.

Here's an example of DOM script element insertion to inject javascript, though this one uses the external javascript file reference, you can modify to instead have the javascript code within the script element. Easier to use the file reference technique:

String injectScript = "var script = document.createElement(\"script\");";
injectScript += "script.src = \""+scriptSrc+"\";";
injectScript += "script.setAttribute(\"type\",\"text/javascript\");";
injectScript += "document.body.appendChild(script);";
((JavascriptExecutor) driver).executeScript(injectScript);
//IE & Safari workaround: add delay for injected code to finish loading in DOM before we call that code
Thread.sleep(1000); 
//you should generally now be able to call the javascript code that has been injected. there might be some exception cases where it might not work (due to needing to be loaded on page load instead, etc.)

Larry Martell

unread,
Oct 10, 2013, 11:53:14 PM10/10/13
to seleniu...@googlegroups.com
On Mon, Oct 7, 2013 at 12:37 PM, David <mang...@gmail.com> wrote:
If I'm not mistaken, what you execute with JavascriptExecutor is not "globalized" or maintaining state. Therefore the previous function, blah, it's scope is within the context of the call of that first JavascriptExecutor. The 2nd call has no knowledge of blah since it did not persist. It's not the same like what you can do in a javascript/error console in browser developer tools which maintains state.

The safer way to ensure your javascript code will persist then is to inject the javacript by way of the DOM (i.e. DOM injection) via inserting a script tag element with the javascript inside it. Then it should persist afterwards (but will be lost on page refresh). You can also store the desired javascript code in a javascript file then link to it via the script tag when inserting rather than embedding the code within the script tag to save lines of code and improve readability. However that would mean you have to host the javascript file on a (test) web server.

Here's an example of DOM script element insertion to inject javascript, though this one uses the external javascript file reference, you can modify to instead have the javascript code within the script element. Easier to use the file reference technique:

String injectScript = "var script = document.createElement(\"script\");";
injectScript += "script.src = \""+scriptSrc+"\";";
injectScript += "script.setAttribute(\"type\",\"text/javascript\");";
injectScript += "document.body.appendChild(script);";
((JavascriptExecutor) driver).executeScript(injectScript);
//IE & Safari workaround: add delay for injected code to finish loading in DOM before we call that code
Thread.sleep(1000); 
//you should generally now be able to call the javascript code that has been injected. there might be some exception cases where it might not work (due to needing to be loaded on page load instead, etc.)


Thanks. Defining the script and calling in the same execute_script call worked.
 

On Sunday, October 6, 2013 12:19:32 PM UTC-7, Larry Martell wrote:
On Friday, October 4, 2013 10:04:47 PM UTC-6, Jim Evans wrote:
Cast your driver object to the JavascriptExecutor interface and use the executeScript method.

I'm using python not java, but your reply led me to find execute_script.  Thanks.

What I'm trying to do is load a js function, and then execute it.

I'm doing it like this:

js_func = """
     function blah(a, b, c) {
        .
        .
        .
};
"""
self.selenium.execute_script(js_script)
self.selenium.execute_script("blah", 1,2,3)

I don't get any errors from the first one (creating the function), but the second one gives me:

*** WebDriverException: Message: u'blah is not defined'

Is what I'm doing valid? How I can tell if the function was successfully created? 

  

--
You received this message because you are subscribed to a topic in the Google Groups "Selenium Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/selenium-users/aU0i4xFyejY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to selenium-user...@googlegroups.com.
To post to this group, send email to seleniu...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/selenium-users/797bdf26-2df9-4e90-b8c3-b24ee389bb69%40googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.

David Lai

unread,
Oct 11, 2013, 8:29:09 PM10/11/13
to seleniu...@googlegroups.com
Python is just driver.execute_script("javascript to execute", **var_args_of_parameters)

I have some simple example of using this to find elements by jquery.
Reply all
Reply to author
Forward
0 new messages