Take the 2-minute tour ×
Software Quality Assurance & Testing Stack Exchange is a question and answer site for software quality control experts, automation engineers, and software testers. It's 100% free, no registration required.

Is it possible to inject a jQuery script into a page if the page isn't already using jQuery? We have a few pages in our sites where we don't add jQuery if it doesn't need it, but I'm using it to automate the page with WebDriver. I don't want to test my JavaScript on every browser just for these pages.

Example usage of jQuery code:

public static long GetLongValueViaJQuery(IWebDriver driver, string jQueryCode)
{
    IJavaScriptExecutor js = driver as IJavaScriptExecutor;
    return (long)js.ExecuteScript("return " + jQueryCode);
}
share|improve this question
add comment

4 Answers

I am seeing one issue in this. I am getting "Exception in thread "main" org.openqa.selenium.WebDriverException: jQuery is not defined" exception on executing js.executeAsyncScript(jQueryLoader);

share|improve this answer
    
This looks like a commentary on the post and not an actual answer to the question. Plus this is a very old question you are answering. Consider elaborating a bit further. –  Dan Snell Apr 5 at 23:10
add comment

Here is a script which loads jQuery through WebDriver. I've been using it successfully for quite some time.

Features:

-- will not overwrite any existing jQuery instance.
-- will not alter the DOM under test or pollute the global namespace
-- cleans up after itself to avoid memory leaks
-- waits for jQuery to be fully loaded before returning.
-- takes an optional parameter specifying a jQuery source (defaults to version 1.7.2 from Google's CDN).
-- cross-browser compatible

The Script:

You must pass this as a string to IJavaScriptExecutor.ExecuteAsyncScript:

/** dynamically load jQuery */
(function(jqueryUrl, callback) {
    if (typeof jqueryUrl != 'string') {
        jqueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
    }
    if (typeof jQuery == 'undefined') {
        var script = document.createElement('script');
        var head = document.getElementsByTagName('head')[0];
        var done = false;
        script.onload = script.onreadystatechange = (function() {
            if (!done && (!this.readyState || this.readyState == 'loaded' 
                    || this.readyState == 'complete')) {
                done = true;
                script.onload = script.onreadystatechange = null;
                head.removeChild(script);
                callback();
            }
        });
        script.src = jqueryUrl;
        head.appendChild(script);
    }
    else {
        callback();
    }
})(arguments[0], arguments[arguments.length - 1]);

Example Usage (Java):

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

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

/**
 * An example of loading jQuery dynamically using WebDriver.
 */
public class Test {

    // its nice to keep JavaScript snippets in separate files.
    private static final String JQUERY_LOAD_SCRIPT = "resources\\jQuerify.js";

    // driver
    public static void main(String[] args) throws Exception {
        WebDriver driver = new FirefoxDriver();
        driver.get("http://www.google.com");

        String jQueryLoader = readFile(JQUERY_LOAD_SCRIPT);

        // give jQuery time to load asynchronously
        driver.manage().timeouts().setScriptTimeout(10, TimeUnit.SECONDS);
        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeAsyncScript(jQueryLoader /*, http://localhost:8080/jquery-1.7.2.js */);

        // ready to rock
        js.executeScript(
            "jQuery(function($) { " +
                " $('input[name=\"q\"]').val('bada-bing').closest('form').submit(); " +
            " }); "
        );
    }

    // helper method
    private static String readFile(String file) throws IOException {
        Charset cs = Charset.forName("UTF-8");
        FileInputStream stream = new FileInputStream(file);
        try {
            Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
            StringBuilder builder = new StringBuilder();
            char[] buffer = new char[8192];
            int read;
            while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
                builder.append(buffer, 0, read);
            }
            return builder.toString();
        }
        finally {
            stream.close();
        }        
    }
}

Credits:

I adapted this script from the excellent jQuerify bookmarklet by Karl Swedberg.

share|improve this answer
add comment

Here is my extension method I am using with WatiN

The parameter Browser – is WatiN’s browser object.

And also, WitiN required to pass the JavaScript code as a single line. That is why you can see .Replace("\r\n", ""); in the code:

    public static void InjectJQuery(this Browser browser)
    {
        string injectjQuery2 = @"
               function loadScript(scriptUrl) 
               {
                   var head =  document.getElementsByTagName('head')[0];
                   var script = document.createElement('script');
                   script.type = 'text/javascript';
                   script.src = scriptUrl;
                   head.appendChild(script);
               }
               loadScript('https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js');
               loadScript('https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js');
               ".Replace("\r\n", "");

        browser.Eval(injectjQuery2);
    }
share|improve this answer
    
Clean solution, I like it. –  Sam Woods Mar 28 '12 at 0:12
add comment

I haven't tested this, but in theory it should work. You can use javascript like this to load new js files into memory:

var scriptElt = document.createElement('script'); scriptElt.type = 'text/javascript'; scriptElt.src = jsFile; document.getElementsByTagName('head')[0].appendChild(scriptElt);

You would need to load all of the jquery javascript libraries and then you would be able to call the jqeury functions as you listed above.

share|improve this answer
    
Unless you load jQuery from the same domain as your webapp, you may run into this problem: sqa.stackexchange.com/questions/2850/…. –  user246 Mar 27 '12 at 17:57
    
Again, I haven't tested it, but I'm pretty sure the jquery javascript library employs domain lowering to work in this case. Very true that this could cause problems for a lot of .js files though. –  Sam Woods Mar 28 '12 at 0:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.