20

I'm using Selenium WebDriver to try to insert an external javascript file into the DOM, rather than type out the entire thing into executeScript.

It looks like it properly places the node into the DOM, but then it just disregards the source, i.e. the function on said source js file doesn't run.

Here is my code:

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class Example  {
    public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.get("http://google.com");
        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("document.getElementsByTagName('head')[0].innerHTML += '<script src=\"<PATH_TO_FILE>\" type=\"text/javascript\"></script>';");
    }
}

The code of the javascript file I am linking to is

alert("hi Nate");

I've placed the js file on my localhost, I called it using file:///, and I tried it on an external server. No dice.

Also, in the Java portion, I tried appending 'scr'+'ipt' using that trick, but it still didn't work. When I inspect the DOM using Firefox's inspect element, I can see it loads the script node properly, so I'm quite confused.

I also tried this solution, which apparently was made for another version of Selenium (not webdriver) and thus didn't work in the least bit: Load an external js file containing useful test functions in selenium

Community
  • 1
  • 1
Nate L
  • 465
  • 1
  • 5
  • 17

2 Answers2

15

According to this: http://docs.seleniumhq.org/docs/appendix_migrating_from_rc_to_webdriver.jsp

You might be using the browserbot to obtain a handle to the current window or document of the test. Fortunately, WebDriver always evaluates JS in the context of the current window, so you can use “window” or “document” directly.

Alternatively, you might be using the browserbot to locate elements. In WebDriver, the idiom for doing this is to first locate the element, and then pass that as an argument to the Javascript. Thus:

So does the following work in webdriver?

WebDriver driver = new FirefoxDriver();
((JavascriptExecutor) driver)
  .executeScript("var s=window.document.createElement('script');\
  s.src='somescript.js';\
  window.document.head.appendChild(s);");
HMR
  • 37,593
  • 24
  • 91
  • 160
  • 1
    Yes it does! I ended up messing around with it for a while longer and I believe the issue wasn't with Selenium or anything like that, but with my use of innerHTML to append the DOM, rather than appendChild, as per http://stackoverflow.com/questions/1197575/can-scripts-be-inserted-with-innerhtml Hopefully this question will help someone in the future, because I didn't ever find a working example of using selenium to add an external javascript file – Nate L Jun 30 '13 at 07:53
  • Nice code, guy, but in which path this js should be? – estemendoza Apr 22 '14 at 01:15
  • 2
    @estemendoza I guess it's relative but can be root relative like `/js/somescript.js` or on your lical computer `file://home/me/js/somescript.js` – HMR Apr 22 '14 at 06:04
  • Ok, js file is loaded, because I'm seeing it by calling document.head.lastChild, but I can't call any method defined inside the file, always "bla is not defined". I'm using python by the way. – estemendoza Apr 22 '14 at 18:37
  • Make sure the script is loaded other script depending on it could be started on the onload event of the script element or use setTimeout until the script is loaded and objects defined in the script are available. – HMR Apr 23 '14 at 08:44
  • Well, after doing this I get an error like `Loading failed for the – Burak Kaymakci Mar 12 '19 at 09:10
6

Injecting our JS-File into DOM

Injecting our JS-File into browsers application from our local server, so that we can access our function using document object.

injectingToDOM.js

var getHeadTag = document.getElementsByTagName('head')[0]; 
var newScriptTag = document.createElement('script'); 
newScriptTag.type='text/javascript'; 
newScriptTag.src='http://localhost:8088/WebApplication/OurOwnJavaScriptFile.js';
// adding <script> to <head>
getHeadTag.appendChild(newScriptTag);

OurSeleniumCode.java

String baseURL = "http://-----/";
driver = new FirefoxDriver();
driver.navigate().to(baseURL);
JavascriptExecutor jse = (JavascriptExecutor) driver;
Scanner sc = new Scanner(new FileInputStream(new File("injectingToDOM.js")));
String inject = ""; 
    while (sc.hasNext()) {          
        String[] s = sc.next().split("\r\n");   
        for (int i = 0; i < s.length; i++) {
            inject += s[i];
            inject += " ";
        }           
    }       
    jse.executeScript(inject);
    jse.executeScript("return ourFunction");

OurOwnJavaScriptFile.js

document.ourFunction =  function(){ .....}

Note : If you are passing JS-File as String to executeScript() then don't use any comments in between JavaScript code, like injectingToDOM.js remove all comments data.

Yash
  • 9,250
  • 2
  • 69
  • 74