Unable to execute IndexOutOfBounds exception while iterating dropdown with webtable - java

Here my code is unable to execute because of an IndexOutOfBounds error. I have to automate iteration dropdown including webtable for every selection of dropdown. I have to edit in webtable.
Can u help me for this situation?
s = new Select(ledger.SelectPayrollCategoriesLedger);
List<WebElement> led=s.getOptions();
int ledselectsize=led.size();
for(int i=0;i<ledselectsize;i++) {
WebElement select=led.get(i);
select.click();
Thread.sleep(1500);
int editactionsize=ledger.EditActionBtnLedger.size();
System.out.println("edit size is: "+editactionsize);
for(int j=0;j<editactionsize;j++) {
try {
editac=ledger.EditActionBtnLedger.get(j);
editac.click();
} catch (Exception e) {
editac = ledger.EditActionBtnLedgerStale.get(j);
editac.click();
}
}
}
It is showing the exception in:
editac = ledger.EditActionBtnLedgerStale.get(j);

Please make sure that size of
ledger.EditActionBtnLedgerStale
is same as that of size of
ledger.EditActionBtnLedger
please check whether below code will work for you,
for(int j=0;j<editactionsize;j++) {
try {
editac=ledger.EditActionBtnLedger.get(j);
editac.click();
} catch (Exception e) {
if(ledger.EditActionBtnLedgerStale.size() > j){
editac=ledger.EditActionBtnLedgerStale.get(j);
editac.click();
}
}
}
It will help to avoid IndexOutOfBounds.

Related

How to swipe till element is found in appium with using loop

I am able to swipe till element is found but then I am getting NoSuchElementException.
I have written following code.
int startX=(int) (dimension.width*0.5);
int startY=(int) (dimension.height*0.8);
int endX=(int) (dimension.width*0.2);
int endY=(int) (dimension.width*0.2);
TouchAction touch=new TouchAction(driver);
boolean b=false;
while (true) {
touch.press(PointOption.point(startX, startY)).waitAction(WaitOptions.waitOptions(Duration.ofSeconds(2)))
.moveTo(PointOption.point(endX, endY)).release().perform();
Thread.sleep(5000);
try {
b=driver.findElement(By.xpath("//android.widget.TextView[#content-desc='Sweep']")).isDisplayed();
if(b) {
b=true;
break;
}
else {
continue;
}
}catch (Exception ex) {
ex.printStackTrace();
}
}
driver.findElement(By.xpath("//android.widget.TextView[#content-desc='Sweep']")).click();
Please help. Thanks
It would be more reliable to use UIAutomator-based locator, cause you obviously have a scrollable view:
MobileElement element = (MobileElement) driver.findElement(MobileBy.AndroidUIAutomator(
"new UiScrollable(new UiSelector().scrollable(true))" +
".scrollIntoView(new UiSelector().textContains(\"Sweep\"))"));
It will not only scroll to element, but make sure it is within view port area and able for interations.

(JAVA) Selenium - Could not find / detect element in while loop

I need help in JAVA Selenium. I could not get the web driver to find the element I want in a while loop. I tried to do it without while loop, it would work. However without the while loop, I could not make the web driver to reload the page while waiting for the element to load. I would really appreciate if anyone could assist me in this.
The problem with my code is it will not exit the loop since elementProgress is forever FALSE because the web driver is not detecting the button thus not updating the elementProgress boolean value.
//check if progress button exist
boolean elementProgress;
elementProgress = driver.findElements(By.cssSelector("tr:nth-child(1) .iconLabel")).size() != 0;
//auto reload page to prevent webpage timeout
while (!elementProgress) {
TimeUnit.SECONDS.sleep(15);
driver.navigate().refresh();
boolean check_dl_queue = driver.findElements(By.cssSelector(".cell > .table .total_records")).size() != 0;
if (!check_dl_queue) {
driver.navigate().refresh();
}
Thread.sleep(1500);
driver.navigate().refresh();
elementProgress = driver.findElements(By.cssSelector("tr:nth-child(1) .iconLabel")).size() != 0;
System.out.println("P2:" + elementProgress); //to printout element status
}
I had found a solution to that, haven't got time to post it here. Below are the the solution.
//boo stat for while loop
boolean elementProgress = true;
boolean elementProgress2 = true;
//setup new web driver wait
WebDriverWait dl_wait = new WebDriverWait(driver, 15);
//auto reload page to prevent webpage timeout
while (elementProgress) {
driver.navigate().refresh();
//start button click
try {
//phase 1: wait for button 1, if exceed wait time goto exception
dl_wait.until(presenceOfElementLocated(By.cssSelector("tr:nth-child(1) .iconLabel")));
retryingFindClick(By.cssSelector("tr:nth-child(1) .iconLabel"));
//phase 2: refresh page after button successfully clicked
driver.navigate().refresh();
//phase 3: wait for button 2, if exceed wait time goto exception
while(elementProgress2) {
try {
dl_wait.until(presenceOfElementLocated(By.cssSelector("tr:nth-child(1) .icon-cancel")));
retryingFindClick(By.cssSelector("tr:nth-child(1) .icon-cancel"));
//exit elementProgress2 while loop
elementProgress2 = false;
} catch(Exception ex) {
//refresh page to counter false positive element not found exception
driver.navigate().refresh();
}
}
//exit elementProgress while loop
elementProgress = false;
} catch(Exception ex) {
//refresh page to counter false positive element not found exception
driver.navigate().refresh();
}
}
public boolean retryingFindClick(By by) {
boolean result = false;
int attempts = 0;
while(attempts < 2) {
try {
driver.findElement(by).click();
result = true;
break;
} catch(StaleElementReferenceException e) {
}
attempts++;
}
return result;
}

(StaleElementException:Selenium) How do I handle this?

This is my first time first day working on selenium and I have no hands on experience on Web Technologies in depth either.
Working around, I have been facing StaleElementException while i try to access a particular object on the DOM.
Following Method handles all the task:
private void extract(WebDriver driver) {
try {
List<WebElement> rows = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr"));
for (WebElement row : rows) {
WebElement columns = row.findElement(By.xpath("./td[1]/a"));
if (assertAndVerifyElement(By.xpath("//*[#id='gvSearchResults']/tbody/tr/td[1]/a"))) {
columns.click();
}
List<WebElement> elements = driver
.findElements(By.xpath("//*[#id='ctl00_MainContent_pnlDetailsInd']/table/tbody/tr"));
for (WebElement element : elements) {
WebElement values = element.findElement(By.xpath("./td[1]"));
System.out.print(values.getText() + " ");
WebElement values2 = element.findElement(By.xpath("./td[2]"));
System.out.println(values2.getText());
}
if(assertAndVerifyElement(By.xpath("//*[#id='ctl00_MainContent_btnBack']")))
driver.findElement(By.xpath("//*[#id='ctl00_MainContent_btnBack']")).click();
}
} catch (Exception e) {
e.printStackTrace();
}
}
The Assertion logic goes here:
public boolean assertAndVerifyElement(By element) throws InterruptedException {
boolean isPresent = false;
for (int i = 0; i < 5; i++) {
try {
if (driver.findElement(element) != null) {
isPresent = true;
break;
}
} catch (Exception e) {
// System.out.println(e.getLocalizedMessage());
Thread.sleep(1000);
}
}
Assert.assertTrue("\"" + element + "\" is not present.", isPresent);
return isPresent;
}
I have tried few solutions asking me to use wait until expected conditions, but none of them worked.
Also, It would be appreciated if you point out any bad design practices I might be using in the above sample.
I can give you the idea to overcome staleness.
Generally we will be getting the Stale Exception if the element attributes or something is changed after initiating the webelement. For example, in some cases if user tries to click on the same element on the same page but after page refresh, gets staleelement exception.
To overcome this, we can create the fresh webelement in case if the page is changed or refreshed. Below code can give you some idea.
Example:
webElement element = driver.findElement(by.xpath("//*[#id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception
To overcome this, we can store the xpath in some string and use it create a fresh webelement as we go.
String xpath = "//*[#id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.findElement(by.xpath(xpath)).click(); //This works
Another example:
for(int i = 0; i<5; i++)
{
String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
System.out.println(value);
}
Hope this helps you. Thanks
The StaleElementException occurs when the webelement in question is changed on the dom and the initial reference to that webelement is lost.
You can search for the webelement again
try this
try:
element = self.find_element_by_class('')
element.click()
except StaleElementReferenceException:
element = self.find_element_by_class('')
element.click()

How to make click on the Update Button in the shopping Cart Page - Url="http://live.guru99.com/"

Even though x-path picking the element , and i tried with java executor, but at the time of code run , it is only able to click on update button for the first element in the cart . Below is the Code :
Here once after placing 3 products in the cart i have added there text boxes into a list :
I have attached the image :
Url="http://live.guru99.com/"
List<WebElement> li2 =driver.findElements(By.xpath(".//td[#class='product-
cart-actions']/input"));
for(int j=0;j<li2.size();j++)
{
if(j==0)
{
li2.get(j).clear();
li2.get(j).sendKeys("4");
driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update']")).click();
li2 =driver.findElements(By.xpath(".//td[#class='product-cart-actions']/input"));
}
else if(j==1)
{
li2.get(j).clear();
li2.get(j).sendKeys("2");
//wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']")));
//driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']")).isDisplayed();
WebElement element = driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']"));
try {
if (element.isEnabled() && element.isDisplayed()) {
System.out.println("Clicking on element with using java script click");
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
} else {
System.out.println("Unable to click on element");
}
} catch (StaleElementReferenceException e) {
System.out.println("Element is not attached to the page document "+ e.getStackTrace());
} catch (NoSuchElementException e) {
System.out.println("Element was not found in DOM "+ e.getStackTrace());
} catch (Exception e) {
System.out.println("Unable to click on element "+ e.getStackTrace());
}
// if (element.isDisplayed()) {
// element.click();
//}
li2 =driver.findElements(By.xpath(".//td[#class='product-cart-actions']/input"));
}
else
{
li2.get(j).clear();
li2.get(j).sendKeys("3");
WebElement element1 = driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update']"));
if (element1.isDisplayed()) {
element1.click();
}
}
This is the culprit:-
WebElement element = driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']"));
So when you have multiple elements with same locators, WebDriver clicks on the first and moves ahead. So if you want to click the 2nd or 3rd element you can modify your xpath something like:-
.//td[#class='product-cart-actions']/button[#title='Update' and #type='submit'][2] -- For 2nd Element
OR
.//td[#class='product-cart-actions']/button[#title='Update' and #type='submit'][3] -- For 3rd element.
But it won't be a nice approach there may be multiple in future and you won't go around adding the index for each and every element.
Best approach would be to identify the update button with reference to the product name which is unique in your case.

handle exception while checking links using selenium webdriver

I am trying to check all the menu urls of a webpage by checking H1 element on the page. So when the loop runs and encounters an exception loop stops. I want the loop to continue even if it encounters a mismatch of css locator. please help
here's my code
List<WebElement> dropdown = Driver.findElementsByXPath("//ul[#class='nav']//ul//li//a");
int dropdown_count = dropdown.size();
System.out.println(dropdown_count);
for (int i=0; i<dropdown_count; i++)
{
String page = dropdown.get(i).getAttribute("href");
System.out.println(page);
Thread.sleep(2000);
Driver1.get(page);
try
{
Driver1.findElement(By.cssSelector("h1")).isDisplayed();
}
catch(NoSuchElementException ne)
{
System.out.println("error page: " + page);
}
{
System.out.println("page heading: " + Driver1.findElement(By.cssSelector("h1")).getText());
}
}
You have two major problems here:
Problem #1 - An unhandled NoSuchElementException.
The only statement in your code that can lead to that, is Driver1.findElement(...).
You are executing this statement inside the try clause, but also outside the try clause.
So obviously, the loop (and probably the entire method) is terminated due to that exception.
Therefore, you need to move the second Driver1.findElement(...) into the try clause.
In fact, in the try clause, you might as well search for the h1 element only once:
try
{
WebElement h1 = Driver1.findElement(By.cssSelector("h1"));
if (h1.isDisplayed())
System.out.println("page heading: " + h1.getText());
}
catch(NoSuchElementException ne)
{
System.out.println("error page: " + page);
}
Problem #2 - An unhandled StaleElementException.
This exception usually occurs when you fetch some WebElement object, and at a later point in execution - after navigating to a different page using get(...), or after switching to a different frame using switchTo().frame(...) - you attempt to use it.
This is what probably happens when you attempt to use dropdown after calling Driver1.get(page).
Here is an optional workaround for this problem:
for (int i=0; true; i++)
{
List<WebElement> dropdown = Driver.findElementsByXPath(...);
int dropdown_count = dropdown.size();
if (dropdown_count >= i)
break;
String page = dropdown.get(i).getAttribute("href");
Driver1.get(page);
...
Driver1.navigate().back();
}
And here is an alternative solution to both problems, that would make your program a lot more efficient. First, iterate all the links and build a list of URLs. Then, navigate to each URL and do whatever you wanna do on each page:
List<WebElement> links = Driver.findElementsByXPath(...);
List<String> pages = new ArrayList<String>();
for (WebElement dropdown : links)
{
String page = dropdown.getAttribute("href");
pages.add(page);
}
for (String page : pages)
{
Driver1.get(page);
try
{
WebElement h1 = Driver1.findElement(By.cssSelector("h1"));
if (h1.isDisplayed())
System.out.println("page heading: " + h1.getText());
}
catch(NoSuchElementException ne)
{
System.out.println("error page: " + page);
}
}

Categories