I use Selenium to perform automation.
However, if I repeat automation, I have a lot of chromedrivers.
I want to solve this problem.
Can't you just run one chromedriver?
The reason you're left with the *driver.exe processes is most probably because you are not explicitly closing them at the end of your tests run - calling the quit() method on the driver object in your chosen language.
That step is usually done in the object's destructor - if you're using object-oriented approach; a finally block if it's exception-handling; or the the program's/script's exit lines. Most high-level frameworks (Cucumber, TestNG, Robotframework, the plethora of unit testing in the different languages) have some kind of "tear-down" blocks which is usually used for this purpose.
Why is this happening?
When you start your automation, the OS starts the process for it; when you instantiate a webdriver object, it spawns a process for the browser's driver - the "chromedriver.exe" in your case. The next step is to open the browser instance - the "chrome.exe".
When your run finishes, the process for it is closed. But, if you have not explicitly called the quit() method - the browser's driver persists, "stays alive"; and is now an orphaned process (not to be mistaken with a zombie one, which is a totally different thing) - fully functional, yet - with no program to command it.
In fact, at this stage - having a working driver process and a browser, you can reconnect to it, and use in future runs. Check out how and why here - https://stackoverflow.com/a/52003231/3446126
As per the screenshot you have provided there seems to be presence of a couple of Zombie ChromeDriver process within your system.
Answering straight, you can't work with initiating just one ChromeDriver process while repeat automation as you can not reconnect to the previous browsing session. You can find a detailed discussion in How can I reconnect to the browser opened by webdriver with selenium?
You code trials would have given us more insights why the ChromeDriver processes are not getting cleaned up. As per best practices always invoke driver.quit() within tearDown(){} method to close & destroy the WebDriver and Web Client instances gracefully as follows:
driver.quit() // Python
//or
driver.quit(); // Java
//
driver.Quit(); // DotNet
You can find a detailed discussion in PhantomJS web driver stays in memory
Incase the ChromeDriver processes are still not destroyed and removed you may require to kill the processes from tasklist. You can find a detailed discussion in Selenium : How to stop geckodriver process impacting PC memory, without calling driver.quit()?
Python Solution(Cross Platform):
import os
import psutil
PROCNAME = "geckodriver" # or chromedriver or IEDriverServer
for proc in psutil.process_iter():
# check whether the process name matches
if proc.name() == PROCNAME:
proc.kill()
I use a cleanup routine at the end of my tests to get rid of zombie processes, temp files, etc. (Windows, Java)
import org.apache.commons.io.FileUtils;
import java.util.logging.Logger;
import java.io.File;
import java.io.IOException;
public class TestCleanup {
protected static Logger logger = Logger.getLogger(TestCleanup.class.getName());
public void removeTemporaryFiles() {
try {
FileUtils.cleanDirectory(new File(getPropertyValue("java.io.tmpdir")));
} catch (IOException ioException) {
logger.info("IOexception trying to clean the downloads directory: " + ioException.getMessage());
}
}
public void closeWebdriver() {
webDriver.close();
}
public void killOperatingSystemSessions() {
try {
Process process = Runtime.getRuntime().exec("taskkill /IM \"chromedriver.exe\" /F");
} catch (IOException ioException) {
logger.info("Exception when shutting down chromedriver process: " + ioException.getMessage());
}
}
}
Related
We are using Junit5 + Selenium/Webdriver to run parallel tests.
junit-platform.properties has this settings:
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
junit.jupiter.execution.parallel.mode.classes.default = concurrent
junit.jupiter.execution.parallel.config.dynamic.factor = 1.5
junit.jupiter.execution.parallel.config.strategy = dynamic
The Test*.java:
public class TestSuiteParallel extends TestSuite {
#RepeatedTest(2)
void testParallel() {
WebDriver driver = new ChromeDriver();
driver.get("https://www.amazon.com")
driver.quit();
}
}
Running in Linux everything works perfect, we have multiple Chromium windows handled separately by each thread worker. Headless or not, it works.
Running in Windows, always only ONE Chrome window with multiple tabs is openend. And only the last openend tab (in foreground) works sometimes. Mostly all tabs are frozen, nothing happens, after some seconds we get WebDriverException: unknown error: Chrome failed to start: crashed
If I change the code to #RepeatedTest(1) it runs without errors as expected.
So why this works so differently? Is there a setting I can force WebDriver to always open separate Browser windows? Or maybe it's more an operation system setting?
There is an existing question for the same problem but that question was not completely answered, so posting new question.
I am new to selenium and trying to execute the very basic script, but getting the compilation errors. I am using Eclipse Oxygen 4.7.2 and Selenium 3.8.1. I have added all the necessary Jar files and used the Geckodriver as well, still i am getting errors. Below are the error messages in the console window:
**"Exception in thread "main" java.lang.Error: Unresolved compilation problems:
package automationFramework;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class FirstTestCase {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.setProperty("Webdriver.gecko.driver","C:\\Users\\vermap6\\Downloads\\geckodriver-v0.19.0-win64\\geckodriver.exe");
// Create a new instance of the Firefox driver
WebDriver driver = new FirefoxDriver();
//Launch the Online Store Website
driver.get("http://www.google.com");
// Print a Log In message to the screen
System.out.println("Successfully opened the website www.google.com");
//Wait for 5 Sec
Thread.sleep(5000);
// Close the driver
driver.quit();
}
}
WebDriver cannot be resolved to a type
FirefoxDriver cannot be resolved to a type"**
Can anybody tell me what mistake i am doing ? Attaching screenshots. Webdriver Error.png JAr Files in Selenium 3.8.1
The problem is about file permission. I guess you are using Mac or Linux and the default permission of the library doesn't allow Eclipse to read it. What you need is going to the directory in Terminal and then use sudo chmod to change the permission.
sudo chmod -R 755 ./
Then you may need to restart Eclipse.
I want to write Selenium test cases in JUnit and test my projects in multiple browsers and I would like to take advantage of the fact that all Selenium drivers implement the same interface.
Each test case should look like this:
package fm;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import static org.junit.Assert.*;
public class HomepageTest {
#Test
public void testTitle(WebDriver driver) {
driver.get("http://localhost/");
assertEquals("Foo", driver.getTitle());
}
#Test
public void testSearchForm(WebDriver driver) {
//...
}
}
The passed WebDriver implementations should be controlled somewhere centrally. I'll probably need to override some of the JUnit behaviour and I hope it's possible.
I want to do it this way in order to avoid two things:
Code repetition: If each test case would initialize all tested browsers in #Before, the test suite would have a lot of repeated code that is hard to maintain.
Speed of the test suite: If I had centralized control over the order and passed WebDriver implementations, I could easily manage to open for example Firefox, run all test cases in it, close it and open the next browser. If each test case would manage to open and close browsers on its own, it would add a lot of time to each test run.
Anybody have an idea how should I do it? Thanks.
In the Selenium project we inject what we need using http://code.google.com/p/selenium/source/browse/trunk/java/client/test/org/openqa/selenium/AbstractDriverTestCase.java and then our build calls the browser and we get tests running in it.
Have a look at our code base to get some inspiration!
Please check with ISFW it supports selenium webdriver/remote webdriver as well as conventional (selenium1) rc way.
You need to write code using regular selenium api
for example
selenium.open(url);
selenium.type("loc", "text to type");
selenium.submit("loc");
Here is the working demo. Set browser String as per your requirement.
The FW support selenium conventional way as well as selenium 2 webdriver. You need to set appropriate browser string in application properties. Following are different browser configurations for Firefox:
*firefox - required selenium server running on configured host/port
if not found then fw will check/start one on locahost/port
firefoxDriver – will run directly with firefox web driver without
selenium server
firefoxRemoteDriver - required selenium server running on
configured host/port if not found then fw will check/start one on
locahost/port, it will run test using firefox web driver on host
machine
Same way for IE - *iexplore, *iehta, iexplorerDriver, iexplorerRemoteDriver
and so on.
I did what you are/were? trying to do with a static class that controlls the webdriver and all my test which need the same webdriver get it from there. It really helps when you are running multiple tests that need to use the same session. And all your tests run in one browser, so not every tests opens a new browser instance.
Maybe you should also have a look at testNG. I made the experience that testNG is better for tests with selenium since it is not so focused on independent tests. It offers a lot of useful functionality.
Is there a way we can start the Selenium RC server without using command prompt?
Also, is there a way of seeing the Log window and Test case window in the same one window?
You may use the following code snippet:
new Thread(new Runnable() {
#Override
public void run()
{
org.openqa.selenium.server.SeleniumServer.main();
}
}, "SeleniumServer").start();
Or much simpler in Groovy:
new Thread({ org.openqa.selenium.server.SeleniumServer.main(); }, "SeleniumServer").start()
This may sound a bit random, but I would suggest using maven to control your build and test process. There is a nice plugin for Selenium in maven that will control the startup/shutdown of the server. Maven will provide you with many other added benefits.
I want to add a suite of Selenium tests as part of a global PHPUnit test suite for an application. I have hooked the suite of Selenium tests into the global AllTests.php file and everything runs fine whilst the Selenium server is running.
However, I would like the script to skip the Selnium tests if the Selenium server isn't running so other developers aren't forced to install Selenium server in order for the tests to run. I would normally try to connect within the setUp method of each testcase and mark the tests as skipped if this failed, but this seems to throw a RuntimeException with message:
The response from the Selenium RC server is invalid: ERROR Server Exception: sessionId should not be null; has this session been started yet?
Does anyone have a method for marking the Selenium tests as skipped in this scenario?
You could use test dependencies that were introduced in PHPUnit 3.4.
Basically
write a test that checks whether Selenium is up.
If not, call $this->markTestAsSkipped().
Make all your selenium requiring tests depend on this one.
My preferred selenium / PHPUnit Configuration:
Maintaining integration (selenium) tests can be a lot of work. I use the firefox selenium IDE for developing test cases, which doesn't support exporting test suites to PHPUnit, and only supports individual test cases. As such - if I had to maintain even 5 tests, that'd be a lot of manual work to re-PHPUnit them every time they needed to be updated. That is why I setup PHPUnit to use Selenium IDE's HTML Test files! They can be reloaded & reused between PHPUnit & selenium IDE
<?php
class RunSeleniumTests extends PHPUnit_Extensions_SeleniumTestCase {
protected $captureScreenshotOnFailure = true;
protected $screenshotPath = 'build/screenshots';
protected $screenshotUrl = "http://localhost/site-under-test/build/screenshots";
//This is where the magic happens! PHPUnit will parse all "selenese" *.html files
public static $seleneseDirectory = 'tests/selenium';
protected function setUp() {
parent::setUp();
$selenium_running = false;
$fp = #fsockopen('localhost', 4444);
if ($fp !== false) {
$selenium_running = true;
fclose($fp);
}
if (! $selenium_running)
$this->markTestSkipped('Please start selenium server');
//OK to run tests
$this->setBrowser("*firefox");
$this->setBrowserUrl("http://localhost/");
$this->setSpeed(0);
$this->start();
//Setup each test case to be logged into WordPress
$this->open('/site-under-test/wp-login.php');
$this->type('id=user_login', 'admin');
$this->type('id=user_pass', '1234');
$this->click('id=wp-submit');
$this->waitForPageToLoad();
}
//No need to write separate tests here - PHPUnit runs them all from the Selenese files stored in the $seleneseDirectory above!
} ?>
You can try skipWithNoServerRunning()
For more information follow this link