Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

phantomjs not closing and leaving orphan processes

On PhantomJS 1.9.2, ubuntu 12 LTS and Ghostdirver 1.04 together with selenium 2.35 I get dangling phantomjs processes after my tests. Anyone knows a good way how to fix this?

Here is a test program that demonstrates the odd behavior:

package testing;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;

public class PhantomIsNotKilledDemo {

    private static WebDriver getDriver(){
        String browserPathStr = System.getProperty("selenium.pathToBrowser");
        if (browserPathStr == null) browserPathStr = "/home/user1/apps/phantomjs/bin/phantomjs";

        DesiredCapabilities caps = DesiredCapabilities.phantomjs();

        caps.setCapability("takesScreenshot", true);
        caps.setCapability(
                PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
                browserPathStr );

        WebDriver driver = new PhantomJSDriver(caps);

        return driver;
    }

    public static void main(String[] args) {
        int max = 10;
        for (int i = 0; i < max; i++){
            WebDriver d1 = getDriver();
            d1.get("http://www.imdb.com/title/tt1951264");

            System.out.println("done with cycle " + (i+1) +" of "+max);
            d1.close();
            //d1.quit();
        }

        System.out.println("done");
        System.exit(0);
    }
}

To run this, you should supply the path of your phantomjs binary as system property or set the variable accordingly.

After letting this run I do this shell command

ps -ef | grep phantomjs

and find 10 dangling phantomjs processes.

If I use d1.quit() instead, I end up with no dangling process. This is clearly better, but still I would have expected to get the same result with .close.

Note, this is a crosspost of https://github.com/detro/ghostdriver/issues/162#issuecomment-25536311

Update This post is changed according to Richard's suggestion (see below).

like image 612
luksch Avatar asked Oct 02 '13 14:10

luksch


2 Answers

You should be using quit() to terminate the process instead of close().

As you have discovered, close will close the current window (and browser), but it will not shut down the process. This is useful for if you are going to send additional commands to the process or want to inspect the process.

Quit is for when you want to close every window and stop the process, which sounds like what you are looking for.

The documentation for these two methods reads:

close()

Close the current window, quitting the browser if it's the last window currently open.

quit()

Quits this driver, closing every associated window.

like image 159
Ryan Guest Avatar answered Jan 05 '23 03:01

Ryan Guest


I'd rewrite your code to something like this:

public static void main(String[] args) {
    int max = 10;
    for (int i = 0; i < max; i++){
        WebDriver d1 = getDriver();

        d1.get("http://www.imdb.com/title/tt1951264");

        System.out.println("done with cycle " + (i+1) +" of "+max);
        d1.quit();
    }

    System.out.println("done");
    System.exit(0);
}

I'm not entirely sure why the .close() is not ending the WebDriver. In theory, .close() should quit WebDriver if it is called on the last open window. Perhaps something is opening a second window when that url is called? Or maybe .close() works differently for phantomjs.

As to why .quit() isn't closing all of the phantomjs sessions, the last getDriver() you're calling does not have a corresponding .quit() outside of the loop. I restructured your for loop to create the instance of WebDriver, perform your test, then .quit() that session of WebDriver/phantomjs at the end of each loop.

like image 21
Richard Avatar answered Jan 05 '23 03:01

Richard