How to find the auto suggestion on google search with Xpath - java

With Selenium webdriver, I am trying search 'Selenium' in google search box, which provides auto suggestions of several texts. Then I am trying to click one particular text from auto suggestions list. It seems though, my Xpath is not working.
Below is the code I wrote:
package com.initial.selenium;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
public class GoogleSearch {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\Shahid\\eclipse-
workspace\\InitialSeleniumProject\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.com");
driver.findElement(By.xpath("//*[#name='q']")).sendKeys("selenium");
List < WebElement >
mylist=driver.findElements(By.xpath("//ul[#role='listbox']//li/descendant::div[#class='sbl1']/span"));
System.out.println(mylist.size());
for (int i = 0; i < mylist.size(); i++) {
System.out.println(mylist.get(i).getText());
if (mylist.get(i).getText().contains("Selenium Benefits")) {
mylist.get(i).click();
break;
}
}
}

Try this:
List<WebElement> options = new WebDriverWait(driver, 10).until(ExpectedConditions.numberOfElementsToBeMoreThan(By.xpath("//ul[#role='listbox']//li/descendant::span"), 0));
System.out.println("no. of suggestions:"+options.size());
for(int i=0;i<options.size();i++) {
System.out.println(options.get(i).getText());
}

In this case, the error you're getting (a null result) is because the ul element you're targeting doesn't contain any elements.
So, in this case, you're going to change your target. Instead of doing:
ul[#role='listbox']
Do
li[#role='presentation']
And that will result in
//li[#role='presentation']/descendant::div[#class='sbl1']/span
Which returns the span you're trying to get.

Related

Nested for loop not incrementing in the Selenium Automation script practice

There's a website with a div, containing 7 items, when one item is added to cart there is a new popup regarding continue shopping or checkout. Need to automate, Add all the 7 items one by one while clicking Continue shopping over the pop.
I tried this with nested For Loops, but looks like nested for loop variable "j" not incrementing.
Currently, for the first item, works as expected, but for the rest of the items, just the first loop's mouse hover action is performed.
Also please instruct if any better methods than my method, much appreciated.
Code:
import java.time.Duration;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class DressShop {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:/Java with Lan/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
driver.get("http://automationpractice.com/index.php");
List<WebElement> offers = driver.findElements(By.cssSelector("#homefeatured li"));
List<WebElement> addCarts = driver.findElements(By.xpath("//ul[#id='homefeatured']/li/div/div[2]/div[2]/a[1]"));
Actions a = new Actions(driver);
for (int i = 0; i < offers.size(); i++) {
WebElement offer = offers.get(i);
a.moveToElement(offer).build().perform();
for (int j = 0; j == i; j++) {
WebElement addCart = addCarts.get(j);
wait.until(ExpectedConditions.elementToBeClickable(addCart));
a.moveToElement(addCart).click().build().perform();
WebElement closePop = driver.findElement(By.xpath("//span[#title='Continue shopping']"));
wait.until(ExpectedConditions.elementToBeClickable(closePop));
a.moveToElement(closePop).click().build().perform();
}
}
}
}
You don't really need nested loop for this type of scenarios.
You can collect all the link
//ul[#id='homefeatured']//li
using this xpath, now iterate over the list and hover the mouse to each product and click on add to cart and then continue shopping.
Code:
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "D:/Java with Lan/chromedriver.exe");
WebDriver driver = new ChromeDriver();
wait = new WebDriverWait(driver, Duration.ofSeconds(30));
driver.manage().window().maximize();
driver.get("http://automationpractice.com/index.php");
Actions action = new Actions(driver);
List<WebElement> allLinks = driver.findElements(By.xpath("//ul[#id='homefeatured']//li"));
for (WebElement link : allLinks) {
action.moveToElement(wait.until(ExpectedConditions.visibilityOf(link))).pause(3).build().perform();
WebElement addToCart = link.findElement(By.xpath(".//descendant::div[#class='right-block']//descendant::a[#title='Add to cart']"));
action.moveToElement(addToCart).pause(2).click().build().perform();
//wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//descendant::div[#class='right-block']//descendant::a[#title='Add to cart']")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[#title='Continue shopping']"))).click();
}

Selenium 4 : frameToBeAvailableAndSwitchToIt doesn't seem to work

I am trying to work with a webpage in Selenium 4. The page has a few iframes and I am trying to wait for an iframe to load completely and then switch to it.
However, the code below doesn't seem to work:
driver = new ChromeDriver(options);
driver.get("https://www.stagecoachliquor.com/online-store-1/Whiskey-c20954043");
WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(30));
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("#TPASection_iw75naz9 > iframe")));
System.out.println(driver.getPageSource());
The system out just prints an empty HTML snippet below:
<html><head></head><body></body></html>
As a result, when I try to select any element after the switch, it fails. The iframe is loading alright in the chrome window which seems strange to me. I have tried implicit wait as well which did not work and had the same result.
After a few hours of debugging, I have not been able to identify the root cause. Any help is much appreciated.
Best,
R
I've reproduced the issue.
This behavior looks like a selenium bug, because, when it switches to frame, the frame has no any product elements (they are loaded a few seconds later). But then, when I was in debug and all the products loaded, and a I call driver.getPageSource(), the result is <html><head></head><body></body></html>, and when I call this again, it loads the correct page source, but still the driver cannot find any element inside the iframe.
So, I've added a custom expected condition, which switches to frame and check if some element present for workaround this.
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
import static java.time.Duration.ofSeconds;
public class ChromeIframeTest {
#Test
public void test() {
// I use https://github.com/bonigarcia/webdrivermanager lib for download chromedriver
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
WebDriver driver = new ChromeDriver(options);
driver.get("https://www.stagecoachliquor.com/online-store-1/Whiskey-c20954043");
WebDriverWait wait = new WebDriverWait(driver, ofSeconds(30));
wait.until(
frameToBeAvailableAndSwitchToItAndElementToBeAvailable(
By.cssSelector("#TPASection_iw75naz9 > iframe"),
By.cssSelector(".grid-product__shadow") // product in iframe
)
);
System.out.println(driver.getPageSource());
driver.quit();
}
// Custom expected condition
public static ExpectedCondition<Boolean> frameToBeAvailableAndSwitchToItAndElementToBeAvailable(
By frame, By frameElement) {
return new ExpectedCondition<>() {
private boolean isLoaded = false;
#Override
public Boolean apply(WebDriver driver) {
if (ExpectedConditions.frameToBeAvailableAndSwitchToIt(frame).apply(driver) != null) {
isLoaded = ExpectedConditions.presenceOfAllElementsLocatedBy(frameElement).apply(driver) != null;
}
if (!isLoaded) {
driver.switchTo().defaultContent();
}
return isLoaded;
}
#Override
public String toString() {
return String.format("element \"%s\" should present in frame \"%s\", is present: \"%b\"", frameElement.toString(), frame.toString(), isLoaded);
}
};
}
}
The root cause is your condition is always true, iframe is available after you get the HTML. You can simply add a Thread.sleep to verify it.
For now: I can't find any condition that is suited for your situation.
WebDriver driver = new ChromeDriver();
driver.get("https://www.stagecoachliquor.com/online-store-1/Whiskey-c20954043");
Thread.sleep(10000);
driver.switchTo().frame(driver.findElement(By.cssSelector("#TPASection_iw75naz9 > iframe")));
System.out.println(driver.getPageSource());
driver.quit();

How to test drag and drop with Selenium on the react-dnd-treeview library

I'm trying to test a simple drag and drop behavior on a React app.
I am using the react-dnd-treeview library and their example website to test my test case.
When I run the tests in debug, I don't get any errors and Selenium is able to get the right elements, but nothing is happening, I'm not able to create or visualize any sort of actions, even after trying so many of the different answers in this similar question, but in vain.
Here is the code I am working with:
package tests;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import java.io.File;
public class DAndDJava {
public static void main(String[] args) {
File file = new File("C:/misc/chromedriver.exe");
System.setProperty("webdriver.chrome.driver" , file.getAbsolutePath());
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://teleport.github.io/react-dnd-treeview/example/dist/index.html");
WebElement dragPoint = driver.findElement(By.xpath ("//*[#id=\"root\"]/div/div/div[3]/div[2]/div[2]/div/div/div[3]/div[2]/div/div[1]/div[3]/div[1]/div"));
WebElement dropPoint = driver.findElement(By.xpath ("//*[#id=\"root\"]/div/div/div[3]/div[2]/div[2]/div/div/div[3]/div[2]/div/div[1]/div[3]/div[1]"));
Actions builder = new Actions(driver);
Action dragAndDrop = builder.clickAndHold(dragPoint)
.moveToElement(dropPoint)
.release(dropPoint)
.build();
dragAndDrop.perform();
driver.quit();
}
}
Could you try with below code:
Action dragAndDrop = builder.clickAndHold(dragPoint)
.moveToElement(dropPoint)
.moveByOffset(0,10)
.release()
.build()
.perform() ;
Solution is described here
react-beautiful-dnd/issue
First cursor movement should be within element borders in order to change the state of the element to dragged, and only then you can drag it to the expected position:
action.clickAndHold(elementToDrag)
.moveByOffset(0, -5)
.pause(100)
.moveByOffset(0, -300)
.release()
.perform();

How to differentiate between image link and href link in selenium webdriver?

I am trying to get the name of the links of wikipedia home page in selenium webdriver . In the home page there is a table at the bottom which contains the link of wikipedia sister projects like Media-wiki, meta wiki etc . But after running the code I am getting 24 links. But in the webpage there are only 12 links. My suspicion is it is taking the links of images also.
package tcsWebmail;
import java.io.File;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class WikiPediaLinks {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("https://en.wikipedia.org/wiki/Main_Page");
System.out.println(driver.getTitle());
WebElement Block=driver.findElement(By.xpath("//*[#id='mp-sister']/table//a[not(img)]"));
List<WebElement> Links= Block.findElements((By.tagName("a")));
System.out.println("Printing the no of items in block");
int i=0;
for ( i=0;i<Links.size();i++){
System.out.println(Links.get(i).getText());
}
System.out.println("The no of items are"+Links.size());
driver.quit();
}
}
Your XPath includes images as you suspect. In order to get a that don't contain a descendant img, you can to use XPath below:
//*[#id='mp-sister']/table//a[not(img)]
or
//*[#id='mp-sister']/table//a[not(descendant::*[local-name() = 'img'])]
See code below:
List<WebElement> Links= driver.findElements(By.xpath("//*[#id='mp-sister']/table//a[not(img)]"));
In for loop put another condition to check to validate imgage (img) or link (href)
List<WebElement> Links= Block.findElements((By.tagName("a")));
System.out.println("Printing the no of items in block");
for ( int i=0;i<Links.size();i++)
{
if(Links.get(i).getAttribute("href").contains("http://")
{System.out.println(Links.get(i).getText());
}
driver.quit();
}
}

Handling Light box / Light window in selenium using webdriver

I have been trying to automate a certain flow on a website, but whenever I navigate to the site a light box/window appears because of which my element is not getting selected.
I have tried 2 approaches to close the window but none of them are working:
Have tried to close the window using the pop up closing approach.
Have tried Frames approach but that isn't working as well.
Below is my code:
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Handle_Windows_popUP {
static WebDriver driver = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\Drvier\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.get("http://www.makemytrip.com");
Set<String> id = driver.getWindowHandles();
Iterator<String> itr = id.iterator();
System.out.println(id.size());
while(itr.hasNext())
{
Object element = itr.next();
System.out.println("id: "+element);
}
// Trying to find the 'X' button if present in any of the frame but none of the frame has it
List<WebElement> ls = driver.findElements(By.tagName("iframe"));
System.out.println("Numberof frames:"+ls.size());
for(int i=0;i<ls.size();i++)
{
driver.switchTo().frame(i);
System.out.println("Frame: "+i);
System.out.println(driver.findElements(By.xpath("*[#id='htmlDoc']/body/div[13]/div/a[1]")).size());
driver.switchTo().defaultContent();
}
// The Pop-up approach
String parent_Window = itr.next();
String child_win = null;
while(itr.hasNext())
{
child_win = itr.next();
driver.switchTo().window(child_win);
driver.close();
}
driver.switchTo().window(parent_Window).getTitle();
}
}
as this works fine if u refresh the browser, i will suggest u not to use any other code. But if u want to know how to close the window without refresh browser, write the below code after launch:
//wait until the browser loaded.
//than use this code
driver.findElement(By.cssSelector("div.appfest_container.appfest_container-bg.visible-md.visible-lg >a.appfest_container-close.pull-right.clearfix")).click();
my css path is long but u may change it by using xpath.
//*[#id="htmlDoc"]/body/div[13]/div/a[1]
and hope u will accept the answer.

Categories

Resources