Since last week I got stuck in a problem that can't resolve it.
I have an ear project containing an EJB project and a WAR project that worked fine before.
When I execute my project first i get the login page, authenticate and get my home page.
But when I want to write in an input, i tell him to wait until the element is visible but it throws a WebDriverEception :
Can't send keys to the element com.sun.proxy.$Proxy23 Expected condition failed: waiting for visibility of [[ChromeDriver: chrome on XP (508d2b6115709e937cfa289fdb0a438b)] -> xpath: //div[#class='form-control browse__browse-name-display___2s17-']/following-sibling::input[#type='file']] (tried for 20 second(s) with 500 milliseconds interval)
The problem here is that I have an old project with the same files and when I execute it through main class, it works fine but when i want to run it with Junit, i get this exception.
This is my Code :
public void sendKeyOnElement(WebElement element, String string) {
try {
if (new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOf(element)) != null) {
System.out.println("d5allll");
if (element.getText().equals(""))
element.sendKeys(string);
else {
System.out.println("d5al louta");
element.clear();
element.sendKeys(string);
}
} else {
System.out.println("Can't send keys element not visible ");
}
} catch (ElementNotVisibleException v) {
System.out.println("Element Not Visible");
} catch (WebDriverException e) {
System.out.println("Can't send keys to the element " + element.getClass().getName() + " " + e.getMessage());
}
}
After modifying my code it appears to be a Timeout Exception but the problem is that the element exists and returns its tagName and shows that the element is enabled
public boolean waitVisibilityOfElement(WebElement element) {
try {
System.out.println("Waiting visibility of element : " + element.getTagName());
if (element.isEnabled())
System.out.println("Element " + element.getTagName() + " is enabled");
else
System.out.println("Element " + element.getTagName() + " is not enabled");
fluentWait.until(ExpectedConditions.visibilityOf(element));
return true;
} catch (TimeoutException e) {
System.out.println("Time out for visibility");
return false;
} catch (ElementNotVisibleException v) {
System.out.println("Element Not Visible");
return false;
} catch (NoSuchElementException u) {
System.out.println("Element does not exist");
return false;
}
}
public void sendKeyOnElement(WebElement element, String string) {
try {
if (waitVisibilityOfElement(element)) {
System.out.println("d5allll");
if (element.getText().equals(""))
element.sendKeys(string);
else {
System.out.println("d5al louta");
element.clear();
element.sendKeys(string);
}
} else {
System.out.println("Can't send keys element not visible ");
}
} catch (ElementNotVisibleException v) {
System.out.println("Element Not Visible");
} catch (WebDriverException e) {
System.out.println("Can't send keys to the element " + element.getClass().getName() + " " + e.getMessage());
}
I can't show my Html because it is confidential but i can only show the div and input elements :
<div class="form-control browse__browse-name-display___2s17-"> </div>
<input type="file" style="display:none">
I found the solution.
I don't know if it is normal with selenium, but by default the input which its type is file can't be displayed although it is displayed in Web Browser, The method isEnabled() returns true and isDisplayed() returns false so the wait until will wait, and at the end will throws a Timeout Exception and The most funny thing is even for selenium it is not displayed you can send keys in the input which is not logic.
Related
Below is the screenshot of the mouse hover event.
Style type
It is triggered only on mouse hover. Currently, I'm able to read the Style Type Text. I can select the first element without any issues, however, I'm unable to click the second and last element (Categorized and Graduated ).
UI Code for reference.
UI code
Below is the Selenium code for reference.
static void styletype() throws InterruptedException {
Thread.sleep(1000);
String sname = null;
// select style type
Actions action = new Actions(driver);
WebElement menu = driver.findElement(By.xpath("//*[#src = 'assets/images/down_arrow.svg']"));
action.moveToElement(menu).perform();
Thread.sleep(1500);
List<WebElement> rowsList = driver.findElements(By.xpath("//*[contains(#class,'dropdown-item')]"));
for (WebElement element : rowsList) {
try {
sname = element.getText();
// System.out.println("File Type is : " + sname);
int result = JOptionPane.showConfirmDialog(frame, "Layer Stype Type : '" + sname + "'",
"Do you want to continue", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == 0) {
element.click();
break;
}
action.moveToElement(menu).perform();
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
This question already has answers here:
Getting StaleElementReferenceException while trying print the link names
(3 answers)
Selenium Webdriver - Stale element exception when clicking on multiple dropdowns while HTML DOM doesn't change
(1 answer)
StaleElementReference Exception in PageFactory
(3 answers)
Closed 4 years ago.
I have try all available solving
WebDriverWait wait6 = new WebDriverWait(driver, 500);
wait6 .until(ExpectedConditions.presenceOfElementLocated(By.xpath("(//i[#class='material-icons'])[" + j + "]")));
I have application where I need to click on all item and get text of item name I am get Stale Element Reference Exception.
I have try to put different method to resolve it but nothing working.
public void page(WebDriver driver, String Filtername) throws InterruptedException {
waitForElementPresent(driver, 60, sidenavbutton);
click(driver, sidenavbutton);
Thread.sleep(2000);
click(driver, viewcopyportfolio);
Thread.sleep(1000);
click(driver, sidenavbutton);
waitForElementPresent(driver, 30, porfoliosheader);
clearText(driver, pagenumtextbox);
Thread.sleep(1000);
setText(driver, pagenumtextbox, Filtername);
Thread.sleep(1000);
List<WebElement> editicons1 = driver.findElements(By.xpath("//i[#class='material-icons']"));
for (int j = 1; j <= editicons1.size(); j++) {
editicons1 = driver.findElements(By.xpath("//i[#class='material-icons']"));
String porfolioName = driver.findElement(By.xpath("(//mat-table//mat-row)[" + j + "]//mat-cell[2]")).getText();
//Added to fix Stale Element Exception
WebElement editicon = driver.findElement(By.xpath("(//i[#class='material-icons'])[" + j + "]"));
//In click method attached code below this will loop for 5 times
click1(driver, editicon, porfolioName + " portfolio edit icon");
Thread.sleep(1000);
waitForElementPresent(driver, 30, buildportfolioheader);
}
}
This code for click1 method
public void click1(WebDriver driver, WebElement element, String name) throws InterruptedException {
int attempts = 0;
while(attempts < 5) {
try {
element.click();
Add_Log.info("Successfully clicked on " + name);
Reporter.log("Successfully clicked on " + name);
return;
} catch (Exception e) {
attempts++;
Thread.sleep(500);
try {
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Add_Log.info("Successfully clicked on " + name);
Reporter.log("Successfully clicked on " + name);
return;
} catch (Exception e2) {
Add_Log.info("Not able to click " + name);
Reporter.log("Not able to click " + name);
TestResultStatus.Testfail = true;
Assert.fail("Not able to click " + name);
}
}
}
}
" editicons1 = driver.findElements(By.xpath("//i[#class='material-icons']"));" This line in the loop doesn't look like it's needed, you just wanted the initial count, I don't see a reason to re load the list of elements.
The problem with this wait logic is that if the element already exists it will just sleep a second, see that the element is there and then continue, and from what I've seen, the next page could then start loading and then your script will be in a world of hurt.
Thread.sleep(1000);
waitForElementPresent(driver, 30, buildportfolioheader);
IF the element isn't already on the page, I would swap the explicit wait to come first. The reason for that is that presence of an element doesn't really mean a whole lot, the page could still be in motion, so a little bit of a sleep after the explicit wait (assuming this is one of the last elements to appear on the page) usually stabilizes flakey scripts.
waitForElementPresent(driver, 30, buildportfolioheader);
Thread.sleep(1000);
i want to check negative condition.
above boolean element is not displayed ,but i have to print true and false but it shows no such element exception
please help.
try{
boolean k= driver.findElement(By.xpath("xpath_of_element")).isDisplayed();
if(!k==true)
{
System.out.println("true12");
}
}catch (NoSuchElementException e) {
System.out.println(e);
}
There are two distinct stages of an element as follows:
Element present within the HTML DOM
Element visible i.e. displayed within the DOM Tree
As you are seeing NoSuchElementException which essentially indicates that the element is not present within the Viewport and in all possible conditions isDisplayed() method will return false. So to validate both the conditions you can use the following solution:
try{
if(driver.findElement(By.xpath("xpath_of_the_desired_element")).isDisplayed())
System.out.println("Element is present and displayed");
else
System.out.println("Element is present but not displayed");
}catch (NoSuchElementException e) {
System.out.println("Element is not present, hence not displayed as well");
}
You should use the below code which will validate if at least one or more than one elements are present or not for the given xpath, before checking for the display status of the element.
List<WebElement> targetElement = driver.findElements(By.xpath("xpath_your_expected_element"));
try {
if(targetElement>=1) {
if(targetElement.isDisplayed()) {
System.out.println("Element is present");
}
else {
System.out.println("Element is found, but hidden on the page");
}
else {
System.out.println("Element not found on the page");
}
}catch (NoSuchElementException e) {
System.out.println("Exception in finding the element:" + e.getMessage());
}
if (driver.findElements(xpath_of_element).size() != 0) return true;
return false;
I am trying to check jobstatus of a Mapreduce Job.
When I run job.iscomplete() , I get exception
"Job in state DEFINE instead of RUNNING" .
try {
if (job.isComplete()) {
printInfoLog(LOG, this.filename,
"** " + job.getTrackingURL());
break;
}
} catch (Exception e) {
LOG.warn("** " + e.getMessage());
}
But there is no such state as I checked all the fields in Jobstatus(https://hadoop.apache.org/docs/stable/api/org/apache/hadoop/mapreduce/JobStatus.html)
I kind of understand it by the feeling that the job is not yet submitted . Can anyone please suggest me how to check whether job is submitted or not as I could not find any such method in the API.
I solved it as follows,
if ( job.getJobState() == JobStatus.State.RUNNING || job.getJobState() == JobStatus.State.SUCCEEDED || job.getJobState() == JobStatus.State.KILLED || job.getJobState() == JobStatus.State.FAILED)
{
try {
if (job.isComplete()) {
printInfoLog(LOG, this.filename,
"** " + job.getTrackingURL());
break;
}
} catch (Exception e) {
LOG.warn("** " + e.getMessage());
}
}
}
Although i do agree its a crude solution
Some of the sites I deal with have heavy ajax requests. I plan to wait for Ajax request completion before clicking for asserting for element. Currently I use
try {
if (driver instanceof JavascriptExecutor) {
JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
for (int i = 0; i< timeoutInSeconds; i++)
{
Object numberOfAjaxConnections = jsDriver.executeScript("return jQuery.active");
// return should be a number
if (numberOfAjaxConnections instanceof Long) {
Long n = (Long)numberOfAjaxConnections;
System.out.println("Number of active jquery ajax calls: " + n);
if (n.longValue() == 0L) break;
}
Thread.sleep(1000);
}
}
else {
System.out.println("Web driver: " + driver + " cannot execute javascript");
}
}
catch (InterruptedException e) {
System.out.println(e);
}
But it works well for Ajax requests but not for any similar requests with variants of jQuery libraries.
Note:
document.readyState == 'complete'
It doesn't work for Ajax requests or any other similar alternatives.
Neither tests are written by me or belong to single webapp. So I can't edit the webapp.
I found the answer and it worked for few Ajax and non-ajax sites I checked. After this patch I no longer need to do implicit waits even for ajax heavy pages, LeGac pointed out the following code in one of his comments to the question.
public static void checkPendingRequests(FirefoxDriver driver) {
int timeoutInSeconds = 5;
try {
if (driver instanceof JavascriptExecutor) {
JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
for (int i = 0; i< timeoutInSeconds; i++)
{
Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
// return should be a number
if (numberOfAjaxConnections instanceof Long) {
Long n = (Long)numberOfAjaxConnections;
System.out.println("Number of active calls: " + n);
if (n.longValue() == 0L) break;
} else{
// If it's not a number, the page might have been freshly loaded indicating the monkey
// patch is replaced or we haven't yet done the patch.
monkeyPatchXMLHttpRequest(driver);
}
Thread.sleep(1000);
}
}
else {
System.out.println("Web driver: " + driver + " cannot execute javascript");
}
}
catch (InterruptedException e) {
System.out.println(e);
}
}
public static void monkeyPatchXMLHttpRequest(FirefoxDriver driver) {
try {
if (driver instanceof JavascriptExecutor) {
JavascriptExecutor jsDriver = (JavascriptExecutor)driver;
Object numberOfAjaxConnections = jsDriver.executeScript("return window.openHTTPs");
if (numberOfAjaxConnections instanceof Long) {
return;
}
String script = " (function() {" +
"var oldOpen = XMLHttpRequest.prototype.open;" +
"window.openHTTPs = 0;" +
"XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {" +
"window.openHTTPs++;" +
"this.addEventListener('readystatechange', function() {" +
"if(this.readyState == 4) {" +
"window.openHTTPs--;" +
"}" +
"}, false);" +
"oldOpen.call(this, method, url, async, user, pass);" +
"}" +
"})();";
jsDriver.executeScript(script);
}
else {
System.out.println("Web driver: " + driver + " cannot execute javascript");
}
}
catch (Exception e) {
System.out.println(e);
}
}
After every step you would need to call
checkPendingRequests(driver);
This doesn't work?
http://api.jquery.com/ajaxstop/
$(document).ajaxStop(function() {
// Do stuff here...
});
If you are using JSONP requests, you need to enable the active handling:
jQuery.ajaxPrefilter(function( options ) {
options.global = true;
});
I think that the use of active is correct, but possibly the way you have used might return false in the instanceof conditions.
Optionally, see another way to wait for jQuery ajax calls using active in Selenium tests:
browser.wait_for_condition("selenium.browserbot.getCurrentWindow().jQuery.active === 0;", '30000')
Based on our discussion over the comments, this might work for you.
With prototype.js:
var ACTIVE_REQUESTS = 0; // GLOBAL
ACTIVE_REQUESTS++
new Ajax.Request('/your/url', {
onSuccess: function(response) {
ACTIVE_REQUESTS--;
// Handle the response content...
}
}));
console.log("there are " + ACTIVE_REQUESTS + " open AJAX requests pending");
With plain script:
interValRef = 0;
interValRef = setInterval("checkState();",100)
function checkState(){
if(document.readyState == 'complete'){
clearInterval(interValRef);
myFunc();
}
}
Source: Check Pending AJAX requests or HTTP GET/POST request