I have a circumstance in which clicking a link webpage opens a popup window. And after the popup window opens the focus is in the popup window and master window is disabled. And i am unable to get the control transferred to the popup window.
Please have a look at the following code.
driver.findElement(By.linkText("Click me")).click();// when this line of code is reached then a popup window opens.
System.out.println("After Clicking me"); // After the popup window opens this line of code is never executed.
I am unable to transfer the control from parent window to popup window. I am aware of the following command.
driver.switchTo().window("popup window");
But its not helping much. please help me.
This is a code i use when i need to work with a following pop-up window, close it and go back to my main window. Of course it has been simplified for the purpose of this answer. It maintains a handle of the original window (main) so it can make a difference between the others.
It requires an explicit WebDriverWait because i did have problems during development that code got run before the window actually got open, so this might not be a ideal condition,
function manipulatePopUp(final WebDriver driver, final WebDriverWait wait) {
final String mainWindowHandle = driver.getWindowHandle();
driver.findElement(By.id("linkThatOpensPopUp")).click();
wait.until(new ExpectedConditions<Boolean>() {
#Override
public Boolean apply(WebDriver d) {
return (d.getWindowHandles().size() != 1);
}
});
for (String activeHandle : driver.getWindowHandles()) {
if (!activeHandle.equals(mainWindowHandle)) {
driver.switchTo().window(activeHandle);
}
}
driver.close();
driver.switchTo().window(mainWindowHandle);
}
driver.findElement(By.linkText("Click me")).click();// when this line of code is reached then a popup window opens.
System.out.println("After Clicking me"); // After the popup window
opens this line of code is never executed.
The line of code is never executed because the process is waiting for the popup to be handled.
getWindowHandles() works properly in this situation.
Example:
//handle of the master window before clicking the link
String master = driver.getWindowHandle();
driver.findElement(By.linkText("Click me")).click();
//logic for waiting for the popup, checking the size to become greater than 1 or breaking after sometime to avoid the infinite loop.
int timeCount = 1;
do
{
driver.getWindowHandles();
Thread.sleep(200);
timeCount++;
if ( timeCount > 50 )
{
break;
}
}
while ( driver.getWindowHandles().size == 1 );
//Assigning the handles to a set
Set<String> handles = driver.getWindowHandles();
//Switching to the popup window.
for ( String handle : handles )
{
if(!handle.equals(master))
{
driver.switchTo().window(handle);
}
}
Now driver is switched to the popup window. If the popup window has a frame then you need to switch to the frame before identifying elements in it.
public class socialSignOn extends masterBaseClassNewSiteStage {
#Test
public void testSocialSignOn() throws Throwable {
openParticularUrl("/my-lfc/join/user-details?user_type=free");
driver.findElement(By.cssSelector("#socialSignOn > div.left.socialLogin.googleButton")).click();
String MainWindow = driver.getWindowHandle();
for (String activeHandle : driver.getWindowHandles()) {
if (!activeHandle.equals(MainWindow)) {
driver.switchTo().window(activeHandle);
}
}
driver.findElement(By.cssSelector("#Email")).sendKeys("");
driver.findElement(By.cssSelector("#next")).click();
pauseFiveSeconds();
driver.findElement(By.cssSelector("#Passwd")).sendKeys("");
driver.findElement(By.cssSelector("#signIn")).click();
pauseOneSecond();
driver.switchTo().window(MainWindow);
pauseTenSeconds();
closeDriver();
}
}
// delay : max number of seconds
new WebDriverWait(driver, delay * 1000).until(ExpectedConditions.alertIsPresent());
drive`enter code here`r.switchTo().alert().accept();
Related
After some time searching for the issue I have I could not encounter any solution. So here I am.
Some background, I am trying to automate the sign up, confirmation and join for a "Live Class" for certain platform.
To do so, you have every 10 minutes a 5 minutes window where you can sign up, then confirm, then wait X time then Join the live class.
But this is just for the first part, where I want to sign up. This is what I did using fluent wait:
public void joinPrivateClass() {
System.out.println("Starting join private class");
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(480))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
WebElement signUp = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
WebElement signUpButton = driver.findElement(By.xpath("//*[#id=\"live-class-322102\"]/div[1]/div/div/button"));
if(signUpButton.isDisplayed()){
System.out.println("button is displayed");
} else {
System.out.println("button is not displayed yet");
}
return signUpButton;
}
}); signUp.click();
}
My issue is that after the page is loaded, while the fluentwait "works" I expected to have a "Button is not displayed" every 5 sec until it is and then gets clicked. but while the button is displayed or not I am not getting any message neither the "Button is not displayed" nor "The button is displayed" so I would assume that something is failing in the "wait.until"
Some things to mention, I am not a programmer so sorry if I did something wrong,
Also in my IDE (intelliJ) it marks me the "driver" of this portion of code
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
In "purple" and this "driver" :
public WebElement apply(WebDriver driver)
in GREY if it has anything to do with! thanks for your precious help
Your wait is built with ignoring(NoSuchElementException.class). So as long as the button does not exist, your wait.until(...) will just silently keep failing at the findElement(...) line - it will never make it to the println(...).
Remove the ignoring(...) from your wait, and change your wait.until(...) body to something like:
WebElement signUpButton;
try {
signUpButton = driver.findElement(By.xpath("//*[#id=\"live-class-322102\"]/div[1]/div/div/button"));
System.out.println("button is displayed");
} catch(NoSuchElementException ignored) {
System.out.println("button is not displayed yet");
}
return signUpButton;
When clickevent is fired, I want it to redirect/open new page in same tab. The new tab would be '/Waiting', however even after click event is fired, it stays in the same page. While doing manually by going to browser's localhost, it works though. Also, even after 10 secs, it doesn't load.
#Test
public void firstPlayerConnection() {
try {
driver.get(uiPath);
WebElement startGame = driver.findElement(By.id("startGame"));
startGame.click();
WebElement gif = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("loading")));
assertEquals("/Waiting", driver.getCurrentUrl());
} finally {
driver.quit();
}
}
Provide wait explicitly, & if it still does not work then try to use submit() in place of click().
If I'm not mistaken the NoSuchElement exception must be on the startGame.Click() command. To avoid this exception you have to (explicit) wait till this element is clickable.
WebElement startGame = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.elementToBeClickable(By.id("startGame")));
I would like to implement a custom wait method which should wait till a loading popup is visible.
This loading popup has its own id = "wait". I use this custom expectedConditions (from Stackoverflow) to check it:
public static ExpectedCondition<Boolean> absenceOfElementLocated(
final WebElement element) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
try {
element.isDisplayed();
return false;
} catch (NoSuchElementException e) {
return true;
} catch (StaleElementReferenceException e) {
return true;
}
}
#Override
public String toString() {
return "element to not being present: " + element.getText();
}
};
}
My script pass on when the loading still visible and I do not know why.
Thanks!
Use ExpectedConditions#invisibilityOfElementLocated(By locator)
You can also use negation -> ExpectedConditions#not(ExpectedCondition condition)
A basic example:
Go to this page: Primefaces - dropdown
There is Submit button on this page, if you click on this button, then Selected message will appear on the screen, then this message will dissapear after a few seconds.
So we will wait in our code for the following events:
the button appears and is clickeable (it cannot be clicked until it is not clickeable)
the message appears and is visible
the message disappears an is not visible
WebDriver driver = new ChromeDriver();
try {
driver.get("https://www.primefaces.org/showcase/ui/ajax/dropdown.xhtml");
final By buttonSubmit = By.xpath("//button[ *[ text() = 'Submit' ]]");
final By message = By.xpath("//span[ text() = 'Selected' ]");
WebDriverWait wait = new WebDriverWait(driver, 50);
long time = System.currentTimeMillis();
wait.until(ExpectedConditions.elementToBeClickable(buttonSubmit)).click();
System.out.println(String.format("Button clicked after %d miliseconds", System.currentTimeMillis() - time));
wait.until(ExpectedConditions.visibilityOfElementLocated(message));
System.out.println(String.format("The message appeared after %d miliseconds", System.currentTimeMillis() - time));
// wait.until(ExpectedConditions.invisibilityOfElementLocated(message));
wait.until(ExpectedConditions.not(ExpectedConditions.visibilityOfElementLocated(message)));
System.out.println(String.format("The message dissapeared after %d miliseconds", System.currentTimeMillis() - time));
} finally {
driver.quit();
}
And a result is:
Starting ChromeDriver 2.33.506120 (e3e53437346286c0bc2d2dc9aa4915ba81d9023f) on port 15827
.....
.....
.....
Button clicked after 153 miliseconds
The message appeared after 791 miliseconds
The message dissapeared after 6924 miliseconds
It's hard to tell why your code isn't working without more of the code. You do have some logic errors in your custom wait but you don't need that custom wait because ExpectedConditions already has visibility and invisibility covered.
Use this to wait for the popup to appear
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.id("wait")));
Use this to wait for the popup to disappear
new WebDriverWait(driver, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("wait")));
There are times when a popup is just a container for dynamically loaded content. In these cases, you might wait for the frame of the popup to appear but the contents of the frame are not quite loaded yet so if you try to interact with them, you will get errors. In those cases you will need to wait for an element inside the container to be visible.
Same thing for when a dialog is closing. I've had experiences where I've waited for the dialog container to close but the grey overlay is still up blocking clicks, etc. In those cases I had to wait for the overlay to become invisible.
I would suggest that you spend some time familiarizing yourself with the available methods of ExpectedConditions and save yourself having to write custom waits for things that already exist and don't need to be debugged/tested.
I got an error org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with. How can i solve it?
It could mean that your element visibility is set to hidden. Or it could also mean that the element is not currently in view and have to be scrolled into view.
If it's not visible while the WebDriver is looking to interact with the drop down then:
1st-) You should increase the implicit wait time, until any controller appears in the UI:
public Accesor(WebDriver driver,String url){
this.driver = driver;
this.driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.get(url);
}
2nd-)Try waiting until that specific element appears (but i wouldnt recommend that):
WebElement cBoxOverlay = wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("cboxOverlay"))));
3rd-) If it's a real bug of the application and the UI does not show the dropdown you are looking for that is suppose to be there then try handling those kind of exceptions by taking a screenshot of the screen and trying with the next testcase or testsuite:
public void takePicture(){
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// Now you can do whatever you need to do with it, for example copy somewhere
try {
FileUtils.copyFile(scrFile, new File("c:\\tmp\\"+ getClass().getName().substring("com.automation.testsuite.".lastIndexOf(".")+1) + ""+new Date().toString().substring(0,10) +".png"));
} catch (IOException e) {
e.printStackTrace();
}
I have to write an applet that brings up a password dialog. The problem is that dialog is set to be always on top but when user clicks on IE window dialog gets hidden behind IE window nevertheless. And since dialog is modal and holds all IE threads IE pane does not refresh and dialog window is still painted on top of IE (but not refreshed). This behaviour confuses users (they see dialog on top of IE but it looks like it has hanged since it is not refreshe).
So I need a way to keep that dialog on top of everything. But any other solution to this problem would be nice.
Here's the code:
PassDialog dialog = new PassDialog(parent);
/* do some non gui related initialization */
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
Resolution: As #shemnon noted I should make a window instead of (null, Frame, Applet) parent of modal dialog. So good way to initlialize parent was:
parent = javax.swing.SwingUtilities.getWindowAncestor(theApplet);
What argument are you using for the parent?
You may have better luck if you use the parent of the Applet.
javax.swing.SwingUtilities.getWindowAncestor(theApplet)
Using the getWindowAncestor will skip the applet parents (getRoot(component) will return applets). In at least some versions of Java there was a Frame that was equivalent to the IE window. YMMV.
Make a background Thread that calls toFront on the Dialog every 2 seconds.
Code that we use (I hope I got everything):
class TestClass {
protected void toFrontTimer(JFrame frame) {
try {
bringToFrontTimer = new java.util.Timer();
bringToFrontTask = new BringToFrontTask(frame);
bringToFrontTimer.schedule( bringToFrontTask, 300, 300);
} catch (Throwable t) {
t.printStackTrace();
}
}
class BringToFrontTask extends TimerTask {
private Frame frame;
public BringToFrontTask(Frame frame) {
this.frame = frame;
}
public void run()
{
if(count < 2) {
frame.toFront();
} else {
cancel();
}
count ++;
}
private int count = 0;
}
public void cleanup() {
if(bringToFrontTask != null) {
bringToFrontTask.cancel();
bringToFrontTask = null;
}
if(bringToFrontTimer != null) {
bringToFrontTimer = null;
}
}
java.util.Timer bringToFrontTimer = null;
java.util.TimerTask bringToFrontTask = null;
}
This is a shot in the dark as I'm not familiar with applets, but you could take a look at IE's built-in window.showModalDialog method. It's fairly easy to use. Maybe a combination of this and Noah's suggestion?
You might try launching a modal from JavaScript using the JavaScript integration (see http://www.raditha.com/java/mayscript.php for an example).
The JavaScript you would need would be something like:
function getPassword() {
return prompt("Enter Password");
}
And the Java would be:
password = jso.call("getPassword", new String[0]);
Unfortunately that means giving up all hope of having a nice looking modal. Good luck!