Skip to content

Instantly share code, notes, and snippets.

@DylanLacey
Created February 20, 2020 03:23
Show Gist options
  • Save DylanLacey/67eb33a67e027c48732d855b7e5d98f8 to your computer and use it in GitHub Desktop.
Save DylanLacey/67eb33a67e027c48732d855b7e5d98f8 to your computer and use it in GitHub Desktop.
TestNG WebDriver Session Cleanup Code
/**
* Simple TestNG test which demonstrates being instantiated via a DataProvider in order to supply multiple browser combinations.
*
* @authors Neil Manvar, Dylan Lacey
*/
public class TestBase {
// SNIP
/**
* ThreadLocal variable which contains the Shutdown Hook instance for this Thread's WebDriver.
*
* Registered just before Browser creation, de-registered after 'quit' is called.
*/
private ThreadLocal<Thread> shutdownHook = new ThreadLocal<>();
/**
* Creates the shutdownHook, or returns an existing copy
*/
private Thread getShutdownHook() {
if (shutdownHook.get() == null) {
shutdownHook.set( new Thread(() -> {
try {
if (webDriver.get() != null) webDriver.get().quit();
} catch (org.openqa.selenium.NoSuchSessionException ignored) { } // Don't care if session already closed
}));
}
return shutdownHook.get();
}
/**
* Registers the shutdownHook with the runtime.
*
* Ignoring exceptions on registration; They mean the VM is already shutting down and it's too late.
*/
private void registerShutdownHook() {
// Register a hook to always close this session. Only works/needed once session is created.
try {
Runtime.getRuntime().addShutdownHook(getShutdownHook());
} catch (IllegalStateException ignored) {} // Thrown if a hook is added while shutting down; We don't care
}
/**
* De-registers the shutdownHook. This allows the GC to remove the thread and avoids double-quitting.
*
* Silently swallows exceptions if the VM is already shutting down; it's too late.
*/
private void deregisterShutdownHook() {
if (shutdownHook.get() != null) {
try {
Runtime.getRuntime().removeShutdownHook(getShutdownHook());
} catch (IllegalStateException ignored) { } // VM already shutting down; Irrelevant
}
}
// SNIP
/**
* Constructs a new {@link RemoteWebDriver} instance which is configured to use the capabilities defined by the browser,
* version and os parameters, and which is configured to run against ondemand.saucelabs.com, using
* the username and access key populated by the {@link #authentication} instance.
*
* @param browser Represents the browser to be used as part of the test run.
* @param version Represents the version of the browser to be used as part of the test run.
* @param os Represents the operating system to be used as part of the test run.
* @param methodName Represents the name of the test case that will be used to identify the test on Sauce.
* @return
* @throws MalformedURLException if an error occurs parsing the url
*/
protected void createDriver(String browser, String version, String os, String methodName)
// SNIP
webDriver.set(new RemoteWebDriver(
new URL("https://" + username + ":" + accesskey + "@ondemand.saucelabs.com/wd/hub"),
capabilities));
registerShutdownHook();
// set current sessionId
String id = ((RemoteWebDriver) getWebDriver()).getSessionId().toString();
sessionId.set(id);
}
/**
* Method that gets invoked after test.
* Dumps browser log and
* Closes the browser
*/
@AfterMethod
public void tearDown(ITestResult result) throws Exception {
((JavascriptExecutor) webDriver.get()).executeScript("sauce:job-result=" + (result.isSuccess() ? "passed" : "failed"));
webDriver.get().quit();
deregisterShutdownHook();
}
//SNIP
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment