I am trying of different ways to select a specific button using seleninum webdriver with java but unfortunately, nothing is working.
When I tested using the Selenium IDE is working. I copied the same xpath, for example, but when I try to test in my java application nothing is working. I tried using different ways, By.cssSelector and By.path.
This is my html:
<section class="fd-section"><fd-action-bar><div class="fd-action-bar"><fd-action-bar-header class="fd-action-bar__header"><fd-action-bar-title><h1 class="fd-action-bar__title"> Applications </h1></fd-action-bar-title></fd-action-bar-header><fd-action-bar-actions class="fd-action-bar__actions"><y-list-search _nghost-c4="" hidden=""><!----><!----><div _ngcontent-c4="" clickoutsideevents="click,mousedown" excludebeforeclick="true" class="ng-star-inserted"><!----><button _ngcontent-c4="" fd-button="" class="fd-button xyz-icon--search fd-button--light ng-star-inserted"></button><!----></div></y-list-search><y-list-filter _nghost-c5="" hidden=""><!----></y-list-filter><!----><button class="open-create-namespace-modal fd-button xyz-icon--add ng-star-inserted" fd-button=""> Create Application </button></fd-action-bar-actions></div></fd-action-bar></section>
I need to select the button with the text " Create Application ".
When I created a test using Selenium IDE the xpath for this button is:
//button[contains(.,' Create Application')]
Basically, my java code is:
public WebElement wElement;
wElement = driver.findElement(By.xpath("//button[contains(.,' Create Application')]"));
wElement.click();
This is the exception message:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//button[contains(.,' Create Application')]"}
(Session info: chrome=76.0.3809.100)
(Driver info: chromedriver=72.0.3626.69 (3c16f8a135abc0d4da2dff33804db79b849a7c38),platform=Mac OS X 10.14.6 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:19:58.91Z'
System info: host: 'C02WW0BZHTD8', ip: 'fe80:0:0:0:8f6:17e1:1a28:1e23%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.14.6', java.version: '1.8.0_171'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, acceptSslCerts: false, applicationCacheEnabled: false, browserConnectionEnabled: false, browserName: chrome, chrome: {chromedriverVersion: 72.0.3626.69 (3c16f8a135abc..., userDataDir: /var/folders/2r/99nyn7t16cz...}, cssSelectorsEnabled: true, databaseEnabled: false, goog:chromeOptions: {debuggerAddress: localhost:60374}, handlesAlerts: true, hasTouchScreen: false, javascriptEnabled: true, locationContextEnabled: true, mobileEmulationEnabled: false, nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: MAC, platformName: MAC, proxy: Proxy(), rotatable: false, setWindowRect: true, takesHeapSnapshot: true, takesScreenshot: true, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unexpectedAlertBehaviour: ignore, unhandledPromptBehavior: ignore, version: 76.0.3809.100, webStorageEnabled: true}
Session ID: b2341899cd9b62b0169b02371aaa3018
*** Element info: {Using=xpath, value=//button[contains(.,' Create Application')]}
When this piece of code is being executed, is the button loaded into the page already?
{implicit: 0, pageLoad: 300000, script: 30000}, suggests that the driver will not implicitly wait for finding any elements. i.e. if the element is not available, it will throw the exception immediately.
Try driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS); before you attempt to find the button.
Also try using below locators -
//button[contains(.,'Create Application')]
//button[contains(text(),'Create Application')]
If none of the above works, please can you provide a URL (if it is public)
Also check whether the button is inside a frame.
You can use JavascriptExecutor interface in this case and try to click the button.
WebElement element = driver.findElement(By.xpath("//button[contains(text(),'Create Application')]"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
Also give a try with WebDriverWait
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(),'Create Application')]"))).click();
The desired element is an Angular element so to locate the element you have to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("fd-action-bar-actions.fd-action-bar__actions button.open-create-namespace-modal.fd-button.xyz-icon--add.ng-star-inserted"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='open-create-namespace-modal fd-button xyz-icon--add ng-star-inserted' and contains(., 'Create Application')]"))).click();
Additional Considerations
Ensure that:
JDK is upgraded to current levels JDK 8u212.
Selenium is upgraded to current levels Version 3.141.59.
ChromeDriver is updated to current ChromeDriver v76.0 level.
Chrome is updated to current Chrome Version 76.0 level. (as per ChromeDriver v76.0 release notes)
Here you can find a detailed discussion on NoSuchElementException, Selenium unable to locate element
Related
I am implementing a script that logs into a web page and perform certain actions, that are irrelevant in this case. This is the code that executes the login:
WebDriver driver;
JavascriptExecutor exec;
String dni = "...";
String passwd = "...";
driver = new ChromeDriver();
exec = (JavascriptExecutor) driver;
// Search web page
driver.get("http://example.com");
// Accept cookies
driver.findElement(By.id("aceptarCookies")).click();
// Login
driver.findElement(By.id("areaPersonal")).click();
driver.findElement(By.id("tab_login_user")).sendKeys(dni);
driver.findElement(By.id("tab_login_password")).sendKeys(passwd);
driver.findElement(By.id("loginFormHeader")).findElement(By.id("buttonHeader")).click();
The bot logs in successfully and, once logged in, if I want to execute any instruction I get very strange behaviors. If I try to search for any item within the home page it doesn't find it because it hasn't been loaded yet, for example adding this instruction just below:
// Search body item
driver.findElement(By.id("my_panel_page"));
However, if I add an implicit wait:
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
// Search body item
driver.findElement(By.id("my_panel_page"));
Or an explicit wait:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("id_of_new_item")));
driver.findElement(By.id("my_panel_page"));
The script hangs and does not execute any more instructions. For example, if I add the following print, it never gets executed:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("id_of_new_item")));
System.out.println("Page loaded!!!");
driver.findElement(By.id("my_panel_page"));
The behavior is very strange, it is as if selenium does not work once the page has been loaded, it only works when the new page is still loading and the HTML objects I want to use are not yet available. I'm using the following versions:
ChromeDriver: 109.0.5414.74
Chrome: 109.0.5414.120
Selenium: 3.141.59
JDK: 11.0.16.1
I can't indicate specific data of the web page I'm using because it is detected as spam, but I have previously made sure that the items I'm searching on the script exists in the HTML code, in fact, the script worked correctly until a few months ago.
EDIT:
I add some examples of output to better understand the problem. If I execute the instruction driver.findElement(By.id("my_panel_page")); without using any type of wait the output is as follows:
... (Initialize ChromeDriver)
no such element: Unable to locate element: {"method":"css selector","selector":"#my_panel_page"}
(Session info: chrome=109.0.5414.120)
For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'xxx', ip: 'xxx', os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '11.0.16.1'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 109.0.5414.120, chrome: {chromedriverVersion: 109.0.5414.74 (e7c5703604da..., userDataDir: C:\Users\xxx\AppData\Loca...}, goog:chromeOptions: {debuggerAddress: localhost:52373}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
Session ID: 533a8a11a33254b8ab788522dada77ab
*** Element info: {Using=id, value=my_panel_page}
If I use some kind of wait I didn't get an output, the ChromeDriver initializes and logs into the web page successfully, but its execution hangs when it reaches the wait statement. It only prints the ChromeDriver initialization info:
Starting ChromeDriver 109.0.5414.74 (e7c5703604daa9cc128ccf5a5d3e993513758913-refs/branch-heads/5414#{#1172}) on port 15136
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
feb. 01, 2023 5:28:28 P. M. org.openqa.selenium.remote.ProtocolHandshake createSession
INFORMACIËN: Detected dialect: W3C
presenceOfElementLocated()
presenceOfElementLocated() is the expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.
Solution
So instead of presenceOfElementLocated(), you have to induce WebDriverWait for the visibilityOfElementLocated() and you can use the following solution:
So instead of presenceOfElementLocated(), you have to induce WebDriverWait for the visibilityOfElementLocated() and you can use the following solution:
try
{
new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.id("id_of_new_item")));
System.out.println("new_item is visible");
System.out.println("Page loaded!!!");
driver.findElement(By.id("my_panel_page"));
// lines of the program
}
catch(TimeoutException e) {
System.out.println("new_item is not visible");
}
// remaining lines of the program
I am trying to run the following code:
WebElement body = driver.findElement(By.xpath("/html/body"));
js.executeScript("var injector = window.angular.element(argument[0]).injector(); var $http = injector.get('$http'); return ($http.pendingRequests.length === 0);",body);
I however get the following error:
org.openqa.selenium.JavascriptException: javascript error: Cannot read properties of undefined (reading 'element')
(Session info: chrome=103.0.5060.134)
Build info: version: '4.2.2', revision: '683ccb65d6'
System info: host: 'DESKTOP-UPVJF2U', ip: '192.168.0.132', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '18.0.1.1'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Command: [c6b4ce36aa115d9746065cead6c3271b, executeScript {script=var injector = window.angular.element(argument[0]).injector(); var $http = injector.get('$http'); return ($http.pendingRequests.length === 0);, args=[{ELEMENT=a0c33e06-9db9-49ed-984f-535b6bc72f7a, element-6066-11e4-a52e-4f735466cecf=a0c33e06-9db9-49ed-984f-535b6bc72f7a}]}]
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 103.0.5060.134, chrome: {chromedriverVersion: 103.0.5060.134 (8ec6fce403b..., userDataDir: C:\Users\win10\AppData\Loca...}, goog:chromeOptions: {debuggerAddress: localhost:53279}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: WINDOWS, proxy: Proxy(), se:cdp: ws://localhost:53279/devtoo..., se:cdpVersion: 103.0.5060.134, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
Session ID: c6b4ce36aa115d9746065cead6c3271b
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:200)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:133)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:53)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:184)
at org.openqa.selenium.remote.service.DriverCommandExecutor.invokeExecute(DriverCommandExecutor.java:167)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:142)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:588)
at org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:522)
at com.vilcart.app.CustomerCreation.testCreation(CustomerCreation.java:118)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
... Removed 28 stack frames
Can you please let me know how i could resolve this issue?
Since you want to get arguments list element by index try to replace
argument[0]
with
arguments[0]
#suhail shaik You can try the following, assuming you want to check if all the pending $http requests are served by Angular in the background.
String angularReady = "return angular.element(document).injector().get('$http').pendingRequests.length === 0";
boolean isAngularReady = (boolean)js.executeScript(angularReady);
I have gone through this link which helped me find a solution. This has a way to put wait for angular version 5 which is working for my current angular version 11.
https://www.swtestacademy.com/selenium-wait-javascript-angular-ajax/
Here is the scenario:
Click a link that opens up to a new tab.
Call getWindowHandles() and switch to the new tab.
Use JavaScript Executor to open up the Print PopUp
Call getWindowHandles() again to switch focus to the Print PopUp
This second getWindowHandles() call is causing my script to timeout and I'm not sure why. Could someone help me figure out what's going on with this second call? Everything is working as expected until step 4
link.click();
ArrayList<String> handles2 = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(handles2.get(1));
((JavascriptExecutor)driver).executeScript("window.print()");
ArrayList<String> handles3 = new ArrayList<String> (driver.getWindowHandles());
Maybe useful information:
Error Message:
org.openqa.selenium.ScriptTimeoutException: script timeout
(Session info: chrome=86.0.4240.183)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: '', ip: '', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_261'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: true, browserName: chrome, browserVersion: 86.0.4240.183, chrome: {chromedriverVersion: 86.0.4240.22 (..., userDataDir: C:\Users\AppData\L...}, goog:chromeOptions: {debuggerAddress: localhost:}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
The issue was the print dialog causing the main thread to lock out.
You are able to use the Robot class as suggested by #pcalkins. But I used the SetTimeout function.
Reference: ChromeDriver - Timeout when trying to print page with javascript
This question already has answers here:
An error has occured in 'site url': Uncaught TypeError: Cannot read property 'getColomnSet' of undefined with Selenium and Python
(2 answers)
"unknown error: cannot read property 'scrollleft' of null" in Chrome using selenium
(1 answer)
Closed 2 years ago.
enter image description here Facing Below error while taking (org.openqa.selenium.JavascriptExecutor)
String style = "";
style = (String) ((JavascriptExecutor) driver)
.executeScript("return document.getElementById(\"modalLayer\").getAttribute(\"style\")");
org.openqa.selenium.JavascriptException: javascript error: Cannot read property 'getAttribute' of null (Session info: headless chrome=80.0.3987.116) Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53' System info: host: 'cloudappnode1.chainsys.com', ip: '192.168.57.140', os.name: 'Linux', os.arch: 'amd64', os.version: '3.10.0-693.el7.x86_64', java.version: '11.0.5' Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 80.0.3987.116, chrome: {chromedriverVersion: 80.0.3987.106 (f68069574609..., userDataDir: /tmp/.com.google.Chrome.SYBV2k}, goog:chromeOptions: {debuggerAddress: localhost:41272}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify} Session ID: f574977f80da997e421f3783bb669
Please try the below code. Hope so that helps you. I have tested at my end and it is working fine.
JavascriptExecutor executor = (JavascriptExecutor) driver;
String data = String.valueOf(executor.executeScript(
"var styledata = document.getElementById('modalLayer').getAttribute('style');" + "return styledata;"));
System.out.println(data);
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));
}
}
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.
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)
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);
}