James Dunn
James Dunn

Reputation: 8274

In Java, best way to check if Selenium WebDriver has quit

I need to check a collection of Page Objects to see, for each one, if quit() has been called on its WebDriver.

I've written the following method to check a WebDriver's state:

public static boolean hasQuit(WebDriver driver) {
        try {
            driver.getTitle();
            return false;
        } catch (SessionNotFoundException e) {
            return true;
        }
}

Here's the problem: I don't like having to throw and catch an exception to discover the truth of a boolean, but it seems I have no choice since the WebDriver API doesn't provide a method to check if the driver has quit.

So my question is, is there a better way to check if a WebDriver has quit?

I found a similar (and more general) question here, but the question did not have any code that had been tried, and the only answer was to always set the WebDriver to null after quiting (which I don't necessarily have control over).

Upvotes: 34

Views: 36594

Answers (3)

Dingredient
Dingredient

Reputation: 2199

If quit() has been called, driver.toString() returns null:

>>> FirefoxDriver: firefox on XP (null))

Otherwise, it returns a hashcode of the object:

>>> FirefoxDriver: firefox on XP (9f897f52-3a13-40d4-800b-7dec26a0c84d)

so you could check for null when assigning a boolean:

boolean hasQuit = driver.toString().contains("(null)");

Upvotes: 24

James Dunn
James Dunn

Reputation: 8274

There are basically two approaches you can take, depending on your situation.

Situation 1: Extending WebDriver is not a realistic option.

This is the most common situation. Most developers working with Selenium in real-work situations who want a handy way of telling if a WebDriver has quit are working in an already established testing framework, and trying to refactor the framework to ensure that only your custom extensions of WebDrivers are used is probably more trouble than it's worth.

In this case, Sajan's answer and Gili's recommendation of his answer won't be useful, because overriding RemoteWebDriver#stopClient() is not an option. (Besides, even if it was, most people are looking for a simple answer.)

As long as you are only using standard implementations of WebDriver that come with Selenium (FirefoxDriver, ChromeDriver, InternetExplorerDriver, SafariDriver, etc.), you can cast the WebDriver to a RemoteWebDriver and then check if the sessionId is null (Pat was on the right track, but a direct call to sessionId is better than using toString()).

public static boolean hasQuit(WebDriver driver) {
    return ((RemoteWebDriver)driver).getSessionId() == null;
}

This answer should be good for 95% of all cases, because how often are you going to use a WebDriver that doesn't implement RemoteWebDriver? (Not very often.)

Situation 2: You CAN realistically extend your WebDriver.

This situation is less common, but perhaps you are either:
    (a)  Working with a well-designed and abstracted framework, or
    (b)  Starting a selenium test framework from scratch.

In this case, you can create your own interface that extends WebDriver:

public interface CustomDriver extends WebDriver {

    boolean hasQuit();

}

And then you can extend standard WebDrivers like so (in this example, ChromeDriver):

public class CustomChromeDriver extends ChromeDriver implements CustomDriver {

    boolean hasQuit = false;

    @Override
    public boolean hasQuit() {
        return hasQuit;
    }

    @Override
    public void stopClient() {
        super.stopClient();
        hasQuit = true;
    }
}

Upvotes: 16

Sajan Chandran
Sajan Chandran

Reputation: 11487

StopClient method will be invoked after quit (RemoteWebDriver Source) is called, may be you can subclass your instance of RemoteWebDriver and override stopClient method, set some flag and check for the flag to determine if the webdriver is closed (quit).

Upvotes: 5

Related Questions