How do I search for something on Google , click on the link , then return to the search and click the following link ( without repeating the already links clicked ) and after the links that the page finished , navigate to the page 2 and repeat the same steps in succession?
So far I could go to the first link, go to the page and return to the list of links searched only.
package Search;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class GoogleSearch {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.setProperty("webdriver.ie.driver", "C:/Users/paulo.roberto/Documents/eclipse/Selenium/IEDriverServer.exe");
DesiredCapabilities caps = DesiredCapabilities.internetExplorer();
caps.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
WebDriver driver = new InternetExplorerDriver(caps);
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
driver.get("https://www.google.com.br");
driver.findElement(By.name("q")).sendKeys("test");
driver.findElement(By.name("btnG")).click();
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("resultStats")));
// find the number of pages
int size = driver.findElements(By.cssSelector("[valign='top'] > td")).size();
for(int j = 1 ; j < size ; j++) {
if (j > 1) {// we don't need to navigate to the first page
driver.findElement(By.cssSelector("[aria-label='Page " + j + "']")).click(); // navigate to page number j
}
String pagesearch = driver.getCurrentUrl();
List<WebElement> findElements = driver.findElements(By.xpath("//*[#id='rso']//h3/a"));
System.out.println(findElements.size());
for(int i=0;i<findElements.size();i++){
findElements= driver.findElements(By.xpath("//*[#id='rso']//h3/a"));
findElements.get(i).click();
driver.navigate().to(pagesearch);
// or driver.navigate().back();
}
}
}
}
message on the console:
Started InternetExplorerDriver server (32-bit)
2.48.0.0
Listening on port 37101
10
10
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 4, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at Search.GoogleSearch.main(GoogleSearch.java:48)
You can use nested loops. One to navigate between results pages and one to click on results
// find the number of pages
int size = driver.findElements(By.cssSelector("[valign='top'] > td")).size();
for(int j = 1 ; j < size ; j++) {
if (j > 1) {// we don't need to navigate to the first page
driver.findElement(By.cssSelector("[aria-label='Page " + j + "']")).click(); // navigate to page number j
}
String pagesearch = driver.getCurrentUrl();
List<WebElement> findElements = driver.findElements(By.xpath("//*[#id='rso']//h3/a"));
System.out.println(findElements.size());
for(int i=0;i<findElements.size();i++){
findElements= driver.findElements(By.xpath("//*[#id='rso']//h3/a"));
findElements.get(i).click();
driver.navigate().to(pagesearch);
// or driver.navigate().back();
}
}
Related
I have code that reads the rows from a web table that consists of multiple pages and prints them. On the last page there are only 2 rows, but the code counts 10 instead (10 is the max rows on a page). When I run it in debug mode and step through, it correctly counts 2 rows. I have no idea why this is happening and would like some help on this.
Here is the web table : https://demo.opencart.com/admin/index.php?route=sale/order&user_token=cf5c87b778476447f8451877fae6af2f
Here is where the rows are counted in my code:
//get number of rows
int rows = driver.findElements(By.xpath("//table[#class='table table-bordered table-hover']//tbody/tr")).size();
System.out.println("No of Rows: "+rows);
Here is all my code:
package mypackage;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import io.github.bonigarcia.wdm.WebDriverManager;
public class DynamicWebTable {
static WebDriver driver;
public static void main(String[] args) throws InterruptedException {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.get("https://demo.opencart.com/admin/");
driver.manage().window().maximize();
WebElement username = driver.findElement(By.id("input-username"));
username.clear();
username.sendKeys("demo");
WebElement password = driver.findElement(By.id("input-password"));
password.clear();
password.sendKeys("demo");
driver.findElement(By.xpath("//button[normalize-space()='Login']")).click();
//Close popup
if(driver.findElement(By.xpath("//div[#class='modal-content']")).isDisplayed()) {
driver.findElement(By.xpath("//button[#class='btn-close']")).click();
}
driver.findElement(By.xpath("//a[normalize-space()='Sales']")).click();
driver.findElement(By.xpath("//a[normalize-space()='Orders']")).click();
//get total no of pages
String textWithTotalPages = driver.findElement(By.xpath("//div[#class='col-sm-6 text-end']")).getText();
int pages = getNumberOfPages(textWithTotalPages);
System.out.println(pages);
//go through each page
for(int p = 1; p <= pages; p++) {
System.out.println("Page no: "+p);
**//get number of rows
int rows = driver.findElements(By.xpath("//table[#class='table table-bordered table-hover']//tbody/tr")).size();
System.out.println("No of Rows: "+rows);**
//read rows from page
for(int r=1; r<=rows; r++) {
String orderId = retryingFindClick(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr["+r+"]//td[2]"));
String store = retryingFindClick(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr["+r+"]//td[3]"));
String customer = retryingFindClick(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr["+r+"]//td[4]"));
String status = retryingFindClick(By.xpath("//table[#class='table table-bordered table-hover']//tbody//tr[\"+r+\"]//td[5]"));
System.out.println(orderId+ " "+store+" "+customer+" "+status);
}
//stop when finished with the last page
if(p == pages) {
break;
}
//click next page
String nextPage = Integer.toString(p + 1);
// try {
// driver.findElement(By.xpath("//ul[#class='pagination']//li//a[text()='"+nextPage+"']")).click();
// }catch(ElementClickInterceptedException e) {}
JavascriptExecutor js= (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0,document.body.scrollHeight)");
Thread.sleep(2000);
driver.findElement(By.xpath("//ul[#class='pagination']//li//a[text()='"+nextPage+"']")).click();
//waitAndLocate(By.xpath("//ul[#class='pagination']//li//a[text()='"+nextPage+"']")).click();
System.out.println("Clicked page: "+nextPage);
}
driver.quit();
}
//extract number of pages from String
public static int getNumberOfPages(String text){
return Integer.valueOf(text.substring(text.indexOf("(")+1, text.indexOf("Pages")-1));
}
public static String retryingFindClick(By by) {
//boolean result = false;
String s = null;
int attempts = 0;
while(attempts < 2) {
try {
s = driver.findElement(by).getText();
//result = true;
break;
} catch(StaleElementReferenceException e) {
}
attempts++;
}
return s;
}
public static WebElement waitAndLocate(By by) {
return new WebDriverWait(driver, Duration.ofSeconds(2))
.until(driver -> driver.findElement(by));
}
}
I rewrote your code to simplify things.
I think your main issue was that the script was not waiting properly so when it printed the number of rows for the last page, it was actually printing them for the previous page. The way to prevent this is to use ExpectedConditions.stalenessOf(). This takes an existing element on the page and then waits for it to go stale (no longer on the page). I added this at the bottom of every loop to make sure when the > button is clicked to go to the next page, the script pauses until the next page is loaded.
I added waits, where needed
Instead of getting a count of pages, just loop until there's no > (Next) button
Instead of getting a count of rows, just loop through all rows
I changed the URL to navigate straight to the sale/order page to save time
I removed the implicit wait since you shouldn't mix implicit and explicit waits according to the docs
Removed all support methods since they were no longer needed
With all these changes, the code is much shorter, simpler, and works successfully.
public static void main(String[] args) throws InterruptedException {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
String url = "https://demo.opencart.com/admin/index.php?route=sale/order";
driver.get(url);
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("input-username"))).sendKeys("demo");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("input-password"))).sendKeys("demo");
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("i.fa-key"))).click();
// loop until last page is reached
while (true) {
for (WebElement row : wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("table tr")))) {
String orderId = row.findElement(By.xpath("./td[2]")).getText();
String store = row.findElement(By.xpath("./td[3]")).getText();
String customer = row.findElement(By.xpath("./td[4]")).getText();
String status = row.findElement(By.xpath("./td[5]")).getText();
System.out.println(orderId + " " + store + " " + customer + " " + status);
}
List<WebElement> nextButton = driver.findElements(By.xpath("//a[text()='>']"));
if (nextButton.isEmpty()) {
break;
} else {
nextButton.get(0).click();
wait.until(ExpectedConditions.stalenessOf(nextButton.get(0)));
}
}
}
//Main Class TestNg class
public class XCartCheckout extends TestBase {
public static WebDriver driver;
StoreHomePage ohome;
// ArrayList<String> productname = new ArrayList<String>();
#Test(dataProvider = "DataFromExcel", priority = 1)
// public void Ad`enter code here`dToCartTest(productname) throws InterruptedException {
public void AddToCartTest(String[][] productname) throws InterruptedException {
int b = 0;
ArrayList < String > arrlist = new ArrayList < String > ();
boolean t = true;
System.out.println("length =" + productname.length);
System.out.println("arraylist values are");
for (int i = 0; i < productname.length; i++) {
for (int j = 0; j < productname[i].length; j++) {
// System.out.println("productname=" + productname[i][j]);
arrlist.add(productname[i][j]);
// System.out.println("b=" + b+ "productname="+productname[i][j]);
// b++;
}
}
for (int k = 0; k < arrlist.size(); k++) {
System.out.println(arrlist.get(k));
}
driver.get("");
driver.manage().window().maximize();
ohome = new StoreHomePage(driver);
ohome.movingBanners();
boolean sortstatus = ohome.selectSortOrder();
b = Boolean.compare(sortstatus, t);
if (sortstatus == t) {
for (int l = 0; l < arrlist.size(); l++) {
String cartmsg = ohome.addToCart(arrlist.get(l));
Assert.assertEquals(cartmsg, "You have just added");
System.out.println("Product added to cart");
}
}
}
//Add to Cart Method in my subclass:
public String addToCart(String prodnamefrmexcel) {
String successmsg = null;
i++;
try {
WebElement prodname = driver.findElement(By.xpath("//h5/a[contains(text(),'" + prodnamefrmexcel + "')]"));
WebElement addtocartbtn = driver.findElement(By.xpath("//h5/a[contains(text(),'" + prodnamefrmexcel +
" ')]//parent::h5//following-sibling::div//span[text()='Add to cart']"));
Actions action = new Actions(driver);
Action action1 = action.moveToElement(prodname).moveToElement(addtocartbtn).build();
action1.perform();
addtocartbtn.click();
Thread.sleep(4000);
successmsg = driver.findElement(By.xpath("(//span[text()='You have just added'])['" + i + "']"))
.getAttribute("innerText");
System.out.println(successmsg);
Thread.sleep(3000);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//span[text()='You have just added'])['" + i + "']//following-sibling::button"))).click();
} catch (Exception e) {
e.printStackTrace();
}
return successmsg;
}
}
I am trying to add 2 items to cart.While adding each item,an overlay with close button is displayed.I am trying to click Close button after adding each item.After adding 1st item,I am able to click Close button.But after adding 2nd item,unable to click close button.
The following is the error received:
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for element to be clickable: By.xpath: (//span[text()='You have just added'])['2']//following-sibling::button (tried for 30 second(s) with 500 milliseconds interval)
Screenshots containing the webpage and html elements are attached.
web-page-1
web-page-2
Try to click with JsExecutor:
element = driver.findElement(By.xpath("your_xpath"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);
Is there any way to solve sorting web element ? I am getting difficulties while sorting using drag and drop function. My drag and drop is not working, i think my logic is good, but while running code nothing happening...
public void sortable() { // loop for drag and drop is not working...
try {
driver.get("http://jqueryui.com/");
myLibrary.clickButton(By.partialLinkText("Sortable"));
WebElement iframe = driver.findElement(By.xpath("//*[#id='content']/iframe"));
driver.switchTo().frame(iframe);
String temp = "";
Thread.sleep(10 * 1000); //manual work to disorder sortable list prior to start for loop.
Actions action = new Actions(driver);
int i = 1, j = 1;
for (i = 1; i < 8; i = i + 1) {
WebElement sourceText = driver.findElement(By.cssSelector("#sortable > li:nth-child(" + i + ")"));
WebElement dragElement = driver
.findElement(By.cssSelector("#sortable > li:nth-child(" + i + ") > span"));
while (true) {
temp = "Item" + " " + j;
if (temp == sourceText.getText()) {
WebElement targetElement = driver
.findElement(By.cssSelector("#sortable > li:nth-child(" + j + ")"));
action.moveToElement(dragElement).dragAndDrop(dragElement, targetElement).build().perform();
Thread.sleep(1 * 1000);
break;
} else {
if (j == 8) {
break;
} else {
j++;
}
}
}
}
Thread.sleep(5 * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
Building upon what #JeffC posted as an answer, here's another variant of the same that uses some of the built in capabilities of Java.
We basically use the List.sort() and a Comparator to get this done.
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class SorterSample {
private RemoteWebDriver driver;
#BeforeClass
public void setup() {
driver = new ChromeDriver();
}
#AfterClass
public void cleanup() {
if (driver != null) {
driver.quit();
}
}
#Test
public void testMethod() {
String url = "http://jqueryui.com/sortable/";
driver.get(url);
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe.demo-frame")));
List<WebElement> items = driver.findElements(By.cssSelector("#sortable > li"));
items.sort(
(o1, o2) -> {
int compareValue = o1.getText().compareTo(o2.getText());
if (compareValue < 0) {
new Actions(driver).dragAndDrop(o1, o2).perform();
}
return compareValue;
});
}
}
This was a fun little exercise...
Rather than trying to invent your own sorting code, you should use an established sorting algorithm. I chose bubble sort but you can pick any one you want. If you are just sorting a few items, this should work just fine. It runs in just a few seconds.
The main code
String url = "http://jqueryui.com/sortable/";
driver.get(url);
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe.demo-frame")));
List<WebElement> items = driver.findElements(By.cssSelector("#sortable > li"));
bubbleSort(items);
The bubble sort method
static void bubbleSort(List<WebElement> items)
{
int n = items.size();
boolean swapped;
for (int i = 0; i < n - 1; i++)
{
swapped = false;
for (int j = 0; j < n - i - 1; j++)
{
int compare = items.get(j).getText().compareTo(items.get(j + 1).getText());
if (compare < 0)
{
swap(items.get(j + 1), items.get(j));
swapped = true;
}
}
// break if no elements were swapped
if (swapped == false)
{
break;
}
}
}
and finally the support method to swap items
public static void swap(WebElement source, WebElement target)
{
new Actions(driver).dragAndDrop(source, target).perform();
}
I just ran this code a few times and it's working just fine. It sorts the items in reverse order (so you don't have to mix them up manually). This is not the most efficient way to do this but I wanted to be able to watch the bubble sort work so you see each swap. If you want this to go faster, you can pull the text from the items, sort that list and then line up the elements with their sorted text so you only have to do n swaps.
This is my code when I run it goes to the 2nd page and stop it not looping all pages and search the required element. It should look for particular text in a page and click on the link of it.
if (driver.getTitle().contains("Article properties")) {
WebElement assigninitial = driver.findElement(By.partialLinkText("Assign reviewer for initial review"));
assigninitial.click();
} else {
//pagination code
//driver.findElement(By.xpath("/html/body/app/main/app-mytasks/div[1]/section/div/pagination/ul/li[3]/a")).click();
#SuppressWarnings("unchecked")
ArrayList<WebElement> pagination = (ArrayList<WebElement>) driver.findElements(By.xpath("/html/body/app/main/app-mytasks/div[1]/section/div/pagination/ul/li[5]/a"));
// checkif pagination link exists
if ((pagination).size() > 0) {
//System.out.print("pagination exists");
// click on pagination link
for (int i = 0; i < pagination.size(); i++) {
pagination.get(i).click();
if (driver.getPageSource().contains("Article properties")) {
WebElement assigninitial = driver.findElement(By.partialLinkText("Assign reviewer for initial review"));
assigninitial.click();
}
}
} else {
System.out.print("pagination not exists");
}
}
public void pagination_check() throws InterruptedException {
loader_wait(5); //wait until 'loader' loading
List<WebElement> pagination = driver.findElements(By.xpath("//page-navigation/div/div/span/a"));
Thread.sleep(5000);
if (pagination.size() > 0) {
System.out.println("pagination exists and size=>"+pagination.size());
int page_no=pagination.size();
for (int i = 2; i <= pagination.size(); i++) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView();", driver.findElement(By.xpath("//page-navigation/div/div/span"))); //for
scroller move
js.executeScript("arguments[0].click();", driver.findElement(By.xpath("//page-navigation/div/div/span/a["+i+"]")));
loader_wait(5); //wait
}
} else {
System.out.println("no pagination");
}
}
package com.selenium;
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.io.IOException;
public class Exxcel {
public static void main(String[] args) throws Exception,NullPointerException{
//WebDriver driver= new FirefoxDriver();
//WebElement wb;
String Value;
try{
FileInputStream file= new FileInputStream("C:\\Documents and Settings\\OMEGA\\Desktop\\Test Planning And Documents\\Automation Data.xlsx");
Workbook data=WorkbookFactory.create(file);
Sheet sheet=data.getSheet("Sheet1");
for(int i=1;i<=sheet.getLastRowNum();i++){
Row row = sheet.getRow(i);
if(row != null){
// Putting condition to check row is null or not
for (int j = 1; j < row.getLastCellNum();) {
if (row.getCell(j) != null) {
// Putting condition to check row cell is null or not
String value=row.getCell(j).getStringCellValue();
Value=value;
//String value1=row.getCell(j+1).getStringCellValue();
String[] array= new String[2];
array[0]=Value;
//array[1]=value1;
if( array[0] != null ) {
// Putting condition to check array[] is null or not
System.out.println(array[0]);
//System.out.println(array[1]);
}
}
}
}
}
}catch(NullPointerException n){
n.printStackTrace();
//System.out.println("Null");
}// catch
}//main
}//class
This is the code which i am trying to run but as soon as i click on run buton the entier eclipse stops responding. Don't know why its happening?
It is possible that your loop never ends:
for (int j = 1; j < row.getLastCellNum();) {
I don't see j being incremented anywhere in your code.
An infinite loop on the main GUI thread would have the side-effect to freeze the IDE.
As the OP Shantanu commented, adding an increment j++ was enough to resolve the situation:
for(int j=0; j<=row.getLastRowNumber(); j++) {
...
}
You must put an increment or decrement operater on the second for loop. You have not put any condition in the second loop which is why your program is going in an infinite loop and eclipse becomes slow in performance.
Change your code with:
for(int j=0; j<=row.getLastRowNumber(); j++)
{
//Your Code
}