0

For our BDD tests we use Specflow that talks to selenium 2 webdriver (Chrome driver in this instance).

While running on local host (Yes, "it works on my machine" has came up in conversation a few times) the tests work fine. They setup the data and a new webdriver, do the test and then tear down the webdriver and data. Even if a test goes horribly wrong because I'm using correct attributes the tear down is always hit and therefore driver.Quit() is run destroying the browser and the driver.

The problem arises when I run it on our server [Windows Server 2008 r2] using our continuous integration [TeamCity]. For some reason it will start to run multiple driver instances which cause the tests to fail.

Has anyone ran into this problem before and found a fix? We need a solution that uses a driver that isn't HtmlUnitDriver.

Extra information:

  • Language = C#
  • Server = Windows Server 2008 R2
  • CI = TeamCity

EDIT: The Webdriver is set up by making sure that it isn't already created and then creates a new instance of the ChromeDriver. Pseudo/real code example bellow shows how its set up, sorry I cant show the full code as it has to much fluff in that we use for other options that we stick in (e.g zap or fiddler integration / language changes etc).

Setup

[SetUp]
[BeforeScenario()]
public static void BeforeWebScenario()
{
   if driver == null
     driver = new ChromeDriver();
   // Code to start page
}

Tear down

[TearDown]
[AfterScenario()]
public static void AfterWebScenario()
{
   try
   {
       driver.Quit();
   } catch (Exception)
   {
       throw Exception
   }
   driver = null;
}
3
  • Can you give a sample test that reproduces this? Commented Jun 6, 2012 at 10:28
  • Two questions: First, how are you starting the driver, by using ChromeDriver or RemoteWebDriver? Second, what does a typical constructor for the driver for your test look like? Commented Jun 6, 2012 at 11:32
  • Hi thanks for the interest, its quite difficult to give an example test as they use a framework I've created and operate the page object model (There's a lot of abstraction). I'll edit the post to show how the driver is set up. Commented Jun 6, 2012 at 12:15

2 Answers 2

1

I had this problem too. I fixed it by killing any running instances of chromedriver.exe in my testSetup() method. I used a VBScript and some Groovy code to run the scripts. Sorry this answer is kind of long.

I had this in my setUp):

if (wshsc.isRunningByCommandLineContents("chromedriver.exe"))
    wshsc.killProcessByCommandLineContents("chromedriver.exe")

isRunningByCommandLineContents:

If WScript.Arguments.Count = 1 Then

strCmdLine = WScript.Arguments.Item(0)
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objShell = CreateObject("WScript.Shell")
Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process")
If colProcessList.Count > 0 Then
    For Each objItem in colProcessList
        If (InStr(objItem.CommandLine, strCmdLine)) Then
            If (InStr(objItem.CommandLine, "cscript")) Then
            Else
                WScript.StdOut.Write "A process is running with " + strCmdLine + " in its command line = " + objItem.Name
            End If  
        End If
    Next
End If
End If

killProcessByCommandLineContents:

If WScript.Arguments.Count = 1 Then
strProcess = WScript.Arguments.Item(0)
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objShell = CreateObject("WScript.Shell")
Set colProcessList = objWMIService.ExecQuery _
    ("Select * from Win32_Process")

If colProcessList.Count > 0 Then
    For Each objItem in colProcessList
        If InStr(objItem.CommandLine, strProcess) Then
            If (InStr(objItem.CommandLine, "cscript")) Then
            Else
                WScript.StdOut.Write objItem.Name + " "
                objItem.Terminate()
            End If
        End If
    Next
Else
    WScript.StdOut.Write "No instances found running"
End If
Else
WScript.StdOut.Write "Bad Arguments"
End If

And the "run the scripts part":

public void killProcessByCommandLineContents(String contents) {
    List<String> arg = new ArrayList<String>()
    arg.add(contents)
    String [] args = arg.toArray()
    runScript("killByCmdLineContents.vbs", args, true)
}
public boolean isRunningByCommandLineContents(String contents) {
    List<String> arg = new ArrayList<String>()
    arg.add(contents)
    String [] args = arg.toArray()
    String returnData = runScript("IsRunningByCmdLineContents.vbs", args, true)
    if (returnData.contains(contents)) {
        return true
    } else {
        return false 
    }
}
public String runScript(String name, String [] args, boolean returnOutput) {
    String s = null;
    List<String> cmdLine = new ArrayList<String>()
    cmdLine.add("C://Windows//System32//cscript.exe")
    cmdLine.add(dir + "dir//src//com//misc//wshScripts//" + name)
    int index = 0
    args.each() {
        cmdLine.add(args[index])
        index++
    }

    try {
        String [] cmdLineArray = cmdLine.toArray()
        Process p = Runtime.getRuntime().exec(cmdLineArray, null);
        if (returnOutput) {
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
            BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            String dataToReturn
            Log.logger.info("Standard output: ");
            while ((s = stdInput.readLine()) != null) {
                Log.logger.info(s)
                dataToReturn = s // should get last line
            }

            Log.logger.info("Standard error: ");
            while ((s = stdError.readLine()) != null) {Log.logger.info(s);}
            return dataToReturn
        } else {
            return ""
        }
    }
    catch (IOException e) {
        Log.logger.info(e.message, e);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this seems like it could fix the problem, at least until I find out why its creating them to begin with. I'll run our over night build tonight and get back to you tomorrow with the results. Thanks
Thanks this helped me to identify the real problem (I've also kept it in as a nice tidy up). I was getting "OpenQA.Selenium.WebDriverException : No response from server for url" on the build server. When I looked in to this it seems that any time after using .FindElement(obj) you should do a Thread.Sleep(200) as there's some kind of race condition going on if too many find's are called.
0

If you use the DriverService interface, hold onto the service until you're done with the driver, and call DriverService.stop() as well. For me, the driver.quit() wasn't enough because I was using DriverService as well.

driver.close();
driver.quit();
driverService.stop();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.