223

I have a Selenium test suite that runs many tests and on each new test it opens a browser window on top of any other windows I have open. Very jarring while working in a local environment. Is there a way to tell Selenium or the OS (Mac) to open the windows in the background?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kevzettler
  • 4,783
  • 15
  • 58
  • 103

18 Answers18

230

If you are using Selenium web driver with Python, you can use PyVirtualDisplay, a Python wrapper for Xvfb and Xephyr.

PyVirtualDisplay needs Xvfb as a dependency. On Ubuntu, first install Xvfb:

sudo apt-get install xvfb

Then install PyVirtualDisplay from PyPI:

pip install pyvirtualdisplay

Sample Selenium script in Python in a headless mode with PyVirtualDisplay:

    #!/usr/bin/env python

    from pyvirtualdisplay import Display
    from selenium import webdriver

    display = Display(visible=0, size=(800, 600))
    display.start()

    # Now Firefox will run in a virtual display.
    # You will not see the browser.
    browser = webdriver.Firefox()
    browser.get('http://www.google.com')
    print browser.title
    browser.quit()

    display.stop()

EDIT

The initial answer was posted in 2014 and now we are at the cusp of 2018. Like everything else, browsers have also advanced. Chrome has a completely headless version now which eliminates the need to use any third-party libraries to hide the UI window. Sample code is as follows:

    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options

    CHROME_PATH = '/usr/bin/google-chrome'
    CHROMEDRIVER_PATH = '/usr/bin/chromedriver'
    WINDOW_SIZE = "1920,1080"

    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
    chrome_options.binary_location = CHROME_PATH

    driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH,
                              chrome_options=chrome_options
                             )
    driver.get("https://www.google.com")
    driver.get_screenshot_as_file("capture.png")
    driver.close()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Amistad
  • 7,100
  • 13
  • 48
  • 75
  • 11
    Is it available for Mac OSX? – vanguard69 Jul 19 '15 at 12:44
  • This is great if you're using Ubuntu and your test suite is in Python – kevzettler Feb 10 '16 at 23:08
  • See this.http://stackoverflow.com/questions/944086/is-there-anything-like-xvfb-or-xnest-for-windows – Amistad Jul 26 '16 at 12:21
  • Is this possible in Java? – Ali Hesari Apr 28 '17 at 13:22
  • The only python specific library for this setup to work is PyvirtualDisplay..if you can find some alternative for that in Java, this will work.. – Amistad Apr 29 '17 at 14:54
  • I know this is an old thread, but is there any such method of Safari? – Anubhav Dinkar Sep 15 '19 at 15:07
  • 5
    the use of chrome_options is deprecated, now is just options – Mojimi Mar 11 '20 at 17:53
  • In the edited answer, note that when instanciating Chrome in headless mode is important to set the window-size, as the responder doing. In fact, in headless mode, the default windows size is much smaller than the size in the standard mode, and so the website you are loading may be loaded in a "mobile phone" version which changes the DOM of the page – robertspierre Nov 29 '20 at 23:32
  • See [this answer](https://stackoverflow.com/a/15663596/5267751) for an option which only uses Xvfb (without any additional Python package) -- so for example it would be usable on java. – user202729 Dec 22 '20 at 01:57
74

There are a few ways, but it isn't a simple "set a configuration value". Unless you invest in a headless browser, which doesn't suit everyone's requirements, it is a little bit of a hack:

How to hide Firefox window (Selenium WebDriver)?

and

Is it possible to hide the browser in Selenium RC?

You can 'supposedly', pass in some parameters into Chrome, specifically: --no-startup-window

Note that for some browsers, especially Internet Explorer, it will hurt your tests to not have it run in focus.

You can also hack about a bit with AutoIt, to hide the window once it's opened.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Arran
  • 24,648
  • 6
  • 68
  • 78
51

Chrome 57 has an option to pass the --headless flag, which makes the window invisible.

This flag is different from the --no-startup-window as the last doesn't launch a window. It is used for hosting background apps, as this page says.

Java code to pass the flag to Selenium webdriver (ChromeDriver):

ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
ChromeDriver chromeDriver = new ChromeDriver(options);
74nine
  • 838
  • 7
  • 13
  • Do you know if it is possible to do the same in VBA language? – Martin Aug 01 '17 at 08:52
  • @Martin I don't know whether your problem already has been fixed or not, but after a quick search I found those: https://github.com/prajaktamoghe/selenium-vba/issues/33 https://stackoverflow.com/questions/45121955/how-can-i-use-chrome-options-in-vba-with-selenium Does this help you? – 74nine Aug 23 '17 at 14:36
35

For running without any browser, you can run it in headless mode.

I show you one example in Python that is working for me right now

from selenium import webdriver


options = webdriver.ChromeOptions()
options.add_argument("headless")
self.driver = webdriver.Chrome(executable_path='/Users/${userName}/Drivers/chromedriver', chrome_options=options)

I also add you a bit more of info about this in the official Google website https://developers.google.com/web/updates/2017/04/headless-chrome

23

I used this code for Firefox in Windows and got answer(reference here):

from selenium import webdriver
from selenium.webdriver.firefox.options import Options

Options = Options()
Options.headless = True

Driver = webdriver.Firefox(options=Options, executable_path='geckodriver.exe')
Driver.get(...)
...

But I didn't test it for other browsers.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
PouriaDiesel
  • 660
  • 8
  • 11
16

Since Chrome 57 you have the headless argument:

var options = new ChromeOptions();
options.AddArguments("headless");
using (IWebDriver driver = new ChromeDriver(options))
{
    // The rest of your tests
}

The headless mode of Chrome performs 30.97% better than the UI version. The other headless driver PhantomJS delivers 34.92% better than the Chrome's headless mode.

PhantomJSDriver

using (IWebDriver driver = new PhantomJSDriver())
{
     // The rest of your test
}

The headless mode of Mozilla Firefox performs 3.68% better than the UI version. This is a disappointment since the Chrome's headless mode achieves > 30% better time than the UI one. The other headless driver PhantomJS delivers 34.92% better than the Chrome's headless mode. Surprisingly for me, the Edge browser beats all of them.

var options = new FirefoxOptions();
options.AddArguments("--headless");
{
    // The rest of your test
}

This is available from Firefox 57+

The headless mode of Mozilla Firefox performs 3.68% better than the UI version. This is a disappointment since the Chrome's headless mode achieves > 30% better time than the UI one. The other headless driver PhantomJS delivers 34.92% better than the Chrome's headless mode. Surprisingly for me, the Edge browser beats all of them.

Note: PhantomJS is not maintained any more!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anton Angelov
  • 1,705
  • 13
  • 16
9

On Windows you can use win32gui:

import win32gui
import win32con
import subprocess

class HideFox:
    def __init__(self, exe='firefox.exe'):
        self.exe = exe
        self.get_hwnd()

    def get_hwnd(self):
      win_name = get_win_name(self.exe)
      self.hwnd = win32gui.FindWindow(0,win_name)

    def hide(self):
        win32gui.ShowWindow(self.hwnd, win32con.SW_MINIMIZE)
        win32gui.ShowWindow(self.hwnd, win32con.SW_HIDE)

    def show(self):
        win32gui.ShowWindow(self.hwnd, win32con.SW_SHOW)
        win32gui.ShowWindow(self.hwnd, win32con.SW_MAXIMIZE)

def get_win_name(exe):
    ''' Simple function that gets the window name of the process with the given name'''
    info = subprocess.STARTUPINFO()
    info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
    raw = subprocess.check_output('tasklist /v /fo csv', startupinfo=info).split('\n')[1:-1]
    for proc in raw:
        try:
            proc = eval('[' + proc + ']')
            if proc[0] == exe:
                return proc[8]
        except:
            pass
    raise ValueError('Could not find a process with name ' + exe)

Example:

hider = HideFox('firefox.exe') # Can be anything, e.q., phantomjs.exe, notepad.exe, etc.
# To hide the window
hider.hide()
# To show again
hider.show()

However, there is one problem with this solution - using send_keys method makes the window show up. You can deal with it by using JavaScript which does not show a window:

def send_keys_without_opening_window(id_of_the_element, keys)
    YourWebdriver.execute_script("document.getElementById('" + id_of_the_element + "').value = '" + keys + "';")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Piotr Dabkowski
  • 5,661
  • 5
  • 38
  • 47
8

I suggest using PhantomJS. For more information, you may visit the Phantom Official Website.

As far as I know PhantomJS works only with Firefox...

After downloading PhantomJs.exe you need to import it to your project as you can see in the picture below PhantomJS.

I have placed mine inside: commonLibraryphantomjs.exe

Enter image description here

Now all you have to do inside your Selenium code is to change the line

browser = webdriver.Firefox()

To something like

import os
path2phantom = os.getcwd() + "\common\Library\phantomjs.exe"
browser = webdriver.PhantomJS(path2phantom)

The path to PhantomJS may be different... change as you like :)

This hack worked for me, and I'm pretty sure it will work for u too ;)

Ayyoub
  • 4,581
  • 2
  • 19
  • 32
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes – slfan May 29 '16 at 15:39
  • PhantomJS is being discontinued as of November 2020. Please see answer above by @Amistad for the headless mode of Google Chrome. – robertspierre Nov 29 '20 at 23:33
3

It may be in options. Here is the identical Java code.

        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setHeadless(true);
        WebDriver driver = new ChromeDriver(chromeOptions);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rinjan
  • 550
  • 5
  • 19
3

This is a simple Node.js solution that works in the new version 4.x (maybe also 3.x) of Selenium.

Chrome

const { Builder } = require('selenium-webdriver')
const chrome = require('selenium-webdriver/chrome');

let driver = await new Builder().forBrowser('chrome').setChromeOptions(new chrome.Options().headless()).build()

await driver.get('https://example.com')

Firefox

const { Builder } = require('selenium-webdriver')
const firefox = require('selenium-webdriver/firefox');

let driver = await new Builder().forBrowser('firefox').setFirefoxOptions(new firefox.Options().headless()).build()

await driver.get('https://example.com')

The whole thing just runs in the background. It is exactly what we want.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
hardfork
  • 2,470
  • 1
  • 23
  • 43
3

If you are using the Google Chrome driver, you can use this very simple code (it worked for me):

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome('chromedriver2_win32/chromedriver.exe', options=chrome_options)
driver.get('https://www.anywebsite.com')
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Majid A
  • 802
  • 9
  • 19
1

On *nix, you can also run a headless X Window server like Xvfb and point the DISPLAY environment variable to it:

Fake X server for testing?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user2645074
  • 107
  • 8
1

One way to achieve this is by running the browser in headless mode. Another advantage of this is that tests are executed faster.

Please find the code below to set headless mode in the Chrome browser.

package chrome;

public class HeadlessTesting {

    public static void main(String[] args) throws IOException {
        System.setProperty("webdriver.chrome.driver",
                "ChromeDriverPath");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("headless");
        options.addArguments("window-size=1200x600");
        WebDriver driver = new ChromeDriver(options);
        driver.get("https://contentstack.built.io");
        driver.get("https://www.google.co.in/");
        System.out.println("title is: " + driver.getTitle());
        File scrFile = ((TakesScreenshot) driver)
                .getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("pathTOSaveFile"));
        driver.quit();
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Navpreet Singh
  • 141
  • 1
  • 5
0

Here is a .NET solution that worked for me:

Download PhantomJS at http://phantomjs.org/download.html.

Copy the .exe file from the bin folder in the download folder and paste it to the bin debug/release folder of your Visual Studio project.

Add this using

using OpenQA.Selenium.PhantomJS;

In your code, open the driver like this:

PhantomJSDriver driver = new PhantomJSDriver();
using (driver)
{
   driver.Navigate().GoToUrl("http://testing-ground.scraping.pro/login");
   // Your code here
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jack Fairfield
  • 1,876
  • 22
  • 25
  • PhantomJS is being discontinued as of November 2020. Please see answer above by @Amistad for the headless mode of Google Chrome – robertspierre Nov 29 '20 at 23:33
0

If you are using Ubuntu (Gnome), one simple workaround is to install Gnome extension auto-move-window: https://extensions.gnome.org/extension/16/auto-move-windows/

Then set the browser (eg. Chrome) to another workspace (eg. Workspace 2). The browser will silently run in other workspace and not bother you anymore. You can still use Chrome in your workspace without any interruption.

Bob
  • 11
  • 1
0

I had the same problem with my chromedriver using Python and options.add_argument("headless") did not work for me, but then I realized how to fix it so I bring it in the code below:

opt = webdriver.ChromeOptions()
opt.arguments.append("headless")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Soroush Bn
  • 26
  • 4
-1

Just add a simple "headless" option argument.

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome("PATH_TO_DRIVER", options=options)
Glatinis
  • 337
  • 1
  • 13
-1

Use it ...

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.headless = True
driver = webdriver.Chrome(CHROMEDRIVER_PATH, chrome_options=options)
Maran Sowthri
  • 829
  • 6
  • 14