org.openqa.selenium.JavascriptException: javascript error: $ is not defined error taking coordinate screenshot with Ashot using ChromeDriver Selenium
Solution 1
This error message...
org.openqa.selenium.JavascriptException: javascript error: $ is not defined
(Session info: chrome=79.0.3945.130)
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
System info: host: 'OPTIMIZEQ-LTP03', ip: '192.168.99.1', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.2'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 79.0.3945.130, chrome: {chromedriverVersion: 78.0.3904.105 (60e2d8774a81..., userDataDir: C:\Users\SHAILE~1.SIN\AppDa...}, goog:chromeOptions: {debuggerAddress: localhost:61006}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: XP, platformName: XP, proxy: Proxy(manual, http=localhos..., setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webdriver.remote.sessionid: f5a47b27537f019dacb73462732...}
...implies that the ChromeDriver was unable to interact with the Browsing Context i.e. Chrome Browser session.
Deep dive
As per the documentation in ReferenceError: "x" is not defined this error means there is a non-existent variable referenced somewhere within the DOM Tree. This variable needs to be declared, or you need to make sure it is available in your current script or scope.
Hint: When loading a library (such as jQuery), make sure it is loaded before you access library variables, such as "$". Put the tag that loads the library before your code that uses it.
As per the discussion JavaScript/jQuery - “$ is not defined- $function()” error @Ketan mentions that this error occurs when you have not made jQuery available to your script, i.e. possibly the JavaScript / jQuery / AJAX haven't completed rendering the HTML DOM.
Solution
In these cases there are 3(three) different approaches available to solve the issue as follows:
-
The jQuery library is a single JavaScript file, and you reference it with the HTML
<script>
tag within the<head>
section as follows:<head> <script src="jquery-3.4.1.min.js"></script> </head>
This goes out and gets the jQuery code from the source.
Note: You do not have to include
type="text/javascript"
inside the<script>
tag as this is not required in HTML5. JavaScript is the default scripting language in HTML5 and in all modern browsers.
- You can also download the jQuery library and reference it locally on the server.
- You can induce WebDriverWait inconjunction with ExpectedConditions for the element's desired state either to be present / visible / interactable.
You can find a detailed discussion in Selenium: How selenium identifies elements visible or not? Is is possible that it is loaded in DOM but not rendered on UI?
This usecase
As you mentioned, the following line fails:
Coords elementCoords = ofElement(driver, element);
This method takes one of the arguments (last) as element, but while defining you seem to be treating it as a list of elements, as in:
@SuppressWarnings("UnusedDeclaration")
public Set<Coords> ofElements(WebDriver driver, WebElement... elements) {
return ofElements(driver, Arrays.asList(elements));
}
Seems some mismatch in argument types here.
Additional considerations
You need to take care of a couple of things more:
- You are using chromedriver=78.0.3904.105
- Release Notes of chromedriver=78.0 clearly mentions the following :
Supports Chrome version 78
- You are using chrome=79.0
- Release Notes of ChromeDriver v79.0 clearly mentions the following :
Supports Chrome version 79
- Your Selenium Client version is 3.14.0 of 2018-08-02T20:19:58.91Z which is almost 1.5 years older.
- Your JDK version is 11.0.2.
So there is a clear mismatch between JDK v8u111 , Selenium Client v3.3.1 , ChromeDriver v2.41 and the Chrome Browser v79.0
Solution
Ensure that:
- JDK is upgraded to current levels JDK 8u241.
- Selenium is upgraded to current levels Version 3.141.59.
- ChromeDriver is updated to current ChromeDriver v80.0 level.
- Chrome is updated to current Chrome Version 80.0 level. (as per ChromeDriver v80.0 release notes)
Solution 2
I found a solution here, https://medium.com/virtualmind-io/jquery-injection-for-selenium-automation-tests-f6121ea57993. Basically it injects jquery into the page. So I followed the steps and created this method that i used before calling AShot methods and could solve this issue, leaving the code here:
JavascriptExecutor js = (JavascriptExecutor) driver;
if(!(Boolean) js.executeScript("return (typeof jQuery != \"undefined\")")) {
js.executeScript(
"var headID = document.getElementsByTagName('head')[0];" +
"var newScript = document.createElement('script');" +
"newScript.type = 'text/javascript';" +
"newScript.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js';" +
"headID.appendChild(newScript);");
WebDriverWait waitJQ = new WebDriverWait(driver, 30);
Function<WebDriver, Boolean> jQueryAvailable = WebDriver -> (
(Boolean) js.executeScript("return (typeof jQuery != \"undefined\")")
);
waitJQ.until(jQueryAvailable);
}
ThinkTank
By Day: I will be available but I am not answering that means I am in the different timezone. By Night: I sleep like the hog. Interests: Learning new things which keeps me updated, and love mountains and trekking.
Updated on December 17, 2022Comments
-
ThinkTank over 1 year
I have encountered a weird problem while working with
AShot
.Ashot
works fine for whole screenShots but while selective screenShot it is BAD. It throws error in CoordsProvider Class while getting co-ordinates of element. am I using a faulty build or product?public abstract class CoordsProvider implements Serializable { public abstract Coords ofElement(WebDriver driver, WebElement element); public Set<Coords> ofElements(WebDriver driver, Iterable<WebElement> elements) { Set<Coords> elementsCoords = new HashSet<>(); for (WebElement element : elements) { ***Coords elementCoords = ofElement(driver, element); //fails here*** if (!elementCoords.isEmpty()) { elementsCoords.add(elementCoords); } } return Collections.unmodifiableSet(elementsCoords); } @SuppressWarnings("UnusedDeclaration") public Set<Coords> ofElements(WebDriver driver, WebElement... elements) { return ofElements(driver, Arrays.asList(elements)); } @SuppressWarnings("UnusedDeclaration") public Set<Coords> locatedBy(WebDriver driver, By locator) { return ofElements(driver, driver.findElements(locator)); } }
org.openqa.selenium.JavascriptException: javascript error: $ is not defined (Session info: chrome=79.0.3945.130) Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z' System info: host: 'OPTIMIZEQ-LTP03', ip: '192.168.99.1', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.2' Driver info: org.openqa.selenium.remote.RemoteWebDriver Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 79.0.3945.130, chrome: {chromedriverVersion: 78.0.3904.105 (60e2d8774a81..., userDataDir: C:\Users\SHAILE~1.SIN\AppDa...}, goog:chromeOptions: {debuggerAddress: localhost:61006}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: XP, platformName: XP, proxy: Proxy(manual, http=localhos..., setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webdriver.remote.sessionid: f5a47b27537f019dacb73462732...} Session ID: f5a47b27537f019dacb734627324a790 at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na] at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) ~[na:na] at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187) ~[selenium-remote-driver-3.14.0.jar:na] at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122) ~[selenium-remote-driver-3.14.0.jar:na] at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49) ~[selenium-remote-driver-3.14.0.jar:na] at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158) ~[selenium-remote-driver-3.14.0.jar:na] at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:548) ~[selenium-remote-driver-3.14.0.jar:na] at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:485) ~[selenium-remote-driver-3.14.0.jar:na] at ru.yandex.qatools.ashot.util.JsCoords.findCoordsWithJquery(JsCoords.java:30) ~[ashot-1.5.2.jar:na] at ru.yandex.qatools.ashot.coordinates.JqueryCoordsProvider.ofElement(JqueryCoordsProvider.java:13) ~[ashot-1.5.2.jar:na] at ru.yandex.qatools.ashot.coordinates.CoordsProvider.ofElements(CoordsProvider.java:21) ~[ashot-1.5.2.jar:na] at ru.yandex.qatools.ashot.AShot.takeScreenshot(AShot.java:115) ~[ashot-1.5.2.jar:na] at ru.yandex.qatools.ashot.AShot.takeScreenshot(AShot.java:132) ~[ashot-1.5.2.jar:na] at com.optq.main.util.SeleniumDriverUtility.captureAShotElement(SeleniumDriverUtility.java:563) ~[classes/:na]
Any help or Alternatives For Ashot are welcome,Please help me into this.
-
ThinkTank about 4 yearsthanks for speedy help @debanjanB It is using
private CoordsProvider coordsProvider = new JqueryCoordsProvider();
rest checkList is verified by me,I think that is Ashot team must change their Implementation. -
undetected Selenium about 4 yearsI think @valfirst pointed us to the right direction in the discussion Ashot is failing to take coordinate/Screenshot in chrome 79.0.3945.130 and selenium 3.141.59 that instead of JqueryCoordsProvider we need to use WebDriverCoordsProvider
-
ThinkTank about 4 yearsyes but library is using this.
private CoordsProvider coordsProvider = new JqueryCoordsProvider();
I think that I can't change in JAR -
Jeff almost 3 yearsCould you please update your answer ? The chromeDriver version is now over 90.