How to close the whole browser window by keeping the webDriver active? - selenium

In my batch execution, multiple browsers with multiple tabs are getting opened for first scenario. I wanted to close all these browsers before starting second scenario.
Driver.close() is just closing one tab of the browser.
Driver.quit() is closing all the browsers and also ending the WebDriver session. So , am unable to run the batch execution. Please provide a solution for this.

You should understand difference between driver.close() and driver.quit()
driver.close() and driver.quit() are two different methods for closing the browser session in Selenium WebDriver. Understanding both of them and knowing when to use which method is important in your test execution.
driver.close() – It closes the the browser window on which the focus is
set.
driver.quit() – It basically calls driver.dispose method which in turn
closes all the browser windows and ends the WebDriver session
gracefully.
You should use driver.quit() whenever you want to end the program. It will close all opened browser window and terminates the WebDriver session. If you do not use driver.quit at the end of program, WebDriver session will not close properly and files would not be cleared off memory. This may result in memory leak errors.
In your case you have to use driver.close() which will close current window and keeps driver active.
Just to add - if there is only browser window open and you use driver.close(), it will quit the webdriver session. The webdriver will not stay active.

The below explanation should explain the difference between driver.close and driver.quit methods in WebDriver. I hope you find it useful.
driver.close and driver.quit are two different methods for closing the browser session in Selenium WebDriver.
Understanding both of them and knowing when to use each method is important in your test execution. Therefore, I have tried to shed some light on both of these methods.
driver.close - This method closes the browser window on which the focus is set. driver.quit close the session of webdriver while
driver.close only close the current window on which selenium control is present but webdriver session not close yet, if no other window open and you call
driver.close then it also close the session of webdriver.
driver.quit – This method basically calls driver.dispose a now internal method which in turn closes all of the browser windows and
ends the WebDriver session gracefully.
driver.dispose - As mentioned previously, is an internal method of WebDriver which has been silently dropped according to another answer - Verification needed. This method really doesn't have a use-case in a normal test workflow as either of the previous methods should work for most use cases.
Explanation use case: You should use driver.quit whenever you want to end the program. It will close all opened browser windows and terminates the WebDriver session. If you do not use driver.quit at the end of the program, the WebDriver session will not close properly and files would not be cleared from memory. This may result in memory leak errors.
............
Now In that case you need to specific browser.
Below is code which will close all the child windows except the Main window.
String homeWindow = driver.getWindowHandle();
Set<String> allWindows = driver.getWindowHandles();
//Use Iterator to iterate over windows
Iterator<String> windowIterator = allWindows.iterator();
//Verify next window is available
while(windowIterator.hasNext())
{
//Store the Recruiter window id
String childWindow = windowIterator.next();
}
//Here we will compare if parent window is not equal to child window
if (homeWindow.equals(childWindow))
{
driver.switchTo().window(childWindow);
driver.close();
}
Now here you need to modify or add the condition according to your need
if (homeWindow.equals(childWindow))
{
driver.switchTo().window(childWindow);
driver.close();
}
Currently it is checking only if home window is equal to childwindow or not. Here you need to specify the condition like which id's you want to close. I never tried it so just suggested you the way to achive your requirement.

This code closes all the opened windows and then brings back control to the main window.
public static void switchTab() {
try {
Set<String> windows = webDriver.getWindowHandles();
Iterator<String> iter = windows.iterator();
String[] winNames=new String[windows.size()];
int i=0;
while (iter.hasNext()) {
winNames[i]=iter.next();
i++;
}
if(winNames.length > 1) {
for(i = winNames.length; i > 1; i--) {
webDriver.switchTo().window(winNames[i - 1]);
webDriver.close();
}
}
webDriver.switchTo().window(winNames[0]);
}
catch(Exception e){
e.printStackTrace();
}
}

My problem was, that when I opened a lot of URLs in the loop, I got a lot of open windows that are memory- and processor-consuming.
Attempt to use webDriver.close() in the end of a loop resulted in org.openqa.selenium.NoSuchSessionException: Tried to run command without establishing a connection - webDriver called quit() cause only one window was opened in first loop run (look top answer for explanation).
Final solution:
if (webDriver.getWindowHandles().size() > 1){
webDriver.close();
}

Related

Is there a change in the handling of unhandled alert in ChromeDriver and Chrome with Selenium?

I have a test that has been running fine for months. One thing it does is cause an alert and then verify the alert text. This is running with Selenium, Java and Chrome Driver 76.0.3809.68.
Lately it has been giving me the error:
"No such alert".
What happens is it clicks a button and waits for an alert if there:
try {
button.click();
} catch (UnhandledAlertException ex) {
// nothing
}
// then here goes code to accept the alert and get the text
when stepping through I see the alert. When I run it, I see the alert but it disappears. I did read something in the (Chrome Driver) release notes about unexpected alerts but it was a bit vague.
We have a global page which sets the options for Chrome, but everyone uses it and I don't want to screw up for other people. I did do it locally (did not git push) and it worked when I set the options before creating the driver.
Then I tried to do this, which does not seem to work. Should it, or once the web page is retrieved, can you not change options?
// Somewhere after web page retrieved this gets called:
public void setIgnoreAlert() {
ChromeDriver cd = (ChromeDriver) driver;
ChromeOptions cap = new ChromeOptions();
cap.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE);
Capabilities other = cap;
cd.getCapabilities().merge(other);
}
Which I was really hoping would work, but did not. Do you have to set the behavior before the Chrome instance comes up? That is, can you not set it as I did above? Any other suggestions on how to set it after the Chrome instance is up?
--- added later to answer question
This is done immediately after the try-catch block with button.click():
The method configPage.getAndHandleAlertPopUp() does the following:
public String getAndHandleAlertPopUp() {
Alert alert = driver.switchTo().alert();
String alertPopup = alert.getText();
alert.accept();
return alertPopup;
}
You saw it right. As per the User Prompts section within WebDriver - W3C Recommendation:
The common denominator for user prompts is that they are modal windows requiring users to interact with them before the event loop is unpaused and control is returned to the current top-level browsing context.
By default user prompts are not handled automatically unless a user prompt handler has been defined. When a user prompt appears, it is the task of the subsequent command to handle it. If the subsequent requested command is not one listed in this chapter, an unexpected alert open error will be returned.
User prompts that are spawned from beforeunload event handlers, are dismissed implicitly upon navigation or close window, regardless of the defined user prompt handler.
A user prompt has an associated user prompt message that is the string message shown to the user, or null if the message length is 0.
As per the discussion in ChromeDriver should return user prompt (or alert) text in unhandled alert error response:
When a user prompt handler is triggered, the W3C Specification states that the error response should return an "annotated unexpected alert open error" which includes an optional dictionary containing the text of the user prompt. ChromeDriver should supply the optional information.
Clearly, ChromeDriver was not compliant with this standard as the #Test were annotated with #NotYetImplemented as follows:
#Test
#NotYetImplemented(CHROME)
#NotYetImplemented(CHROMIUMEDGE)
#Ignore(value = HTMLUNIT, reason = "https://github.com/SeleniumHQ/htmlunit-driver/issues/57")
#NotYetImplemented(value = MARIONETTE,
reason = "https://bugzilla.mozilla.org/show_bug.cgi?id=1279211")
#NotYetImplemented(EDGE)
public void testIncludesAlertTextInUnhandledAlertException() {
driver.get(alertPage("cheese"));
driver.findElement(By.id("alert")).click();
wait.until(alertIsPresent());
assertThatExceptionOfType(UnhandledAlertException.class)
.isThrownBy(driver::getTitle)
.withMessageContaining("cheese")
.satisfies(ex -> assertThat(ex.getAlertText()).isEqualTo("cheese"));
}
Now this feature have been implemented with ChromeDriver v76.0:
Resolved issue 2869: ChromeDriver should return user prompt (or alert) text in unhandled alert error response [Pri-2]
So you have to handle the alert as a mandatory measure.
A bit more of your code code block for ...then here goes code to accept the alert and get the text... would have helped us to debug the issue in a better way. However here are the options:
Induce WebDriverWait for alertIsPresent() as follows:
new WebDriverWait(driver, 10).until(ExpectedConditions.alertIsPresent());
Your code trials was perfect perhaps as you have passed the CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE in a structured way:
public void setIgnoreAlert() {
ChromeOptions opt = new ChromeOptions();
opt.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.IGNORE);
}
Another perspective would be to disable the beforeunload event handlers and you can find a couple of related discussions in:
How to disable a “Reload site? Changes you made may not be saved” popup for (python) selenium tests in chrome?
How to handle below Internet Explorer popup “Are you sure you want to leave this page?” through Selenium
Note: Once the WebDriver and Web Browser instances are initialized you won't be able to change the configuration on the run. Even if you are able to extract the Session ID, Cookies and other capabilities and session attributes from the Browsing Session still you won't be able to alter those attributes of the WebDriver.
You can find a detailed discussion in How can I reconnect to the browser opened by webdriver with selenium?

Selenium:How can I delay the closing of a browser let's say for 5 sec

I have run all my Tests successfully and I have used the driver.close command at the end but I want to delay the closing of a browser for 5 or 10 sec which means once all tests gets executed then browser waits for like 5 sec and then gets close. Is it possible to do this and how?
Just add a "sleep" before calling close().
In Python:
import time
time.sleep(5)
driver.close()
In Java:
Thread.sleep(2000);
driver.close();
Using Selenium 2.x api (not 3.x), you can do it like so, and you wont have to change the test methods signature to throw a InterruptedException :
Sleeper.sleepTight(2000);
Usually, I start the web browser in the tests #Before annotated method and then in the #After annotated method I will stick that sleeper and then a driver.close. Sometimes, just before the sleep, I will navigate the page to a success page and display that just before the browser closes.

Issue with WebDriver test case

I have written a test case using WebDriver, I closed the browser in one method and again I am opening the browser not able to invoke
driver.close();i closed the browser through above command for again opening a browser i driver.get(url)
but i am getting error
'Error communicating with the remote browser It may have died'
If you really want to close the browser before navigating to the new URL, then do:
driver.quit();
driver = new FirefoxDriver();
driver.get(url);
However, why would you want to close the browser before navigating to the new URL in the first place?
I can think of either one of two reasons:
You want to go to the next URL with your browser's history cleaned.
If this is indeed the case, then deleteAllCookies will do the job.
You cannot go to the next URL because some popup alert is preventing you doing it.
If this is indeed the case, then neither close not quit will do the job.
Well you killed the browser with your driver.close();
In order to use the driver you must create a new one using something like driver = new FirefoxDriver(capabilities);
Moving to answer from comment.
I think I got your issue. Though you have called the close() and it only should close the current window, you should use this if you want to shift between multiple windows.
For your case just don't close the driver it will use the same window to open the url.
You have to use following way if you want to close the current browser and open
a new one:
webDriver.Close();
//Goto the Target website
WebDriver.Navigate().GoToUrl("url");
And you can use following way if you want to close the browser and kill the
web driver:
webDriver.Close();
webDriver.Quit();

How could I start a Selenium browser(like Firefox) minimized?

How could I start a Selenium browser (like Firefox) minimized? I want the command browser.start(mySettings) to start a browser minimized.
I have an alternate solution that may meet your needs. You can set the position of the WebDriver to be outside of your view. That way, it'll be out of sight while it runs. (It may start at a visible location, but it will only be there for an instant.)
FirefoxDriver driver = new FirefoxDriver();
driver.manage().window().setPosition(new Point(-2000, 0));
Your question does not say that why you want to run your test cases in minimized browser but unfortunately selenium do not provide any built-in function for the same.
Normally when we want to run test cases with maximized browser we use driver.manage().window().maximize();
No doubt there are several ways to minimize your window through code by using Java key event by using keyboard shortcuts for minimimzing window or by using JavaScriptExecuter but that too depend on which OS and language you are working.
One more thing you can try is HtmlUnitDriver.By using this you cant even see the browser, so that may also serve your purpose if you have a case of not opening the browser while execution of test cases.
Dimension windowMinSize = new Dimension(100,100);
driver.manage().window().setSize(windowMinSize);
For C# you can minimize window easily, also with a built in way.
See: https://www.selenium.dev/documentation/en/webdriver/browser_manipulation
Screenshot:
Without knowing your motive for minimizing the browser and assuming that you are using the WebDriver drivers (Selenium v2) and don't want a UI to pop up, one could use the lightweight browser HtmlUnitDriver.
After you define the driver
driver = webdriver.Chrome(r"FULL PATH TO YOUR CHROMEDRIVER")
Do
driver.minimize_window()
And then call the site
driver.get(r'SITE YOU WANT TO SELECT')
It will minimize.
When Using Python to Move the FireFox Browser off screen:
driver = webdriver.FireFox()
driver.set_window_position(-2000,0)
driver.set_window_position(2000,2000)
or
(x,y) values more than monitor resolution
Later if u want to see the window again
driver.maximize_window()
The workarounds mentioned in the post did not work for NodeWebKit browser, so as a workaround i had to use native C# code as mentioned below:
public static void MinimiseNWKBrowser(IWebDriver d)
{
var body = UICommon.GetElement(By.TagName("body"), d);
body.Click();
string alt = "%";
string space = " ";
string down = "{DOWN}";
string enter = "{ENTER}";
SendKeys.SendWait(alt + space);
for(var i = 1; i <= 5; i++)
{
SendKeys.SendWait(down);
}
SendKeys.SendWait(enter);
}
So this workaround basically uses "ALT+SPACE" to bring up the browser action menu to select "MINIMIZE" from the options and presses "ENTER"
In php we can use JavaScript command to minimize the browser window.
$this->selenium->getEval("Minimize();");
and similar command for java :
browser.getEval("Minimize();");
The best way to minimize your browser is to use shortcut using Robot class.
Shortcut: Alt+Space+N (for Windows)
Robot robot=new Robot();
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyPress(KeyEvent.VK_N);
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_N);
By using above code you can minimize your browser.
Selenium doesn't have a built-in method to minimize the Browsing Context. Minimizing the browser while the Test Execution is In Progress would be against the best practices as Selenium may loose the focus over the Browsing Context and an exception may raise during the Test Execution. You can find a relevant detailed discussion in How to execute tests with selenium webdriver while browser is minimized
However, to mimic the functionality of minimizing the Browsing Context you can use the following steps:
Set the dimension of the Browsing Context to [0, 0]
Set the position of the top left corner of the Browsing Context just below the Viewport
Code Block (Java):
driver.navigate().to("https://www.google.com/");
Point p = driver.manage().window().getPosition();
Dimension d = driver.manage().window().getSize();
driver.manage().window().setSize(new Dimension(0,0));
driver.manage().window().setPosition(new Point((d.getHeight()-p.getX()), (d.getWidth()-p.getY())));
You can use:
driver.manage().window().maximize();
For example code snippet with chrome driver:
System.setProperty("webdriver.chrome.driver", "C://chromedriver.exe");
driver = new ChromeDriver();
baseUrl = "chrome://newtab/";
driver.manage().window().maximize().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
for Firefox use just "firefordriver.exe"
driver.manage().window().minimize();
This should help minimize the window. You can also use "maximize" in place of "minimize" to maximize the window.

How to close the pop up window in selenium running?

I wanna close the pop up window (known window name), and back to the original window.
What shall I do?
If I can't get a constant of the close button in window. so is there any general behavior to reach the goal?
Using WebDriver (shown with Java) you could do something like this:
// instantiate your driver
...
// get window handle
String baseWindowHdl = driver.getWindowHandle();
// navigate to pop-up
...
// close pop-up
driver.close();
// switch back to base window
driver.switchTo().window(baseWindowHdl);
Have you tried:
selenium.Close();
selenium.SelectWindow("null");
I dont know if you are still looking for an answer, but i had some troubles with this.
After spending more than one hour on searching for a way to do it, dont want to use webdriver. I tried using the garbage collector:
Selenium selenium = new DefaultSelenium(......);
selenium.start();
................
selenium.close(); //to terminate testing window
selenium = null; //make sure there are no references to the file
System.gc(); //now the garbage collector can kick in
This worked for me.