How to loop on the if statement if it is a WebElement? - java

I am trying to manipulate this blocks of codes:
List<WebElement> more = driver.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]/button"));
if(more.size()!=0){
driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]/button")).click();
}else {
WebElement present = driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody"));
List<WebElement> list = present.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody/tr"));
System.out.println("Total Number of TR: " + list.size());
}
What Im trying to do hopefully is that before I execute what is in the IF statement I want to loop that everytime it sees the element /html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]/button it will be click and if it is not available then ill execute this:
WebElement present = driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody"));
List<WebElement> list = present.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody/tr"));
System.out.println("Total Number of TR: " + list.size());
For further info what I am trying to do here is this.
I am on a listview for a specific module, and then at the button there is a "Click here for more records" -> its XPath is /html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]/button
I want that if i am in the listview and that button is present as mentioned above -I want to click it. And if in the listview there is no button "Click here for more records" (for example the records is composed of 5records only so there is no pagination clearly) I want to execute a blocks of code.

What I understood from your query is that you want to loop your IF condition statement multiple times until your else condition satisfies. For this, you can try following code:
(1) try{
(2) String xpathVAL="/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]/button";
(3) int i=1;
(4) while(i!=0){
(5) if(driver.findElements(By.xpath(xpathVAL)).size() != 0)
(6) {
(7) driver.findElement(By.xpath(xpathVAL).click();
(8) Thread.sleep(2000);
(9) }
(10) else{
(11) Thread.sleep(2000);
(12) WebElement present = driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody"));
(13) List<WebElement> list = present.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody/tr"));
(14) LOGGER.debug("Total Number of TR: " + list.size());
(15) i=0;
(16) }
(17) }
(18) }catch(Exception e){
(19) LOGGER.debug("Exception Caught");
(20) WebElement present = driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody"));
List<WebElement> list = present.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody/tr"));
}
I think your requirement would be to keep click a button until some window appears and the button disappears. What I suggest for this is, apply "Thread.sleep(//some 3-4 seconds//)". However, it is poor style of coding and using forceful thread is not suggested by many standards. You can put some other implicit wait there. Also, if your element is not found after certain period of time, you can apply break condition after certain time interval, else it will go to infinite loop. If you are having trouble writing the code, let me know and I will help you in that.
EDIT
Try following points to remove element not present in cache:-
Use Explicit wait(Thread.sleep) at line 8 and line 11
Change your xpath from position based to some id/name/class type. Changing it to NAME based gets more clearer picture of the element even if its position is changed.
Again re-initialize the element if exception is caught at line 20.

Related

if the next page xpath is displayed, click it and count the elements of the next page, and continue this as long as the next page exists

I have made a unique xpath for enabledNextPage. it is not found on the UI as long as the next page arrow is disabled. but on while loop it is giving me error that the element not found, which is correct that i wasn't found and it should not continue with the while loop. I used "try catch" and if the next page element is not present it still runs the while loop and gives me error on the next line which is to click it.
List<WebElement> rows = new ArrayList();
rows.addAll(driver.findElements(By.xpath("//*[#class='sortable-row']")));
while (schedulingModel.nextPageEnabled.isDisplayed())
{
nextPageEnabledXpath.click();
Thread.sleep(3000);
rows.addAll(driver.findElements(By.xpath("//*[#class='sortable-row']")));
}
I would rather have a different logic implemented by findElements, this will return me a list of next page arrow or link, if the size if >0 then it must have next page link, if not, well then no next page link.
List<WebElement> nextPageList = driver.findElements(By.xpath("xpath of next page arrow"));
if (nextPageList.size() > 0) {
System.out.println("Next page link is present");
// code to click on it, or count or whatever.
}
else {
System.out.println("Next page link is not present");
}
you can try with findElements instead using isDisplayed as it won't throw any exception if element is not present. it will be easy to share logic if you can share more details about your query like URL...
List<WebElement> rows = new ArrayList();
rows.addAll(driver.findElements(By.xpath("//*[#class='sortable-row']")));
while (driver.findElements(By.xpath("nextPageEnabled xpath value").size()>0)
{
nextPageEnabledXpath.click();
Thread.sleep(3000);
rows.addAll(driver.findElements(By.xpath("//*[#class='sortable-row']")));
}

skipping first row of a html table Java

I am still learning xpath and I am trying to skip the first row of a table because the first row has no values. I am not having success i searched through stack over flow and could not find anyone with a similar issue. My code is below:
int reqIndex = 0;
do {
List<WebElement> payDates = driver.findElements(By.xpath("//tr[starts-with(#id,'changeStartWeekGrid_row_')]/td[contains(#id,'_cell_4')/span]"));
System.out.println(payDates);
for(WebElement pd:payDates) {
LocalDate localDate = LocalDate.now();
java.util.Date d = new SimpleDateFormat("yyyy-MM-dd").parse(localDate.toString());
String str = pd.getText();
if ( str >= (d) ){ // still figuring this out
driver.findElement(By.xpath( "//tr[#id='changeStartWeekGrid_row_'" + reqIndex +"])/TBODY[#id='changeStartWeekGrid_rows_tbody']/TR[7]/TD[1]/DIV[1]/DIV[1]/DIV[1]")).click();
break;
}else{
reqIndex++;
}
}
}while(reqIndex < 7 ); /// do this 7 times
Thread.sleep(10000);
This is the part i am trouble shooting right now
List<WebElement> payDates = driver.findElements(By.xpath("//tr[starts-with(#id,'changeStartWeekGrid_row_')]/td[contains(#id,'_cell_4')/span]"));
System.out.println(payDates);
Thread.sleep(10000);
The xpath works the problem is that it is selecting the first row and it has no values row zero does so it needs to skip the first row and go to row zero.
when i run the code i get this message:
( //tr[starts-with(#id,'changeStartWeekGrid_row_')]/td[contains(#id,'_cell_4')/span])
ilter expression must evaluate to nodeset.
the row highlighted is the row i am trying to skip
cell 4 image
-----radio button html code below
<div id="changeStartWeekGrid.store.rows[5].cells[0]_widget" tabindex="0" class="revitRadioButton dijitRadio" onfocus="var registry = require('dijit/registry'); registry.byId('changeStartWeekGrid').changeActiveCell('changeStartWeekGrid_row_5_cell_0', event);" onblur="var registry = require('dijit/registry'); registry.byId('changeStartWeekGrid').blurActiveCell('changeStartWeekGrid.store.rows[5]', 'changeStartWeekGrid.store.rows[5].cells[0]');"><div class="revitRadioButtonIcon"></div></div>
---radio button picture
Try to use XPath
//table[#id='changeStartWeekGrid_rows_table']//tr[preceding-sibling::tr]
to select all tr nodes except the firts one
You can also use position() as below:
//table[#id='changeStartWeekGrid_rows_table']//tr[position()>1]
Note that in XPath indexation starts from 1 and so [position()>1] predicate means return all sibling nodes skiping the first one
You may also use
//tr[starts-with(#id,'changeStartWeekGrid_row_') and not(starts-with(#id, 'changeStartWeekGrid_row_column'))]/td[5]/span

Unable to click or select the value which is displayed in dropdown

I am trying to implement some code using Selenium Webdriver using Java.
Basically, I have a website with a text box. Once user enter the first letter, based on that a value will be displayed(using AJAX). I need to select the particular value, which i mentioned in send keys .
WebElement fromCity = driver.findElement(By.id("pickUpLocation"));
fromCity.sendKeys("A Ma Temple / 媽閣");
Thread.sleep(2000);
WebElement ajaxContainer1 = driver.findElement(By.className("txt-box ng-touched ng-dirty ng-valid"));
WebElement ajaxHolder1 = ajaxContainer1.findElement(By.tagName("ul"));
List<WebElement> ajaxValues1 = ajaxHolder1.findElements(By.tagName("li"));
for (WebElement value1 : ajaxValues1) {
if (value1.getText().equals("A Ma Temple ")) {
((WebElement)ajaxValues1).click();
break;
}
}
After you send keys.your Ajax value should be retrieved in a box related to you keyword search.You need to get the complete box.and fetch each one as you have done in for loop .get the text and compare it with your expected text and click where this condition is true.
What is that line for before thread.sleep()
I think u can try selecting through index. It should be like this
List<WebElement> ajaxValues1 = ajaxHolder1.findElements(By.tagName("li"));
Select dropdown= new Select(ajaxValues1);
dropdown.selectByIndex(0);
dropdown.selectByIndex(1);
dropdown.selectByIndex(2);
0 represents the first element in the dropdown. Based on index number of that element, feed the corresponding number in selectByIndex(0)
Let me know if this helps. Thanks

How do I loop on a button that if it is present then click if not then proceed with the code

I am new in this field and I would like to ask how can i loop if I am trying to achieve this scenario: (JAVA CODE THAT INVOLVES SELENIUM AND WEBDRIVER)
I am on a listview for example Account module. Then in the account module IF there is a pagination(button for Click for more accounts) THEN I will click it, WHEN there is no more pagination seen in the listview then I will execute a blocks of Code.
If there is no pagination in the listview then I will automatically execute a blocks of code.
Here is my code:
WebElement more = driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]"));
List<WebElement> button = more.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]/button"));
for(WebElement clicks:button){
for(int i=0; i!=100 ;i++){
if(clicks.isEnabled()){
driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[4]/button")).click();
}else{
WebElement present = driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody"));
List<WebElement> list = present.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody/tr"));
System.out.println("Total Number of TR: " + list.size());
}
WebElement present = driver.findElement(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody"));
List<WebElement> list = present.findElements(By.xpath("/html/body/div[1]/div/div[3]/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div/table/tbody/tr"));
System.out.println("Total Number of TR: " + list.size());
}
}
When I run it I have this error Element not found in the cache - perhaps the page has changed since it was looked up
Use a try-catch structure to check if the pagination element is present (and catch the error if the element is not present).
If the element is not present, then an error will be given so execution will never reach the contents of the else block. Thus, everything in the else block should be in a catch block, which will be executed if the pagination element is not present.

For loop for Checking list of items in Selenium WebDriver

I have written below code for Checking list Web Elements, but below code is running but for only 1st item its no looping to end of loop.
List <WebElement> listofItems = wd.findElements(By.xpath("//*[starts-with(#id,'result_')]//div//div[1]//div//a//img"));
for (int i=1; i<=listofItems.size(); i++)
{
listofItems.get(i).click();
wd.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
System.out.println(i);
System.out.println("pass");
wd.navigate().back();
}
#Saifur has explained nicely regarding the issue. So, I will just put the code that will see you through
List <WebElement> listofItems = wd.findElements(By.xpath("//*[starts-with(#id,'result_')]//div//div[1]//div//a//img"));
WebDriverWait wait = new WebDriverWait(wd, 20); //Wait time of 20 seconds
for (int i=1; i<=listofItems.size(); i++)
{
/*Getting the list of items again so that when the page is
navigated back to, then the list of items will be refreshed
again */
listofItems = wd.findElements(By.xpath("//*[starts-with(#id,'result_')]//div//div[1]//div//a//img"));
//Waiting for the element to be visible
//Used (i-1) because the list's item start with 0th index, like in an array
wait.until(ExpectedConditions.visibilityOf(listofItems.get(i-1)));
//Clicking on the first element
listofItems.get(i-1).click();
wd.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
System.out.print(i + " element clicked\t--");
System.out.println("pass");
wd.navigate().back();
}
So, above I have just tweaked your code a bit and have the relevant comments where changes are made and why. Hope this works out for you. :)
The possible issue with this is the DOM refresh. You cannot find a list and click through the elements back and forth and reference to the same list since the DOM has refreshed after first click. The best solution of that problem is to find the element on the fly. Plus, implicit wait is firm for that driver instance once you set that. So, you do not have to set the wait for each element look up. Instead set it where you instantiate the driver.(possibly). However, I think the explicit wait is a best fit here.
By byXpath = By.xpath("//*[starts-with(#id,'result_')]//div//div[1]//div//a//img");
List <WebElement> listofItems = wd.findElements(byXpath);
for (int i=1; i<=listofItems.size(); i++)
{
//I would suggest you to see if you can improve the selector though
By by= By.xpath("//*[starts-with(#id,'result_')]//div//div[1]//div//a//img[" + i + "]");
WebElement myDynamicElement = (new wd(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(by));
System.out.println(i);
myDynamicElement.click();
wd.navigate().back();
}

Categories