javaseleniumdockerremotewebdriver

RemoteWebDriver - Debugging headless docker containers


Currently I am running a RemoteWebDriver through a docker instance, however I am struggling to debug this because the browser doesn't open so I can see it on my machine.

Here it the code that creates a driver - for some reason its always running in headless mode

public void createDriver() throws MalformedURLException {
    String browser = propertyReader.readProperty("browserType");
    String opSys = getOS();
    String remoteDriverURL = propertyReader.readProperty("remoteWebDriverLocation");

    if (Objects.equals(opSys, "win")) {
        switch (browser) {
            case "firefox":
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), firefoxCap);
                webDriver.manage().window().setSize(new Dimension(1600, 900));
            case "ie": {
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), ieCap);
                webDriver.manage().window().setSize(new Dimension(1600, 900));
                return;
            }
            case "headless":
                chromeCap.setCapability("headlesss", true);
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), chromeCap);
            default: {
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), chromeCap);
                webDriver.manage().window().setSize(new Dimension(1600, 900));
            }
        }
    } else {
        switch (browser) {
            case "firefox":
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), firefoxCap);
                webDriver.manage().window().setSize(new Dimension(1600, 900));
            case "safari":
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), safariCap);
                webDriver.manage().window().setSize(new Dimension(1600, 900));
            case "headless":
                chromeCap.setCapability("acceptInsecureCerts", true);
                chromeCap.setCapability("acceptSslCerts", true);
                chromeCap.setCapability("headless", true);
                chromeCap.setCapability("window-size=1920,1080", true);
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), chromeCap);
            default:
                this.webDriver = new RemoteWebDriver(new URL(remoteDriverURL), chromeCap);
                webDriver.manage().window().setSize(new Dimension(1600, 900));
        }
    }

}

Is there anything which we can config so we can see the browser when running?


Solution

  • I'm approaching this assuming your are running selenium/hub, selenium/node-firefox, selenium/node-chrome. These are linux based images.

    If you are running node-chrome and node-firefox, you want to change them to node-chrome-debug and node-firefox-debug, these versions come with VNC Server running on port 5900. I use docker-compose, and created a separate docker-compose-debug.yml for this type of issue:

    version: "3"
    services:
      selenium-hub:
        image: selenium/hub
        container_name: selenium-hub
        ports:
          - "4444:4444"
      chrome:
        image: selenium/node-chrome-debug
        container_name: node-chrome-debug
        depends_on:
          - selenium-hub
        environment:
          - HUB_PORT_4444_TCP_ADDR=selenium-hub
          - HUB_PORT_4444_TCP_PORT=4444
        volumes:
          - /dev/shm:/dev/shm
        ports:
          - "5901:5900"
      firefox:
        image: selenium/node-firefox-debug
        container_name: node-firefox-debug
        depends_on:
          - selenium-hub
        environment:
          - HUB_PORT_4444_TCP_ADDR=selenium-hub
          - HUB_PORT_4444_TCP_PORT=4444
        volumes:
          - /dev/shm:/dev/shm
        ports:
          - "5902:5900"
    

    NOTE: the ports 5901:5900 and 5902:5900, these allow you to use VNC Client to connect to these nodes.

    docker-compose -f docker-compose-debug.yml up
    

    Basically, your nodes are headless but they still need something to simulate the browser gui, inside the container xvfb takes care of this for you. The debug versions of the nodes run a VNC Server which connects to xvfb. You run a VNC Client to connect to the VNC Server.

    You will need a VNC Client, a popular version is RealVNC, download and install it on your machine. Put it where you like, make it executable and run it. I call mine vncview

    >./vncview
    

    This will launch a gui, you will give it an ip:port for the node you want to look at. e.g 127.0.0.1:5901 (my chrome debug) or 127.0.0.1:5902 (my ff debug) password is "secret" - you will see the ubuntu logo. You can run two of these at the same time since we have assigned different ports.

    Now just run your tests ;-)

    I've edited this answer to include the following:

    Chrome has the ability to go completely Headless by using the --headless option, you have used this.

    Selenium docker images run "headless" by default, containers have no display, xvfb is used to handle this. Xvfb fakes out the ui by creating/using a display buffer that never gets displayed.

    Running chrome --headless on node-chrome, causes nothing to be sent to xvfb. So, if you later want to see what is happening just for debugging you can't.

    You will need to remove the --headless option. This is not a disaster, as the docker selenium/node-chrome image defaults to "essentially" headless. I don't know if there is a time savings by using --headless on the docker image.

    also see:

    Getting Started with Headless Chrome

    Selenium Grid with Docker - lots of details with graphics

    docker-selenium debugging

    Running Chrome in a Docker container

    Goolge terms: XVNC or VNC(virtual network computing) and XVFB (x vritural frame buffer)