Reputation: 8274
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
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
Reputation: 8274
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.)
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
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