package cucumber.examples.java.websockets;

import cucumber.annotation.After;
import cucumber.annotation.Before;
import cucumber.runtime.ScenarioResult;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.events.EventFiringWebDriver;

/**
 * Example of a WebDriver implementation that has an underlying instance that is used for all scenarios and closed
 * when the JVM exits. This saves time. To prevent browser state from leaking between scenarios, cookies are deleted before
 * every scenario.
 * <p/>
 * As a bonus, screenshots are embedded into the report for each scenario. (This only works
 * if you're also using the HTML formatter).
 * <p/>
 * This class can be shared across step definitions via dependency injection.
 */
public class SharedDriver extends EventFiringWebDriver {
    private static final WebDriver REAL_DRIVER = new ChromeDriver();

    static {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                REAL_DRIVER.close();
            }
        });
    }

    public SharedDriver() {
        super(REAL_DRIVER);
    }

    @Before
    public void deleteAllCookies() {
        manage().deleteAllCookies();
    }

    @After
    public void embedScreenshot(ScenarioResult result) {
        try {
            byte[] screenshot = this.getScreenshotAs(OutputType.BYTES);
            result.embed(screenshot, "image/png");
        } catch (WebDriverException somePlatformsDontSupportScreenshots) {
            System.err.println(somePlatformsDontSupportScreenshots.getMessage());
        }
    }
}

@@ -1010,67 +1010,55 @@
 ();%0A
-%0A
     
-static %7B%0A        Runtime.getRuntime().addShutdownHook(
+private static final Thread CLOSE_THREAD = 
 new 
@@ -1064,28 +1064,24 @@
  Thread() %7B%0A
-    
         @Ove
@@ -1094,20 +1094,16 @@
         
-    
 public v
@@ -1126,20 +1126,16 @@
         
-  
-  
 REAL_DRI
@@ -1159,86 +1159,423 @@
     
+%7D%0A
     %7D
+;%0A
 %0A    
-    %7D);%0A    %7D%0A%0A    public SharedDriver() %7B%0A        super(REAL_DRIVER
+static %7B%0A        Runtime.getRuntime().addShutdownHook(CLOSE_THREAD);%0A    %7D%0A%0A    public SharedDriver() %7B%0A        super(REAL_DRIVER);%0A    %7D%0A%0A    @Override%0A    public void close() %7B%0A        if(Thread.currentThread() != CLOSE_THREAD) %7B%0A            throw new UnsupportedOperationException(%22You shouldn't close this WebDriver. It's shared and will close when the JVM exits.%22);%0A        %7D%0A        super.close(
 );%0A 

Add a guard to make sure people don't accidentally close the shared driver from a hook or stepdef.