Selenium Grid 并行执行 ThreadLocal WebDriver SessionNotCreatedException:无法创建新服务:GeckoDriverService

Selenium Grid Parallel Execution ThreadLocal WebDriver SessionNotCreatedException: Unable to create new service: GeckoDriverService

运行 使用 selenium 网格在 windows 节点和 mac 节点上并行测试将通过所有测试但无法通过 运行 并跳过第一个测试 FilterMoreResultsBySquareFeet对于 Mac Firefox 浏览器或 Windows Firefox 浏览器。它不断抛出这个错误 org.openqa.selenium.SessionNotCreatedException: 无法创建新服务:GeckoDriverService 我正在使用最新的 java、最新的 selenium 驱动程序、最新的浏览器驱动程序和最新的浏览器版本。我的所有驱动程序都在我启动 json selenium 网格文件的同一个文件夹中,我的代码系统 属性 指向同一个文件夹。我还在 windows 和 mac 的环境变量路径中设置了文件夹。有没有人遇到过这个错误,你是怎么解决的?

  public class TestBase {
       private static ThreadLocal<WebDriver> driverThread = new ThreadLocal<>();

    public static String whichNodeURL = "";
    public static String nodeURL = "http://xxxx:4444/wd/hub";
    public static String macNodeURL = "http://xxxx:5555/wd/hub";
    public static String winNodeURL = "http://xxxx:5554/wd/hub";

    DesiredCapabilities capabilities = new DesiredCapabilities();

    @SuppressWarnings({ "rawtypes"})
    @BeforeMethod (alwaysRun=true)
    //Use before method instead of before class or before test so each method/test will open in new browser; 
    //This was tested and found before method was the only one that works.
        @Parameters("browser")
    public final void setDriver(String browser) throws IOException, InterruptedException{

            ReadProperties.retrieveGlobalProperties();

        if (ReadProperties.globalProp.getProperty("webautomation").contains("yes") && ReadProperties.globalProp.getProperty("mobileautomation").contains("no"))
        {
            if(browser.contains("winfirefox"))
            {

                System.setProperty("webdriver.gecko.driver", ReadProperties.globalProp.getProperty("pcgeckodriver"));
                FirefoxOptions firefoxOptions = new FirefoxOptions();
                firefoxOptions.setCapability("platform", "WINDOWS");
                firefoxOptions.setCapability("browser", "firefox");
                firefoxOptions.setCapability("newCommandTimeout", 5000);
                firefoxOptions.setCapability(FirefoxDriver.MARIONETTE, true);
                firefoxOptions.setBinary("C:\Program Files\Mozilla Firefox\firefox.exe");    
                whichNodeURL=winNodeURL;    
                try
                {
                    driverThread.set(new RemoteWebDriver(new URL(whichNodeURL), firefoxOptions));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }


            }
            else if(browser.contains("macfirefox"))
            {
                System.setProperty("webdriver.gecko.driver", ReadProperties.globalProp.getProperty("macgeckodriver"));
                FirefoxOptions macfirefoxOptions = new FirefoxOptions();
                macfirefoxOptions.setCapability("platform", "MAC");
                macfirefoxOptions.setCapability("browser", "firefox");
                macfirefoxOptions.setCapability("newCommandTimeout", 5000);
                macfirefoxOptions.setCapability(FirefoxDriver.MARIONETTE, true);
                macfirefoxOptions.setBinary("/Applications/Firefox.app/Contents/MacOS/firefox-bin");
                whichNodeURL=macNodeURL;

                try
                {
                    driverThread.set(new RemoteWebDriver(new URL(whichNodeURL), macfirefoxOptions));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }


            }
            else if (browser.contains("winchrome"))
            {
                System.setProperty("webdriver.chrome.driver", ReadProperties.globalProp.getProperty("pcchromedriver"));
                ChromeOptions chromeOptions = new ChromeOptions();
                chromeOptions.setCapability("platform", "WINDOWS");
                chromeOptions.setCapability("browser", "chrome");
                chromeOptions.setCapability("newCommandTimeout", 5000);
                whichNodeURL=winNodeURL;

                try
                {
                    driverThread.set(new RemoteWebDriver(new URL(whichNodeURL), chromeOptions));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }

            }
            else if (browser.contains("macchrome"))
            {
                System.setProperty("webdriver.chrome.driver", ReadProperties.globalProp.getProperty("macchromedriver"));
                ChromeOptions macchromeOptions = new ChromeOptions();
                macchromeOptions.setCapability("platform", "MAC");
                macchromeOptions.setCapability("browser", "chrome");
                macchromeOptions.setCapability("newCommandTimeout", 5000);
                whichNodeURL=macNodeURL;

                try
                {
                    driverThread.set(new RemoteWebDriver(new URL(whichNodeURL), macchromeOptions));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }

            }
                String weburl = ReadProperties.globalProp.getProperty("weburl");
                this.driverThread.get().get(weburl);
                Thread.sleep(1000);
                this.driverThread.get().manage().window().maximize(); 
                Thread.sleep(1000);
           }
      }
    }
        public static WebDriver getDriver() {
        return driverThread.get();
    }
        @AfterMethod(alwaysRun=true) 
    public static void OnFailure(ITestResult testResult) throws IOException { 
        if (testResult.getStatus() == ITestResult.FAILURE) 
        { 
            System.out.println(testResult.getStatus()); 
        } 
    } 


@AfterMethod(alwaysRun=true)
//Use after method instead of after class or after test so each method/test will open in new browser; 
//This was tested and found after method was the only one that works.   
public void tearDown() {

        getDriver().quit();
}
}






  public class FilterMoreResultsBySquareFeet extends TestBase{

 static SoftAssert softAssert = new SoftAssert();
 final static Logger log = 
 LogManager.getLogger(FilterMoreResultsBySquareFeet.class);


static String className = 
FilterMoreResultsBySquareFeet.class.getSimpleName();
static Date date1= new Date();
static String originaltimestamp = new Timestamp(date1.getTime()).toString();
static String timestamp = originaltimestamp.replace(':', 'x').substring(11);
static String foldername = className+timestamp;
static String errorname = "";

  @Parameters("browser")
@Test(groups= {"smoke", "regression"}, dataProvider = "getData") 
public void filterResultsBySqFeet (String searchkeyword, String minsqfeet, String maxsqfeet) throws IOException, InterruptedException
{
    WebDriver webdriver = getDriver();
    Search.searchByCity(webdriver, searchkeyword);
    FilterMoreResults_Page.clickOpenMoreFilters(webdriver);
    FilterMoreResults_Page.filterBySqFeet(webdriver, minsqfeet, maxsqfeet);
    FilterMoreResults_Page.applyMoreFilters(webdriver);
    String diditfilter = FilterMoreResults_Page.verifyFilterBySqFeet(webdriver, minsqfeet, maxsqfeet);

    try{
        Assert.assertEquals(diditfilter, "yes");
    } 
    catch(AssertionError e)
    { 
        log.error("Didn't filter by square feet.", e.getMessage());
        errorname = "didntfilterbysqft";
        ScreenshotURL.screenshotURL(webdriver, foldername, errorname);
        softAssert.fail();
    }

       softAssert.assertAll();

}


  TESTNG FILE
  <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="XOME Suite" parallel="tests" verbose="10" thread-count="2">

<test name = "Win Firefox Tests" preserve-order="true" group-by-instances="true">
<parameter name="browser" value="winfirefox">
    <classes>
    <class name="webTests.FilterMoreResultsBySquareFeet" />
        <class name="webTests.FilterMoreResultsByKeyword" />
        <class name="webTests.FilterMoreResultsByYear" />
    </classes>
</parameter>
</test>

<test name = "Mac Firefox Tests" preserve-order="true" group-by-instances="true">
<parameter name="browser" value="macfirefox">
    <classes>
    <class name="webTests.FilterMoreResultsBySquareFeet" />
        <class name="webTests.FilterMoreResultsByKeyword" />
        <class name="webTests.FilterMoreResultsByYear" />
    </classes>
</parameter>
</test>

<test name = "Win Chrome Tests" preserve-order="true" group-by-instances="true">
<parameter name="browser" value="winchrome">
    <classes>
    <class name="webTests.FilterMoreResultsBySquareFeet" />
        <class name="webTests.FilterMoreResultsByKeyword" />
        <class name="webTests.FilterMoreResultsByYear" />
    </classes>
</parameter>
</test>
<test name = "Mac Chrome Tests" preserve-order="true" group-by-instances="true">
<parameter name="browser" value="macchrome">
    <classes>
    <class name="webTests.FilterMoreResultsBySquareFeet" />
        <class name="webTests.FilterMoreResultsByKeyword" />
    <class name="webTests.FilterMoreResultsByYear" />
    </classes>
</parameter>
</test>

 macnode.json
 {
  "capabilities":
 [
  {
  "browserName": "firefox",
  "marionette": true,
  "maxInstances": 1,
  "version": 66,
  "platform": "MAC",
  "seleniumProtocol": "WebDriver"
},
{
  "browserName": "chrome",
  "maxInstances": 1,
  "version": 73,
  "platform": "MAC",
  "seleniumProtocol": "WebDriver"
},
{
  "browserName": "safari",
  "technologyPreview": false,
  "platform": "MAC",
  "maxInstances": 1,
  "seleniumProtocol": "WebDriver"
}
],
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"maxSession": 1,
"port": 5555,
"register": true,
"registerCycle": 5000,
"hub": "http://xxxx:4444",
"nodeStatusCheckTimeout": 5000,
"nodePolling": 5000,
"role": "node",
"cleanUpCycle": 5000,
"timeout": 5000,
"unregisterIfStillDownAfter": 60000,
"downPollingLimit": 2,
"debug": false,
"servlets" : [],
"withoutServlets": [],
"custom": {}
}

hub.json
{
"host": null,
"port": 4444,
"newSessionWaitTimeout": -1,
"servlets" : [],
"prioritizer": null,
"capabilityMatcher": 
"org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
"throwOnCapabilityNotPresent": true,
"nodePolling": 5000,
"cleanUpCycle": 5000,
"timeout": 300000,
"browserTimeout": 0,
"maxSession": 1
}

java -jar selenium-server-standalone-3.141.59.jar -role hub -hubConfig Hub.json

java -Dwebdriver.chrome.driver="C:\seleniumgrid\chromedriver.exe" -Dwebdriver.gecko.driver="C:\seleniumgrid\geckodriver.exe" -Dwebdriver.ie.driver="C:\seleniumgrid\IEDriverServer.exe" -Dwebdriver.edge.driver="C:\seleniumgrid\MicrosoftWebDriver.exe" -jar C:\\seleniumgrid\\selenium-server-standalone-3.141.59.jar -角色节点 -nodeConfig C:\\seleniumgrid\\WindowsNode.json

java -Dwebdriver.chrome.driver="/Users/abc/seleniumgrid/chromedriver" -Dwebdriver.gecko.driver="/Users/abc/seleniumgrid/geckodriver" -jar /Users/abc/seleniumgrid/selenium-server-standalone-3.141.59.jar -角色节点 -nodeConfig /Users/abc/seleniumgrid/MacNode.json

org.openqa.selenium.SessionNotCreatedException: Unable to create new service: GeckoDriverService

构建信息:版本:'3.141.59',修订:'e82be7d358',时间:'2018-11-14T08:25:53' 系统信息:host: 'abc-MacBook-Pro.local', ip: '2606:6000:fccc:1e00:0:0:0:6%en0', os.name: 'Mac OS X', os.arch : 'x86_64', os.version: '10.14.4', java.version: '1.8.0_212' 驱动程序信息:driver.version:未知 命令持续时间或超时:155 毫秒 在 org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214) 在 org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166) 在 org.openqa.selenium.remote.JsonWireProtocolResponse.lambda$errorHandler$0(JsonWireProtocolResponse.java:54) 在 org.openqa.selenium.remote.HandshakeResponse.lambda$getResponseFunction$0(HandshakeResponse.java:30) 在 org.openqa.selenium.remote.ProtocolHandshake.lambda$createSession$0(ProtocolHandshake.java:126) 在 java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 在 java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958) 在 java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) 在 java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) 在 java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) 在 java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) 在 java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在 java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464) 在 org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:128) 在 org.openqa.selenium.remote.ProtocolHandshake.createSession(ProtocolHandshake.java:74) 在 org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:136) 在 org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552) 在 org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:213) 在 org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:131) 在 org.openqa.selenium.remote.RemoteWebDriver.(RemoteWebDriver.java:144) 在 base.TestBase.setDriver(TestBase.java:98) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 java.lang.Thread.run(Thread.java:748) 原因:org.openqa.selenium.SessionNotCreatedException:无法创建新服务:GeckoDriverService 构建信息:版本:'3.141.59',修订:'e82be7d358',时间:'2018-11-14T08:25:53' 系统信息:host: 'abc-MacBook-Pro.local', ip: '2606:6000:fccc:1e00:0:0:0:6%en0', os.name: 'Mac OS X', os.arch : 'x86_64', os.version: '10.14.4', java.version: '1.8.0_212' 驱动程序信息:driver.version:未知 构建信息:版本:'3.141.59',修订:'e82be7d358',时间:'2018-11-14T08:17:03' 系统信息:host: 'abc-MacBook-Pro.local', ip: '2606:6000:fccc:1e00:0:0:0:6%en0', os.name: 'Mac OS X', os.arch : 'x86_64', os.version: '10.14.4', java.version: '1.8.0_212' 驱动程序信息:driver.version:未知 在 org.openqa.selenium.grid.session.remote.ServicedSession$Factory.lambda$get$0(ServicedSession.java:135) 在 org.openqa.selenium.grid.session.remote.ServicedSession$Factory.apply(ServicedSession.java:152) 在 org.openqa.selenium.remote.server.ActiveSessionFactory.lambda$apply$12(ActiveSessionFactory.java:180) 在 java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 在 java.util.stream.ReferencePipeline$11$1.accept(ReferencePipeline.java:373) 在 java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 在 java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958) 在 java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) 在 java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) 在 java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) 在 java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) 在 java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在 java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464) 在 org.openqa.selenium.remote.server.ActiveSessionFactory.apply(ActiveSessionFactory.java:183) 在 org.openqa.selenium.remote.server.NewSessionPipeline.lambda$null$2(NewSessionPipeline.java:66) 在 java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 在 java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 在 java.util.Collections$2.tryAdvance(Collections.java:4717) 在 java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) 在 java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) 在 java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) 在 java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) 在 java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在 java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464) 在 org.openqa.selenium.remote.server.NewSessionPipeline.lambda$createNewSession$3(NewSessionPipeline.java:69) 在 java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 在 java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 在 java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 在 java.util.stream.DistinctOps$1$2.accept(DistinctOps.java:175) 在 java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 在 java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) 在 java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) 在 java.util.stream.Streams$StreamBuilderImpl.tryAdvance(Streams.java:405) 在 java.util.stream.Streams$ConcatSpliterator.tryAdvance(Streams.java:728) 在 java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) 在 java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) 在 java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) 在 java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) 在 java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) 在 java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:464) 在 org.openqa.selenium.remote.server.NewSessionPipeline.createNewSession(NewSessionPipeline.java:72) 在 org.openqa.selenium.remote.server.commandhandler.BeginSession.execute(BeginSession.java:65) 在 org.openqa.selenium.remote.server.WebDriverServlet.lambda$handle$0(WebDriverServlet.java:235) ... 还有 5 个 ... 删除了 16 个堆栈帧

[错误] 测试 运行:10,失败:2,错误:0,跳过:1,经过的时间:287.762 秒 <<< 失败! - 在测试套件中 [错误] setDriver(webTests.FilterMoreResultsBySquareFeet) 已用时间:6.55 秒 <<< 失败! org.openqa.selenium.SessionNotCreatedException: 无法创建新服务:GeckoDriverService 构建信息:版本:'3.141.59',修订:'e82be7d358',时间:'2018-11-14T08:25:53' 系统信息:host: 'abc-MacBook-Pro.local', ip: '2606:6000:fccc:1e00:0:0:0:6%en0', os.name: 'Mac OS X', os.arch : 'x86_64', os.version: '10.14.4', java.version: '1.8.0_212' 驱动程序信息:driver.version:未知 命令持续时间或超时:84 毫秒 原因:org.openqa.selenium.SessionNotCreatedException: 无法创建新服务:GeckoDriverService 构建信息:版本:'3.141.59',修订:'e82be7d358',时间:'2018-11-14T08:25:53' 系统信息:host: 'abc-MacBook-Pro.local', ip: '2606:6000:fccc:1e00:0:0:0:6%en0', os.name: 'Mac OS X', os.arch : 'x86_64', os.version: '10.14.4', java.version: '1.8.0_212' 驱动程序信息:driver.version:未知 构建信息:版本:'3.141.59',修订:'e82be7d358',时间:'2018-11-14T08:17:03' 系统信息:host: 'abc-MacBook-Pro.local', ip: '2606:6000:fccc:1e00:0:0:0:6%en0', os.name: 'Mac OS X', os.arch : 'x86_64', os.version: '10.14.4', java.version: '1.8.0_212' 驱动程序信息:driver.version:未知

Ok after struggling with it for several days and trying everything, I got it to work. Hope this helps someone too. There wasn't much info out there on solving this error and the error didn't tell me much where it was wrong.
Here's what I changed.
1. Use the hub url for creating your remotewebdriver for each browser and do not use the node url.
    public static String nodeURL = "http://xxxx:4444/wd/hub";
    public static String macNodeURL = "http://xxxx:4444/wd/hub";
    public static String winNodeURL = "http://xxxx:4444/wd/hub";
2. Add this to the node json files 

        {
      "browserName": "firefox",
      "marionette": true,
      "maxInstances": 1,
      "version": 66,
      "platform": "WINDOWS",
      "seleniumProtocol": "WebDriver",
      "webdriver.gecko.driver": "C:/seleniumgrid/geckodriver.exe",
      "binary":"C:/Program Files/Mozilla Firefox/firefox.exe"
    },

        {
      "browserName": "firefox",
      "marionette": true,
      "maxInstances": 1,
      "version": 66,
      "platform": "MAC",
      "seleniumProtocol": "WebDriver",
      "webdriver.gecko.driver": "/Users/angee/seleniumgrid/geckodriver",
      "binary": "/Applications/Firefox.app/Contents/MacOS/firefox-bin"
    },


3. Set this in your code 
firefoxOptions.setBinary("C:/Program Files/Mozilla Firefox/firefox.exe");
                    macfirefoxOptions.setBinary("/Applications/Firefox.app/Contents/MacOS/firefox-bin");