Unable to switch between two browser windows using Selenium WebDriver - java

I am new to WebDriver, i am facing an issue on browser window switching.
I googled for my query resolution and the answer i found best is still not working for me.
Here is my code :
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.BeforeSuite;
public class FrameWorkBase {
public static WebDriver driver;
public static WebDriverWait wait;
public static String firstWindow,secondWindow;
#BeforeSuite
public void startDriver() throws Exception{
driver= new FirefoxDriver(); // this firefox window is to open survey
driver.manage().window().maximize();
wait=new WebDriverWait(driver, 40);
driver.get("http://www.cricinfo.com");
firstWindow=driver.getWindowHandle();
driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://translate.google.co.in/");
secondWindow=driver.getWindowHandle();
System.out.println("First window handle :" + firstWindow);
System.out.println("\n Second window handle :" + secondWindow);
driver.switchTo().window(firstWindow);
System.out.println("hello");
}
}
I am getting an error on execution as Unable to find window 'xyz' where 'xyz' is the name of first window.
Even i am printing the window name and it is displaying the same window for which it is displaying error.
Please suggest me what i am doing wrong here.
Thanks

This is happening because you have reinitialized the driver instance.
driver=new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://translate.google.co.in/");
This line has reinitialised your driver instance so what ever u try to do you won't find the window handle. If you are trying to work on both websites simultaneously, try to create another object of driver like WebDriver driver2 = new FirefoxDriver();

#Vivek has aptly answered your question. But, if you still want to open a link in a new window, you can try the below code for that:
Actions act = new Actions();
WebElement link = driver.findElement(By.xpath("//xpath of the link"));
//Opening the link in new window (works in FF and Chrome)
act.contextClick(link).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ENTER).build().perform();
And you can switch in between them accordingly, with the use of handles. Furthermore, this link will help you handle two windows simultaneously.

Related

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 effectively change the browser name of the WebDriver object?

I intend to perform some tests by using selenium with multiple web browsers. To distinguish between the different web drivers, I use the following line of code:
((RemoteWebDriver) driver).getCapabilities().getBrowserName();
This will return a String indicating the web browser that is used by the driver object. However, for my Opera WebDriver object this will give me the String 'chrome'. I have tried changing this by explicitly setting the browser name to 'opera' using DesiredCapabilities:
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("opera");
WebDriver driver = new OperaDriver(capabilities);
Unfortunately, this does not fix my problem. How do I effectively change the web browser name?
Your basic requirement is to identify browser initialization if I'm right, which can be done by getting user-agent from your browser using JavascriptExecutor as following:
String userAgent = (String) ((JavascriptExecutor) driver).executeScript("return navigator.userAgent;");
//following is for identifying opera browser initialization
if(userAgent.contains("OPR/"){
System.out.println("Browser currently in use is Opera");
}
Similarly you can identify other browser initilisation by referring this link
Unfortunately , you would not be able to change the BrowserName.
What instead you can try is to create function for specifically handling multiple browsers: -
package multiBrowser;
import org.testng.annotations.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.opera.OperaDriver;
import org.testng.annotations.Parameters;
public class MultiBrowserClass {
WebDriver driver;
#Test
#Parameters("browser")
public void multiBrowsers(String browserName) throws InterruptedException{
if(browserName.equalsIgnoreCase("firefox")){
System.setProperty("webdriver.firefox.marionette","D:\\My Work\\Setup\\JAR\\geckodriver.exe");
ProfilesIni profile = new ProfilesIni();
FirefoxProfile myprofile = profile.getProfile("default");
driver = new FirefoxDriver(myprofile);
}
if(browserName.equalsIgnoreCase("chrome")){
System.setProperty("webdriver.chrome.driver", "D:\\My Work\\Setup\\JAR\\driver\\chromedriver.exe");
driver = new ChromeDriver();
}
else if(browserName.equalsIgnoreCase("IE")){
System.setProperty("webdriver.ie.driver", "D:\\My Work\\Setup\\JAR\\driver\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
}
else if(browserName.equalsIgnoreCase("opera")){
System.setProperty("webdriver.opera.driver", "D:\\My Work\\Setup\\JAR\\driver\\operadriver.exe");
driver = new OperaDriver();
}
driver.manage().window().maximize();
driver.navigate().to("https://");
System.out.println(driver.getTitle());
driver.findElement(By.xpath("//div[#id='navbar-main']/ul/li[5]/a")).click();
driver.findElement(By.xpath("//div[#id='navbar-main']/ul/li[5]/ul/li/a")).click();
Thread.sleep(3000);
driver.findElement(By.name("email")).clear();
driver.findElement(By.name("email")).sendKeys("abc#mm.kk");
driver.findElement(By.name("password")).clear();
driver.findElement(By.name("password")).sendKeys("1qaz2wsx");
Thread.sleep(3000);
driver.findElement(By.xpath("//form[#id='loginform']/div[8]/button")).click();
Thread.sleep(5000);
if(driver.getPageSource().contains("Welcome abc#mm.kk")){
System.out.println("User Successfully logged in");
}else{
System.out.println("Username or password you entered is incorrect");
}
driver.quit();
}
}
=======

Selenium: Don't understand how to write correct xpath for IMDB top movies

I am trying to click on the IMDB Top Rated Movies which is under "Movies, TV & Showtimes" but I don't understand how to write the correct and precise xpath for it. I am not able to click on the Top Rated Movies part.
Below is the code:
driver.get("http://www.imdb.com");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.id("navTitleMenu"))).build().perform();
driver.findElement(By.xpath("//li[#id='navTitleMenu']/div/div[2]/ul[1]/li[6]/a")).click();
Help me out. Thanks already.
That's what worked in my case:
driver.get("http://www.imdb.com");
new WebDriverWait(driver, 5000)
.until(ExpectedConditions.visibilityOfElementLocated(By.id("navTitleMenu")));
new Actions(driver)
.clickAndHold(driver.findElement(By.id("navTitleMenu")))
.moveToElement(driver.findElement(By.linkText("Top Rated Movies")))
.click()
.build().perform();
The problem is that when you move to navTitleMenu - you should continue performing your actions, as focus will be lost from dropdown (so it will be closed)
do you create the xpath yourself i recommend using chrome to create the xpath maybe the problem is that your xpath is incorrect try this:
//*[#id="navMenu1"]/div[2]/ul[1]/li[6]/a
or if not maybe you should wait a little to get the page load done try
try {
// thread to sleep for 5 seconds
Thread.sleep(5000);
} catch (Exception e) {
System.out.println(e);
}
then
driver
.findElement(By.xpath("//*#id="navMenu1"]/div[2]/ul[1]/li[6]/a")).click();
First of all,
Forget about the implicit wait, It is not needed since IMDB is a stable site
Add explicit wait after you have performed the mousehover. It will definitely work for you.
Try the exact code mentioned below, Working fine with my browser.
Please change the gecko driver path according to location in your directory
package com.imdb.top;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Imdb
{
public static void main(String... args)
{
System.setProperty("webdriver.gecko.driver",
"C:\\Users\\thinksysuser\\Downloads\
\geckodriver-v0.18.0-win64\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("http://www.imdb.com");
Actions action = new Actions(driver);
action.moveToElement(driver.findElement(By.id("navTitleMenu")))
.build().perform();
WebDriverWait wait = new WebDriverWait(driver, 60, 50);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*
[#id='navMenu1']/div[2]/ul[1]/li[6]/a"))).click();
driver.findElement(By.xpath(".//*
[#id='navMenu1']/div[2]/ul[1]/li[6]/a")).click();
}
}

Unable to open a new tab in the browser. It loads the 2nd url in the same tab

I am trying to open a new tab in the browser.
But however it open the second URL in the same tab.
Code:
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class ChromeFlock {
public static void main(String[] args) throws Exception { WebDriver driver; System.setProperty("webdriver.chrome.driver", "C:\\Automation\\chromedriver_win32\\chromedriver.exe"); driver = new ChromeDriver();
driver.manage().window().maximize();
String baseUrl = "http://www.google.co.uk/";
driver.get(baseUrl);
Thread.sleep(3000);
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,"t");
driver.findElement(By.tagName("body")).sendKeys(selectLinkOpeninNewTab);
driver.get("http://www.facebook.com"); }
}
use JavascriptExecutor as following:
((JavascriptExecutor) driver).executeScript("window.open('http://www.facebook.com');");
Perhaps you are not switching to the new tab, which is resulting in launching the 2nd link on the parent tab only.
You can use Robot class to open a new tab by simulating pressing of keyboard's Ctrl+t keys. Then you need to switch to the new tab using driver.switchTo() command.
For code snippet and details check this Open a new tab in Selenium
You could use keyboard emulation:
new Actions(driver).sendKeys(Keys.Control + 'w').build.perform(); // or + 't'
driver.get("http://www.facebook.com");
or using JavaScriptExecutor:
((JavascriptExecutor) driver).ExecuteScript("window.open('http://www.facebook.com','_blank');");

counting radio buttons not working with multiple tag names

File file = new File("D:\Selenium 2.48\IEDriverServer.exe");
System.setProperty("webdriver.ie.driver", file.getAbsolutePath());
WebDriver driver=new InternetExplorerDriver();
driver.get("http://www.yatra.com/");
driver.manage().window().maximize();
List<WebElement> radio = driver.findElements(By.tagName("a"));
System.out.println(radio.size());
here is the new code, and i am able to lacate xpath now .thanks for it.But issue is with a white page which comes and result is zero .The original page takes some time.
please find the link
i wanted to count the number of radio buttons.
but i was not able to . I tried finding it by tag name and the result is zero.
The HTML is bit complicated to my understanding as in radio buttons , there is no input .hence i cannot find by input[#type=] etc
Please help me in this regard .
You should locate the right indicator for these ratios
Recommend you to use this xpath
//a[#data-flighttrip]
Here's my script
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.remote.DesiredCapabilities;
public class TestSelenium {
static WebDriver driver;
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver", "res/chromedriver.exe");
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
driver = new ChromeDriver(capabilities);
driver.get("http://www.yatra.com/");
List<WebElement> radio = driver.findElements(By.xpath("//a[#data-flighttrip]"));
System.out.println(radio.size());
driver.quit();
}
}
Here's console output
Starting ChromeDriver (v2.9.248315) on port 14427
3
Tried with IEDriver
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.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
public class TestSelenium {
static WebDriver driver;
public static void main(String[] args) throws Exception {
File file = new File("D:\\IEDriverServer.exe");
System.setProperty("webdriver.ie.driver", file.getAbsolutePath());
DesiredCapabilities cap = DesiredCapabilities.internetExplorer();
cap.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
WebDriver driver=new InternetExplorerDriver(cap);
driver.get("http://www.yatra.com/");
driver.manage().window().maximize();
List<WebElement> radio = driver.findElements(By.xpath("//a[#data-flighttrip]"));
System.out.println(radio.size());
driver.quit();
}
}
Result
Started InternetExplorerDriver server (64-bit)
2.52.0.0
Listening on port 6267
Only local connections are allowed
3
I think you need to wait for things to settle down and the page to load via WebDriverWait:
WebDriverWait wait = new WebDriverWait(webDriver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.trip-type")));
Here, we are waiting for the trip type container to become visible, which, I assume, is a good indication that at least the relevant part of the page is loaded.
Then, you can count the links:
List<WebElement> radio = driver.findElements(By.tagName("a"));
System.out.println(radio.size());
Note that the radiobuttons are not actually HTML radio input elements in your case - these are just links with preceding "radiobutton"-like icons:
<a class="type-active" href="javascript:void(0);" data-flighttrip="O">
<i class="sprite-booking-engine ico-be-radio"> </i>
One Way
</a>
So, if you want to count these types of links anywhere on the page, you may check for the presence of the i child element with a ico-be-radio class with the following XPath expression:
List<WebElement> radio = driver.findElements(By.xpath("//a[contains(i/#class, 'ico-be-radio')]"));
System.out.println(radio.size());
But, if you want to just check how many "trip type" links are there, just get all of the a elements inside the "trip type" container:
WebDriverWait wait = new WebDriverWait(webDriver, 10);
WebElement tripType = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.trip-type")));
List<WebElement> radio = tripType.findElements(By.tagName("a"));
System.out.println(radio.size());

Categories

Resources