driver.close() will hang for forever - selenium

driver.close() is not working on Jenkins and the whole test will hang for forever. I am using Selenium Grid with Java and using Chrome Driver.
I don't want to user driver.quit(). I have to use driver.close(). I have two tabs open and i have to close one.
public static void closeBrowser()
{
try
{
WebDriver testDriver = BrowserFactory.getInstance().getDriver();
if (testDriver != null)
{
testDriver.close();
}
wait.wait(2);
Log.info("Closing the browser");
}
catch (Exception e)
{
Log.info("Cannot close browser");
}
}
This used to work and started to happen recently.

Try this following:
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "w");
This code will close the currently opened tab.

Better solution i found to close window is:
((JavascriptExecutor) BrowserFactory.getInstance().getDriver()).executeScript( "window.close()" );

Related

selenium.UnsupportedCommandException: the requested resource could not be found, or a request

getting exception
FAILED CONFIGURATION: #AfterClass tearDown
"org.openqa.selenium.UnsupportedCommandException: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource"
enter code here
public class BaseClass {
//read config file and initiate variables
ReadConfig readConfig = new ReadConfig();
public String username = readConfig.getUserName();
//public String password = "asas";
public String password = readConfig.getPassword();
public static AppiumDriver driver;
public static org.apache.logging.log4j.Logger logger;
#BeforeClass
public void setUp ()
{
try {
logger = LogManager.getLogger(BaseClass.class);
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.DEVICE_NAME, "bd178829");
dc.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
dc.setCapability(MobileCapabilityType.APP, "D:\\automation\\CRMNextMobileAutomation\\src\\test\\resources\\apps\\CRMNextNative 6.29.0-release_screenshot_enabled.apk");
dc.setCapability("automationName","UiAutomator2");
dc.setCapability("appPackage", "com.crmnextmobile.crmnextofflineplay");
dc.setCapability("appActivity", "com.crmnextmobile.crmnextofflineplay.qr.QrScannerActivity");
dc.setCapability("enforceAppInsall", true);
URL url = new URL("http://127.0.0.1:4723/wd/hub");
driver = new AppiumDriver(url,dc);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
System.out.println("CRMNext automation start..");
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
//Clicking on Allow option on open permission pop up
//driver.findElement(By.id("com.android.permissioncontroller:id/permission_allow_button")).click();
if(!driver.findElements(By.id ("com.android.permissioncontroller:id/permission_allow_button")).isEmpty()){
//THEN CLICK ON THE SUBMIT BUTTON
System.out.println("permission_allow_button is found on page");
driver.findElement(By.id("com.android.permissioncontroller:id/permission_allow_button")).click();
}else{
//DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
System.out.println("permission_allow_button not found on page");
}
//Clicking on Allow button of run in background pop up
//driver.findElement(By.id("android:id/button1")).click();
if(!driver.findElements(By.id ("android:id/button1")).isEmpty()){
//THEN CLICK ON THE SUBMIT BUTTON
System.out.println("button1 is found on page");
driver.findElement(By.id("android:id/button1")).click();
}else{
//DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
System.out.println("button1 not found on page");
}
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
Thread.sleep(5000);
System.out.println("CRMNext automation Before Skip..");
//Clicking on Skip button
driver.findElement(By.id("com.crmnextmobile.crmnextofflineplay:id/skip")).click();
System.out.println("CRMNext automation after Skip..");
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
Thread.sleep(10000);
driver.findElement(By.id("com.crmnextmobile.crmnextofflineplay:id/relative_layout_continue")).click();
Thread.sleep(2000);
} catch (Exception exp) {
// TODO: handle exception
System.out.println("Cause is :"+exp.getCause());
System.out.println("Message is :"+exp.getMessage());
exp.printStackTrace();
}
}
#Test
public void sample() {
System.out.println("Sample run");
}
#AfterClass
public void tearDown()
{
driver.close();
driver.quit();
}
//org.openqa.selenium.UnsupportedCommandException: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource
all tests are failing due to this.
driver.close()
The driver.close() command is used to close the current browser window having focus. In case there is only one browser open then calling driver.close() quits the whole browser session.
Usability
Use driver.close() when dealing with multiple browser tabs or windows e.g. when clicking on a link that opens another tab. In this case after performing required action in the new tab, to close the tab, call the driver.close() method.
driver.quit()
The driver.quit() is used to quit the whole browser session along with all the associated browser windows, tabs and pop-ups.
Usability
Use driver.quit() when no longer want to interact with the driver object along with any associated window, tab or pop-up. Generally, it is the last statements of the automation scripts. Call driver.quit() in the #AfterClass method to close it at the end of the whole suite.
Use following code in #AfterClass
#AfterClass
public void tearDown()
{
if (driver != null)
driver.Quit();
}

Open Edge in InPrivate mode using Selenium

I am using Selenium 3.4 to launch Edge using the Microsoft WebDriver which is now maintained by Microsoft.
Is there any way I can launch the Browser in InPrivate mode using Selenium?
I have searched for answers but couldn't find any.
The closest I got was How to start Edge browser in Incognito mode using selenium remote webdriver?
The solution mentioned there doesn't work. It just shows the same tab as would be shown in InPrivate, but the window isn't a private one. As such, the information is stored and the session is not private.
Add capabilities...
Try the code below.
DesiredCapabilities capabilities = DesiredCapabilities.edge();
capabilities.setCapability("ms:inPrivate", true);
return new EdgeDriver(capabilities);
I made the capabilities work in Python like this:
from selenium.webdriver import Edge
from selenium.webdriver import DesiredCapabilities
capabilities = DesiredCapabilities.EDGE
capabilities['ms:inPrivate'] = True
driver = Edge(capabilities=capabilities)
Use the below code, employing java.awt.Robot to simulate the key combination CTRL+SHIFT+P to open a new browser window in InPrivate mode:
System.setProperty("webdriver.edge.driver","D:\\Workspace\\StackOverlow\\src\\lib\\MicrosoftWebDriver.exe"); //put actual location
WebDriver driver = new EdgeDriver();
driver.navigate().to("https://www.google.com");
driver.manage().window().maximize();
Robot robot;
try {
// This is the actual code that opens the InPrivate window
robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_P);
robot.keyRelease(KeyEvent.VK_CONTROL);
robot.keyRelease(KeyEvent.VK_SHIFT);
robot.keyRelease(KeyEvent.VK_P);
Thread.sleep(3000);
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String parentWindowHandler = driver.getWindowHandle();
String subWindowHandler = null;
Set<String> handles = driver.getWindowHandles();
Iterator<String> iterator = handles.iterator();
while (iterator.hasNext()){
subWindowHandler = iterator.next();
driver.switchTo().window(subWindowHandler);
System.out.println(subWindowHandler);
}
driver.get("https://stackoverflow.com/");
//driver.switchTo().window(parentWindowHandler); // Uncomment this line if you want to use normal browser back
}
Note that we are using robot class and so if the system locks it may not work.

Drag and drop functionality not working in selenium chromedriver

I am working on a drag and drop functionality using selenium chromedriver. But unfortunately unable to achieve it. I am using following piece of code,
public void dragAndDropElement() {
try {
WebElement imgToDrag = driver.findElement(By
.className("imageclassname"));
WebElement dropHere = driver.findElement(By.cssSelector("panelcssname"));
Actions action = new Actions(driver);
Actions actions = null, movetoElement = null;
actions = action.clickAndHold(imgToDrag);
Thread.sleep(3000);
movetoElement = actions.moveToElement(dropHere);
movetoElement.perform();
movetoElement.release();
Thread.sleep(6000);
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception occured in DragAndDropClass :: dragAndDropElement()", e);
}
}
After running this code, nothing is happening I mean neither it is throwing any exception nor it is performing drag and drop functionality. What mistake I am doing here, can anybody help me to get out of this problem.

org.openqa.selenium.remote.SessionNotFoundException: The FirefoxDriver cannot be used after quit()

driver.findElement(By.xpath(OR.getProperty(object))).click();
System.out.println("Test");
Click works for some button.But on clicking a specific button in application.
But 'org.openqa.selenium.remote.SessionNotFoundException' erro comes after the above driver action. Test is not printed on console after that click. Why is it so?
public static void click(String object, String data){
try{
/*try
{
driver.switchTo().alert().accept();
}
catch(Exception e){}*/
new WebDriverWait(driver, 30).until(ExpectedConditions.elementToBeClickable(By.xpath(OR.getProperty(object))));
driver.findElement(By.xpath(OR.getProperty(object))).click();
System.out.println("Test");
Log.info("Clicking on Webelement "+ object);
}catch(Exception e){
Log.error("Not able to click --- " + e.getMessage());
DriverScript.bResult = false;
}
}
This is the code. Its a keyword driven framework. This action keyword gets executed 6 times perfectly. But on clicking some button which popups new window this error occurs. Switch window is supposed to be the next action keyword to be executed. But it is not reaching there . Just after .click it stands idle for long time. Then the above exception.
public static void switchwindow(String object,String data){
try{
parentHandle = driver.getWindowHandle();
System.out.println(driver.getWindowHandles().size());// get the current window handle
for (String winHandle : driver.getWindowHandles()) {
if(winHandle.equalsIgnoreCase("73e19507-bf40-44ce-822a-62630be49c2b"))
{driver.switchTo().window(winHandle);break;} // switch focus of WebDriver to the next found window handle (that's your newly opened window)
}
Log.info("Switched to new window");
}
catch(Exception e){
Log.error("Not able to switch the window --- " + e.getMessage());
DriverScript.bResult = false;
}
}
Seems that your browser is already closed.
I would simplified tests and not call quit anywhere in code.
I would also tried if problem exist in other browsers. Also U could debug or introduce sleeps to check where execly problem is.
I suspect there could be an issue with your code for switching windows. It would be better to debug if you could show the code for switching windows.

release Selenium chromedriver.exe from memory

I set up a python code to run Selenium chromedriver.exe. At the end of the run I have browser.close() to close the instance. (browser = webdriver.Chrome()) I believe it should release chromedriver.exe from memory (I'm on Windows 7). However after each run there is one chromedriver.exe instance remain in the memory. I hope there is a way I can write something in python to kill the chromedriver.exe process. Obviously browser.close() doesn't do the work. Thanks.
per the Selenium API, you really should call browser.quit() as this method will close all windows and kills the process. You should still use browser.quit().
However: At my workplace, we've noticed a huge problem when trying to execute chromedriver tests in the Java platform, where the chromedriver.exe actually still exists even after using browser.quit(). To counter this, we created a batch file similar to this one below, that just forces closed the processes.
kill_chromedriver.bat
#echo off
rem just kills stray local chromedriver.exe instances.
rem useful if you are trying to clean your project, and your ide is complaining.
taskkill /im chromedriver.exe /f
Since chromedriver.exe is not a huge program and does not consume much memory, you shouldn't have to run this every time, but only when it presents a problem. For example when running Project->Clean in Eclipse.
browser.close() will close only the current chrome window.
browser.quit() should close all of the open windows, then exit webdriver.
Theoretically, calling browser.Quit will close all browser tabs and kill the process.
However, in my case I was not able to do that - since I running multiple tests in parallel, I didn't wanted to one test to close windows to others. Therefore, when my tests finish running, there are still many "chromedriver.exe" processes left running.
In order to overcome that, I wrote a simple cleanup code (C#):
Process[] chromeDriverProcesses = Process.GetProcessesByName("chromedriver");
foreach(var chromeDriverProcess in chromeDriverProcesses)
{
chromeDriverProcess.Kill();
}
//Calling close and then quit will kill the driver running process.
driver.close();
driver.quit();
I had success when using driver.close() before driver.quit(). I was previously only using driver.quit().
It's kinda strange but it works for me. I had the similar issue, after some digging I found that there was still a UI action going on in the browser (URL loading or so), when I hit WebDriver.Quit().
The solution for me (altough very nasty) was to add a Sleep() of 3 seconds before calling Quit().
This answer is how to properly dispose of the driver in C#
If you want to use a 'proper' mechanism that should be used to 'tidy up' after running ChromeDriver you should use IWebDriver.Dispose();
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
(Inherited from IDisposable.)
I usually implement IDisposable on class that is dealing with IWebDriver
public class WebDriverController : IDisposable
{
public IWebDriver Driver;
public void Dispose()
{
this.Driver.Dispose();
}
}
and use it like:
using (var controller = new WebDriverController())
{
//code goes here
}
Hope this saves you some time
Kill Multiple Processes From the Command Line
The first thing you’ll need to do is open up a command prompt, and then use the taskkill command with the following syntax:
taskkill /F /IM <processname.exe> /T
These parameters will forcibly kill any process matching the name of the executable that you specify. For instance, to kill all iexplore.exe processes, we’d use:
taskkill /F /IM iexplore.exe
So, you can use the following:
driver.close()
Close the browser (emulates hitting the close button)
driver.quit()
Quit the browser (emulates selecting the quit option)
driver.dispose()
Exit the browser (tries to close every tab, then quit)
However, if you are STILL running into issues with hanging instances (as I was), you might want to also kill the instance. In order to do that, you need the PID of the chrome instance.
import os
import signal
driver = webdriver.Chrome()
driver.get(('http://stackoverflow.com'))
def get_pid(passdriver):
chromepid = int(driver.service.process.pid)
return (chromepid)
def kill_chrome(thepid)
try:
os.kill(pid, signal.SIGTERM)
return 1
except:
return 0
print ("Loaded thing, now I'mah kill it!")
try:
driver.close()
driver.quit()
driver.dispose()
except:
pass
kill_chrome(chromepid)
If there's a chrome instance leftover after that, I'll eat my hat. :(
You should apply close before than quit
driver.close()
driver.quit()
Code c#
using System.Diagnostics;
using System.Management;
public void KillProcessAndChildren(string p_name)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select * From Win32_Process Where Name = '"+ p_name +"'");
ManagementObjectCollection moc = searcher.Get();
foreach (ManagementObject mo in moc)
{
try
{
KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
}
catch (ArgumentException)
{
break;
}
}
}
and this function
public void KillProcessAndChildren(int pid)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select * From Win32_Process Where ParentProcessID=" + pid);
ManagementObjectCollection moc = searcher.Get();
foreach (ManagementObject mo in moc)
{
try
{
KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
}
catch
{
break;
}
}
try
{
Process proc = Process.GetProcessById(pid);
proc.Kill();
}
catch (ArgumentException)
{
// Process already exited.
}
}
Calling
try
{
KillProcessAndChildren("chromedriver.exe");
}
catch
{
}
I had the same issue when running it in Python and I had to manually run 'killall' command to kill all processes. However when I implemented the driver using the Python context management protocol all processes were gone. It seems that Python interpreter does a really good job of cleaning things up.
Here is the implementation:
class Browser:
def __enter__(self):
self.options = webdriver.ChromeOptions()
self.options.add_argument('headless')
self.driver = webdriver.Chrome(chrome_options=self.options)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.driver.close()
self.driver.quit()
And the usage:
with Browser() as browser:
browser.navigate_to_page()
Python code:
try:
# do my automated tasks
except:
pass
finally:
driver.close()
driver.quit()
I know this is somewhat of an old question, but I thought I'd share what worked for me. I was having problems with Eclipse -- it wouldn't kill the processes, and so I had a bunch of phantom processes hanging around after testing the code using the Eclipse runner.
My solution was to run Eclipse as administrator. That fixed it for me. Seems that Windows wasn't permitting Eclipse to close the process it spawned.
This work with python for me
import os
os.system('cmd /k "taskkill /F /IM chromedriver.exe /T"')
os.system('cmd /k "taskkill /F /IM chrome.exe /T"')
I have looked at all the responses and tested them all. I pretty much compiled them all into one as a 'Safety closure'. This in C#
Note: you can change the param from IModule app to that of the actual driver.
public class WebDriverCleaner
{
public static void CloseWebDriver(IModule app)
{
try
{
if (app?.GetDriver() != null)
{
app.GetDriver().Close();
Thread.Sleep(3000); // Gives time for everything to close before quiting
app.GetDriver().Quit();
app.GetDriver().Dispose();
KillProcessAndChildren("chromedriver.exe"); // One more to make sure we get rid of them chromedrivers.
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public static void KillProcessAndChildren(string p_name)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select * From Win32_Process Where Name = '" + p_name + "'");
ManagementObjectCollection moc = searcher.Get();
foreach (ManagementObject mo in moc)
{
try
{
KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
}
catch (ArgumentException)
{
break;
}
}
}
public static void KillProcessAndChildren(int pid)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid);
ManagementObjectCollection moc = searcher.Get();
foreach (ManagementObject mo in moc)
{
try
{
KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
}
catch
{
break;
}
}
try
{
Process proc = Process.GetProcessById(pid);
proc.Kill();
}
catch (ArgumentException)
{
// Process already exited.
}
}
}
I have this issue. I suspect its due to the version of Serenity BDD and Selenium. The chromedriver process never releases until the entire test suite finishes. There are only 97 tests, but having 97 processes eat up the memory of a server that hasn't much resources may be having an affect on the performance.
To address I did 2 things (this is specific to windows).
before each test (annotated with #Before) get the process id (PID) of the chromedriver process with:
List<Integer> pids = new ArrayList<Integer>();
String out;
Process p = Runtime.getRuntime().exec("tasklist /FI \"IMAGENAME eq chromedriver.exe*\"");
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((out = input.readLine()) != null) {
String[] items = StringUtils.split(out, " ");
if (items.length > 1 && StringUtils.isNumeric(items[1])) {
pids.add(NumberUtils.toInt(items[1]));
}
}
after each test (annotated with #After) kill the PID with:
Runtime.getRuntime().exec("taskkill /F /PID " + pid);
For Ubuntu/Linux users: -
the command is either pkill or killall . pkill is generally recommended, since on some systems, killall will actually kill all processes.
I am using Protractor with directConnect. Disabling the "--no-sandbox" option fixed the issue for me.
// Capabilities to be passed to the webdriver instance.
capabilities: {
'directConnect': true,
'browserName': 'chrome',
chromeOptions: {
args: [
//"--headless",
//"--hide-scrollbars",
"--disable-software-rasterizer",
'--disable-dev-shm-usage',
//"--no-sandbox",
"incognito",
"--disable-gpu",
"--window-size=1920x1080"]
}
},
Make Sure You get the Driver instance as Singleton
then Apply at end
driver.close()
driver.quit()
Note: Now if we see task manager you will not find any driver or chrome process still hanging
I simply use in every test a method tearDown() as following and I have no problem at all.
#AfterTest
public void tearDown() {
driver.quit();
driver = null;
}
After quitting the driver instance clear it from the cache by driver = null
Hope the answer the question
There is another way which is working only for windows, but now it is deprecated. it works for previous selenium releases (it works on 3.11.0 version).
import org.openqa.selenium.os.WindowsUtils;
WindowsUtils.killByName("chromedriver.exe") // any process name you want
So, nothing worked for me. What I ended up doing was setting a unique ID on my addArguments to launch chromedriver, then when I want to quit I do something like this:
opts.addArguments(...args, 'custompid' + randomId());
Then to make sure it quits:
await this.driver.close()
await this.driver.quit()
spawn(`kill $(ps aux | grep ${RANDOM_PID_HERE} | grep -v "grep" | awk '{print $2}')`).on('error', e => { /* ignores when grep returns empty */ })
Ugly af, but it's the only thing that worked for my case.
just use this two ways:
open console and run this: taskkill /F /IM chromedriver.exe /T for kill all chrome processes
after how your test is complete you should driver.Dispose, not Close and also not Quit, just Dispose it.
Good Luck.
I came here initially thinking surely this would have been answered/resolved but after reading all the answers I was a bit surprised no one tried to call all three methods together:
try
{
blah
}
catch
{
blah
}
finally
{
driver.Close(); // Close the chrome window
driver.Quit(); // Close the console app that was used to kick off the chrome window
driver.Dispose(); // Close the chromedriver.exe
}
I was only here to look for answers and didn't intend to provide one. So the above solution is based on my experience only. I was using chrome driver in a C# console app and I was able to clean up the lingering processes only after calling all three methods together.
Observed on version 3.141.0:
If you initialize your ChromeDriver with just ChromeOptions, quit() will not close out chromedriver.exe.
ChromeOptions chromeOptions = new ChromeOptions();
ChromeDriver driver = new ChromeDriver(chromeOptions);
// .. do stuff ..
driver.quit()
If you create and pass in a ChromeDriverService, quit() will close chromedriver.exe out correctly.
ChromeDriverService driverService = ChromeDriverService.CreateDefaultService();
ChromeOptions chromeOptions = new ChromeOptions();
ChromeDriver driver = new ChromeDriver(driverService, chromeOptions);
// .. do stuff ..
driver.quit()
I have used the below in nightwatch.js in afterEach hooks.
afterEach: function(browser, done) {
// performing an async operation
setTimeout(function() {
// finished async duties
done();
browser.closeWindow();
browser.end();
}, 200);
}
.closeWindow() just simply closes the window. (But wont work for multiple windows opened).
Whereas .end() ends all the remaining chrome processes.
Please try this tested codes:
ChromeDriverService driverService = ChromeDriverService.createDefaultService();
ChromeDriver chrome = new ChromeDriver(driverService, chromeOptions);
//
// code
//
//
chrome.close();
chrome.quit();
driverService.close();