How to get Handle of the Focused Tab in Selenium? - java

I am using Selenium for Scrapping purpose for Job Website scrapping. I am ctrl+clicking on jobs to go to second page and scrape details, I somehow wish to keep track of where I clicked to which tab opened up (using a map).
But as soon as I ctrl+click an element, new tab opens and focus changes to that.
How do I get handle of the current focused tab in Selenium
I tried
webDriver.getWindowHandle()
But it returns me the handle for main tab that I ctrl+clicked an element from.
My Full Code
private void openAndMapJobTabs(WebElement jobList) {
List<WebElement> jobRowsSelector = jobList.findElements(By.tagName("article"));
for (WebElement jobRow : jobRowsSelector) {
try {
ctrlClickElement(jobRow);
Thread.sleep(4000);
//the next line is expected by me to give handle of current focused tab
System.out.println(webDriver.getWindowHandle()); // but this gives me handle of main tab
webElementToTabMapper.put(jobRow, webDriver.getWindowHandle());
webDriver.switchTo().window(websiteTabHandle);
} catch (Exception e) {
logger.info("Could Not Click Open Job Tab: "+e.getMessage());
}
}
}
UPDATE
Actually for me, I need to map elements to the tab they open, so order of tabs are important for me, so I purposely need the handle of current focused tab so I can map it with the element which opened that. But by iterating through all handels, I might mess up the order if any one of the webElement fails to open a new tab or if click is disabled on that.
Any help world be highly appreciated.
Also if there are faster and better tools for scrapping, please recommend.

You have to get the handles of those two tabs or windows, then you have to iterate and switch to the newly opened tab. Try the below code:
// This line will get the handles of the all the tabs or windows and store in a var with type 'Set'
Set<String> windowHandles = driver.getWindowHandles();
// Iterating through the Set - i.e., window handles and switch to the other tab
for (String handle : windowHandles) {
// System.out.println(handle);
driver.switchTo().window(handle);
System.out.println("Title: " + driver.getTitle());
}
If you have more than two tabs or windows, then put the above code the in a method, pass the window title which you want to switch as a parameter, and compare the title with each window title, once you switch to the expected window, break.

Related

Selenium unable to detect UI element in another tab

I am trying to automate a scenario where when I click on a link another tab opens with details.
Question 1 : Do I have to specifically set my focus to the 2nd tab or selenium automatically finds the element in the 2nd tab?
I am using the below code to set the focus to the 2nd tab :
String currentWindow = driver.getWindowHandle();
driver.switchTo().window(currentWindow);
Problem : I am getting an error that selenium is unable to find the specified element.
Could you guys suggest me what am I doing wrong, and the best way to switch to 2nd tab.
Actually, you are setting the focus on the first tab, not the second one. You need to do something like this
String currentWindow = driver.getWindowHandle();
// open the new tab here
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(currentWindow)) {
driver.switchTo().window(handle);
}
}
And the answer to your question is yes, you have to tell the driver to set its focus on the new tab.
You can get all the window handles as handlers=driver. GetWindowHandles() which will return all the handler string. Then using index switch to the appropriate handle using driver.switchto().window(handlers[1])

Selenium Driver (Chrome) Can't Find Dropdown on hover Element

I'm using the Selenium Chrome Driver to run a couple tests on various site environments, however, when attempting to use an element from a hover drop down menu, I can't seem to reliably select the elements. This works 100% of the time when I'm debugging, but when I run it without an attached debugger it fails about 2/3rds of the time. Here is the code:
private void prepWindow(WebDriver driver, boolean isNightly, String toClick) {
WebDriverWait wait = new WebDriverWait(driver, 300);
try {
if (isNightly) {
WebElement nightlyPopup = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(BOWebElements.nightlyPopup)));
nightlyPopup.click();
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Nightly popup has changed names again.", "Error", JOptionPane.ERROR_MESSAGE);
}
WebElement user = wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Users")));
Actions action = new Actions(driver);
action.moveToElement(user).build().perform(); //Makes hover drop down appear
driver.findElement(By.id(toClick)).click(); //Should click element that is only visible when hover drop down is open
}
I should also note that the same code above works perfectly without using a debugger on a coworker's computer, but not my own.
I would like to use XPath but unfortunately the elements of the drop down aren't actually children of the link I have to hover over to open the drop down. If I try to navigate directly to the element using the XPath, it gives me an error saying the XPath isn't valid. Here is one of the potential XPaths:
//html/body/#outTemplateId/#preambleFormId/#globalNavigation/#navBGC/#navBGCmainMM/ul/li/ul/table/tbody/tr/td/ul.ui-menu-list.ui-helper-reset/li.ui-menuitem.ui-widget.ui-corner-all/a#fleetUsersId2.ui-menuitem-link.ui-corner-all.submenu
How can I make the behavior consistent?
Chain your actions together to better emulate the actions that a user would take:
action.moveToElement(user).moveToElement(driver.findElement(By.id(toClick))).click().build().perform();
Check out this question for more details:
https://stackoverflow.com/a/17294390/3537915

Selenium: How can I navigate back to parent window

I am running below java code for switching windows and getting error message, Kindly suggest something.
Driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
Set<String>set=Driver.getWindowHandles();
Iterator<String> It=set.iterator();
String PId=It.next();
String CId=It.next();
Driver.switchTo().window(CId);
Driver.get("https://www.facebook.com");/* Here again I want to come back to parent window and perform some action */
Please refer to this java documentation link for the list of available switchTo options:
https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/WebDriver.TargetLocator.html
In your case, you may need to save the window handle before switching and then use it later to switch back to original window.
String originalWindow = Driver.getWindowHandle();
Driver.switchTo().window(CId);
//Operations on new window here
Driver.switchTo().window(originalWindow);
//Operations on original window here

How can I use assert in Selenium WebDriver?

I need to know how can I do assertion in Selenium WebDriver. My situation is I have one edit, but on screen, but that edit button is present on some certain criteria.
So I want to check that if that button is present. It should be clicked on and it should open another child window and should perform certain actions. If that edit button element is not present on the screen, it should check the next condition which is the log off button in my keyword framework.
I have tried try and catch block and it is working fine.
Here is the code:
public void click_edit_childwindow2(String objectName) {
// Store the current window handle
String winHandleBefore = driver.getWindowHandle();
// Perform the click operation that opens new window
try{
WebElement elemnt = driver.findElement(By.xpath("//*[#id='main']/div[1]/table/tbody/tr[2]/td[6]/button"));
elemnt.click();
driver.findElement(By.xpath("//*[#id='main']/div[1]/table/tbody/tr[2]/td[6]/button")).click();
// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
// Perform the actions on new window
driver.findElement(By.xpath("//*[#id='myModal']/div/div/div[2]/form/div/div[10]/div/button[1]")).click();
// Close the new window, if that window no more required
//driver.close();
// Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);
// Continue with original browser (first window)
}
catch(Exception e){
driver.findElement((By.xpath("//*[#id='logoutForm']/ul/li[2]/a"))).click();
}
}
But I want to do it with assert. Though try and catch is not stopping the code, but after testing execution it is showing that the test case as failed. How can I do it with assert?
I am using keyword framework in which one is class is for keyword and another is for reading an Excel file.
A typical Selenium setup will include a test framework that is attached to your project.
There are several test frameworks to use, but here are the most popular for Java:
jUnit
TestNG
...
When you have a test framework attached to your project, you could then use asserts like:
Assert.assertTrue(driver.getWindowHandles().size().equals(2));
If the assertion fails, it will fail the test script. This is just one small example. I'd certainly do some research on how to use your test framework of choice. Selenium out-of-the-box is designed to be agnostic to what you use. Get creative.
Try the below code:
Boolean isPresent = driver.findElements(By.yourLocator).size() > 0
if(isPresent == true)
{
// Code
}
At first you need to check whether that button is displayed in the webpage. You can do that by this -
WebElement web = driver.findElement(By.xpath("//*[#id='myModal']/div/div/div[2]/form/div/div[10]/div/button[1]"));
boolean bool = web.isDisplayed();
Assert.assertEquals(true, bool); // Here it will match that if that button
// is present or not. If present it will
// continue execution from the next line
// or if it is not present the execution
// stops there and your test case fails.
You could avoid try-catch by:
List <WebElement> editButton = driver.findElements(By.xpath("//*[#id='main']/div[1]/table/tbody/tr[2]/td[6]/button"));
if(editButton.size() > 0)
{
editButton.get(0).click();
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
// Perform the actions on new window
driver.findElement(By.xpath("//*[#id='myModal']/div/div/div[2]/form/div/div[10]/div/button[1]")).click();
// Close the new window, if that window no more required
//driver.close();
//Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);
}
else
{
driver.findElement((By.xpath("//*[#id='logoutForm']/ul/li[2]/a"))).click();
}

Handle Window Pop Up in Selenium

I am working with Selenium, now there is a condition:
when I hit a button in my webpage a window pop up opens up.
Now I have to click a radio button (one out of two, it will work even if we send a TAB ) and then click an OK button. I searched in the net and got to know about "driver.getWindowHandle()".
But I don't have any idea dealing with the newly opened window popup.
Need help in this.
For switching purpose u can use enhanced for loop:
for (String winHandle : objDriver.getWindowHandles()) {
objDriver.switchTo().window(winHandle);
}
So it will switch the control from one driver window to child windows.
To interact with elements on the window try to find element with whatever tool u r using and perform the required action after switching to the window.
To return back to parent window you can use the same loop or use:
driver.switchTo().defaultContent();
Check my answer in this post and also read the comments to help you understand the difference between getWindowHandle() and getWindowHandles()
Java: focus is not on pop-window during window handling
We handled this situation using AutoItX - https://www.autoitscript.com/site/ in our Windows/IE C# project:
AutoItX3 autoIt = new AutoItX3();
var handle = autoIt.WinWaitActive("[window title]", "", 20);
Assert.IsTrue(handle != 0", string.Format("Was not able to find: {0}", [window title]);
autoIt.Send("{ESCAPE}"); // tab may work as well for selection
The pop up was a Windows window, and not part of IE, therefore the WebDriver didn't know about it.
Hope this helps.

Categories