1

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));
}
}

enter image description here Stack trace

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.

0

2 Answers 2

5

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 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:

Sign up to request clarification or add additional context in comments.

4 Comments

thanks 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.
I 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
yes but library is using this. private CoordsProvider coordsProvider = new JqueryCoordsProvider(); I think that I can't change in JAR
Could you please update your answer ? The chromeDriver version is now over 90.
3

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);
        }

Comments

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.