cucumber / cucumber-jvm

Cucumber for the JVM
https://cucumber.io
MIT License
2.7k stars 2.02k forks source link

[Core] Race condition in Timeout #1241

Closed AndyLPK247 closed 7 years ago

AndyLPK247 commented 7 years ago

Summary

I recently created an example test automation project for Cucumber-JVM using Java 8. It contains a basic Google searching test that uses Selenium WebDriver. The step definitions are written using the new Java 8 lambda style, rather than the traditional method annotation style. The Before and After hooks, also written using the lambda style, respectively initialize and quit a ChromeDriver instance. However, while the init is successful and steps can run, the quit consistently fails with an exception:

Failure in after hook:LambdaGlueBase.java:60 Message: org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died.

Source Code Projects

The example project with the failure is located at: https://github.com/AndyLPK247/cucumber-jvm-java8-example

I also wrote a nearly-identical project that uses the method annotations for step defs: https://github.com/AndyLPK247/cucumber-jvm-java-example

The project with method annotations for step defs works flawlessly.

Feature File Example

Feature: Google Searching As a web surfer, I want to search Google, So that I can learn new things.

@automated @web @google @panda Scenario: Simple Google search Given a web browser is on the Google page When the search phrase "panda" is entered Then results for "panda" are shown

Step Definition Snippet

public GoogleSearchSteps() {
        Before(new String[]{"@web"}, 1000, 1, (Scenario scenario) -> {
            driver = new ChromeDriver();
        });
        Before(new String[]{"@google"}, 1000, 10, (Scenario scenario) -> {
            googlePage = new GooglePage(driver);
        });
        Given("^a web browser is on the Google page$", () -> {
            googlePage.navigateToHomePage();
        });
        When("^the search phrase \"([^\"]*)\" is entered$", (String phrase) -> {
            googlePage.enterSearchPhrase(phrase);
        });
        Then("^results for \"([^\"]*)\" are shown$", (String phrase) -> {
            assertThat(googlePage.pageTitleContains(phrase)).isTrue();
        });
        After(new String[]{"@web"}, (Scenario scenario) -> {
            driver.quit();
        });
    }

Expected Behavior

The expected behavior is that the web driver should work fine. It should be instantiated in the Before, used in the steps, and quit in the After. This works perfectly when the step definitions are written using method annotations.

Current Behavior

When the step definitions are written using lambda expressions, the web driver instance exhibits failing behavior. The exception indicates that the web driver is no longer available when it hits the After hook.

The Maven test output is:

Running com.automationpanda.example.runners.PandaCucumberTest Feature: Google Searching As a web surfer, I want to search Google, So that I can learn new things. Starting ChromeDriver 2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2) on port 21259 Only local connections are allowed. Oct 08, 2017 10:49:59 PM org.openqa.selenium.remote.ProtocolHandshake createSession INFO: Detected dialect: OSS Failure in after hook:LambdaGlueBase.java:60 Message: org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died. Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z' System info: host: 'sterling2', ip: '192.168.1.137', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.6', java.version: '1.8.0_121' Driver info: driver.version: RemoteWebDriver Capabilities [{mobileEmulationEnabled=false, hasTouchScreen=false, platform=MAC, acceptSslCerts=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, platformName=MAC, setWindowRect=true, unexpectedAlertBehaviour=, applicationCacheEnabled=false, rotatable=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2), userDataDir=/var/folders/f0/b04p_rzs5374f4rtqmn2js480000gn/T/.org.chromium.Chromium.crkYPX}, takesHeapSnapshot=true, pageLoadStrategy=normal, unhandledPromptBehavior=, databaseEnabled=false, handlesAlerts=true, version=61.0.3163.100, browserConnectionEnabled=false, nativeEvents=true, locationContextEnabled=true, cssSelectorsEnabled=true}] Session ID: 231984ed19a7354247cbc15b782897cf at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:607) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:643) at org.openqa.selenium.remote.RemoteWebDriver.quit(RemoteWebDriver.java:482) at com.automationpanda.example.stepdefs.GoogleSearchSteps.lambda$new$5(GoogleSearchSteps.java:42) at cucumber.runtime.java.Java8HookDefinition$1.call(Java8HookDefinition.java:51) at cucumber.runtime.Timeout.timeout(Timeout.java:16) at cucumber.runtime.java.Java8HookDefinition.execute(Java8HookDefinition.java:47) at cucumber.runtime.Runtime.runHookIfTagsMatch(Runtime.java:224) at cucumber.runtime.Runtime.runHooks(Runtime.java:212) at cucumber.runtime.Runtime.runAfterHooks(Runtime.java:206) at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:46) at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:102) at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63) at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70) at cucumber.api.junit.Cucumber.runChild(Cucumber.java:95) at cucumber.api.junit.Cucumber.runChild(Cucumber.java:38) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at cucumber.api.junit.Cucumber.run(Cucumber.java:100) at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252) at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141) at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) Caused by: java.lang.RuntimeException: java.lang.InterruptedException at org.openqa.selenium.net.UrlChecker.waitUntilUnavailable(UrlChecker.java:145) at org.openqa.selenium.remote.service.DriverService.stop(DriverService.java:213) at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:95) at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:586) ... 41 more Caused by: java.lang.InterruptedException at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:404) at java.util.concurrent.FutureTask.get(FutureTask.java:204) at com.google.common.util.concurrent.SimpleTimeLimiter.callWithTimeout(SimpleTimeLimiter.java:147) at org.openqa.selenium.net.UrlChecker.waitUntilUnavailable(UrlChecker.java:115) ... 44 more

  org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died.
  Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z'
  System info: host: 'sterling2', ip: '192.168.1.137', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.6', java.version: '1.8.0_121'
  Driver info: driver.version: RemoteWebDriver
  Capabilities [{mobileEmulationEnabled=false, hasTouchScreen=false, platform=MAC, acceptSslCerts=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, platformName=MAC, setWindowRect=true, unexpectedAlertBehaviour=, applicationCacheEnabled=false, rotatable=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2), userDataDir=/var/folders/f0/b04p_rzs5374f4rtqmn2js480000gn/T/.org.chromium.Chromium.crkYPX}, takesHeapSnapshot=true, pageLoadStrategy=normal, unhandledPromptBehavior=, databaseEnabled=false, handlesAlerts=true, version=61.0.3163.100, browserConnectionEnabled=false, nativeEvents=true, locationContextEnabled=true, cssSelectorsEnabled=true}]
  Session ID: 231984ed19a7354247cbc15b782897cf
      at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:607)
      at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:643)
      at org.openqa.selenium.remote.RemoteWebDriver.quit(RemoteWebDriver.java:482)
      at com.automationpanda.example.stepdefs.GoogleSearchSteps.lambda$new$5(GoogleSearchSteps.java:42)
      at cucumber.runtime.java.Java8HookDefinition$1.call(Java8HookDefinition.java:51)
      at cucumber.runtime.Timeout.timeout(Timeout.java:16)
      at cucumber.runtime.java.Java8HookDefinition.execute(Java8HookDefinition.java:47)
      at cucumber.runtime.Runtime.runHookIfTagsMatch(Runtime.java:224)
      at cucumber.runtime.Runtime.runHooks(Runtime.java:212)
      at cucumber.runtime.Runtime.runAfterHooks(Runtime.java:206)
      at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:46)
      at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:102)
      at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
      at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
      at cucumber.api.junit.Cucumber.runChild(Cucumber.java:95)
      at cucumber.api.junit.Cucumber.runChild(Cucumber.java:38)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at cucumber.api.junit.Cucumber.run(Cucumber.java:100)
      at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
      at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
      at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
      at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
      at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
      at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
      at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
  Caused by: java.lang.RuntimeException: java.lang.InterruptedException
      at org.openqa.selenium.net.UrlChecker.waitUntilUnavailable(UrlChecker.java:145)
      at org.openqa.selenium.remote.service.DriverService.stop(DriverService.java:213)
      at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:95)
      at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:586)
      ... 41 more
  Caused by: java.lang.InterruptedException
      at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:404)
      at java.util.concurrent.FutureTask.get(FutureTask.java:204)
      at com.google.common.util.concurrent.SimpleTimeLimiter.callWithTimeout(SimpleTimeLimiter.java:147)
      at org.openqa.selenium.net.UrlChecker.waitUntilUnavailable(UrlChecker.java:115)
      ... 44 more

@automated @web @google @panda Scenario: Simple Google search # GoogleSearch.feature:7 Given a web browser is on the Google page # GoogleSearchSteps.java:32 When the search phrase "panda" is entered # GoogleSearchSteps.java:35 Then results for "panda" are shown # GoogleSearchSteps.java:38

Failed scenarios: GoogleSearch.feature:7 # Scenario: Simple Google search

1 Scenarios (1 failed) 3 Steps (3 passed) 0m5.828s

Possible Solution

I don't know what is causing this problem. However, a workaround is to specify the web driver instantiation in a traditional method annotation style Before hook.

Steps to Reproduce (for bugs)

  1. git clone https://github.com/AndyLPK247/cucumber-jvm-java8-example.git
  2. Edit the step def file to include/exclude the workaround.
  3. mvn clean test

Context & Motivation

It makes no sense why Selenium web driver would work with the old style of step defs but not the new style of step defs.

Your Environment

I tested this on macOS Sierra using ChromeDriver. I also tested with FirefoxDriver and got similar errors.

mlvandijk commented 7 years ago

@AndyLPK247 I see you're using v1.2.5; have you tried v2.0.x yet?

AndyLPK247 commented 7 years ago

I updated my Maven dependencies:

        <!-- Cucumber -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java8</artifactId>
            <version>2.0.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>2.0.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-picocontainer</artifactId>
            <version>2.0.1</version>
            <scope>test</scope>
        </dependency>

And I still get the same error:

Running com.automationpanda.example.runners.PandaCucumberTest
Feature: Google Searching
  As a web surfer,
  I want to search Google,
  So that I can learn new things.

  @automated @web @google @panda
  Scenario: Simple Google search              # src/test/resources/com/automationpanda/example/features/GoogleSearch.feature:7
Starting ChromeDriver 2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2) on port 40093
Only local connections are allowed.
Oct 09, 2017 8:45:30 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
    Given a web browser is on the Google page # NativeConstructorAccessorImpl.java:-2
    When the search phrase "panda" is entered # NativeConstructorAccessorImpl.java:-2
    Then results for "panda" are shown        # NativeConstructorAccessorImpl.java:-2
      org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died.
Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z'
System info: host: 'sterling2', ip: '192.168.1.137', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.6', java.version: '1.8.0_121'
Driver info: driver.version: RemoteWebDriver
Capabilities [{mobileEmulationEnabled=false, hasTouchScreen=false, platform=MAC, acceptSslCerts=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, platformName=MAC, setWindowRect=true, unexpectedAlertBehaviour=, applicationCacheEnabled=false, rotatable=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2), userDataDir=/var/folders/f0/b04p_rzs5374f4rtqmn2js480000gn/T/.org.chromium.Chromium.R3wqiw}, takesHeapSnapshot=true, pageLoadStrategy=normal, unhandledPromptBehavior=, databaseEnabled=false, handlesAlerts=true, version=61.0.3163.100, browserConnectionEnabled=false, nativeEvents=true, locationContextEnabled=true, cssSelectorsEnabled=true}]
Session ID: 56736000202256f355f9115578021933
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:607)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:643)
    at org.openqa.selenium.remote.RemoteWebDriver.quit(RemoteWebDriver.java:482)
    at com.automationpanda.example.stepdefs.GoogleSearchSteps.lambda$new$5(GoogleSearchSteps.java:42)
    at cucumber.runtime.java8.Java8HookDefinition.lambda$execute$0(Java8HookDefinition.java:49)
    at cucumber.runtime.Timeout.timeout(Timeout.java:16)
    at cucumber.runtime.java8.Java8HookDefinition.execute(Java8HookDefinition.java:47)
    at cucumber.runtime.HookDefinitionMatch.runStep(HookDefinitionMatch.java:17)
    at cucumber.runner.UnskipableStep.executeStep(UnskipableStep.java:22)
    at cucumber.api.TestStep.run(TestStep.java:83)
    at cucumber.api.TestCase.run(TestCase.java:58)
    at cucumber.runner.Runner.runPickle(Runner.java:80)
    at cucumber.runtime.junit.PickleRunners$NoStepDescriptions.run(PickleRunners.java:140)
    at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:68)
    at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:23)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:73)
    at cucumber.api.junit.Cucumber.runChild(Cucumber.java:99)
    at cucumber.api.junit.Cucumber.runChild(Cucumber.java:41)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at cucumber.api.junit.Cucumber$1.evaluate(Cucumber.java:108)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.lang.RuntimeException: java.lang.InterruptedException
    at org.openqa.selenium.net.UrlChecker.waitUntilUnavailable(UrlChecker.java:145)
    at org.openqa.selenium.remote.service.DriverService.stop(DriverService.java:213)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:95)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:586)
    ... 42 more
Caused by: java.lang.InterruptedException
    at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:404)
    at java.util.concurrent.FutureTask.get(FutureTask.java:204)
    at com.google.common.util.concurrent.SimpleTimeLimiter.callWithTimeout(SimpleTimeLimiter.java:147)
    at org.openqa.selenium.net.UrlChecker.waitUntilUnavailable(UrlChecker.java:115)
    ... 45 more

Failed scenarios:
src/test/resources/com/automationpanda/example/features/GoogleSearch.feature:7 # Simple Google search

1 Scenarios (1 failed)
3 Steps (3 passed)
0m6.814s
mpkorstanje commented 7 years ago

Please note that these are not identical:

Before(new String[]{"@web"}, 1000, 1, (Scenario scenario) -> {
    driver = new ChromeDriver();
});

@Before(value = "@web", order = 1)
public void initWebDriver() throws Throwable {
    driver = new ChromeDriver();
}

The lambda step definition includes a timeout while the annotation step definition does not. So as a work around I would suggest not using the timeout by setting it to 0.

I also can not reproduce your problem consistently from the provided sample. These two in combination with the stack trace provide a hint towards the underlying issue. The stack trace suggests that while shutting down the web driver the currently executing thread was either interrupted or already in an interrupted state.

The Java8HookDefinition uses Timeout to wrap the lambda invocation in a timeout. And suppose that starting up chrome took about 1000ms - not unreasonable on a regular machine - then it would be reasonable to conclude that there is a race condition in Timeout.

And looking at the code I am quite certain there is.

final Thread executionThread = Thread.currentThread();
final AtomicBoolean done = new AtomicBoolean();

ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> timer = executorService.schedule(new Runnable() {
    @Override
    public void run() {
        if (!done.get()) {
            executionThread.interrupt();
        }
    }
}, timeoutMillis, TimeUnit.MILLISECONDS);
try {
    return callback.call();
} catch (InterruptedException timeout) {
    throw new TimeoutException("Timed out after " + timeoutMillis + "ms.");
} finally {
    done.set(true);
    timer.cancel(true);
    executorService.shutdownNow();
}

}

While done is an atomic boolean, there is a race condition between the timer and the executionThread. E.g. the executionThread completes handling the call back without being interrupted and enters the finally block. The timer takes over and notices that done has not been set and interrupts the executionThread. The executionThread then sets done to true and continues with the next step.

AndyLPK247 commented 7 years ago

Changing the timeout to 0 resolved the issue. Thanks!

lock[bot] commented 6 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.