J'ai une suite de tests Selenium qui exécute de nombreux tests et à chaque nouveau test, une fenêtre de navigateur s'ouvre au-dessus de toutes les autres fenêtres que j'ai ouvertes. C'est très gênant lorsque l'on travaille dans un environnement local. Existe-t-il un moyen d'indiquer à Selenium ou au système d'exploitation (Mac) d'ouvrir les fenêtres en arrière-plan ?
Réponses
Trop de publicités?Depuis Chrome 57, vous avez l'argument sans tête :
var options = new ChromeOptions();
options.AddArguments("headless");
using (IWebDriver driver = new ChromeDriver(options))
{
// The rest of your tests
}
Le mode sans tête de Chrome affiche des performances 30,97 % supérieures à celles de la version avec interface utilisateur. L'autre pilote sans tête PhantomJS offre 34,92 % de mieux que le mode sans tête de Chrome.
Pilote PhantomJSD
using (IWebDriver driver = new PhantomJSDriver())
{
// The rest of your test
}
Le mode sans tête de Mozilla Firefox est 3,68 % plus performant que la version avec interface utilisateur. C'est une déception car le mode headless de Chrome obtient un temps supérieur de plus de 30% à celui de la version UI. L'autre pilote sans tête PhantomJS est 34,92% plus rapide que le mode sans tête de Chrome. Étonnamment pour moi, le navigateur Edge les bat tous.
var options = new FirefoxOptions();
options.AddArguments("--headless");
{
// The rest of your test
}
Ceci est disponible à partir de Firefox 57+.
Le mode sans tête de Mozilla Firefox est 3,68 % plus performant que la version avec interface utilisateur. C'est une déception car le mode headless de Chrome obtient un temps supérieur de plus de 30% à celui de la version UI. L'autre pilote sans tête, PhantomJS, est 34,92 % plus rapide que le mode sans tête de Chrome. Étonnamment pour moi, le navigateur Edge les bat tous.
Note : PhantomJS n'est plus maintenu !
Sous Windows, vous pouvez utiliser 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)
Exemple :
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()
Cependant, cette solution présente un problème : l'utilisation de la méthode send_keys fait apparaître la fenêtre. Vous pouvez y remédier en utilisant le JavaScript qui ne fait pas apparaître de fenêtre :
def send_keys_without_opening_window(id_of_the_element, keys)
YourWebdriver.execute_script("document.getElementById('" + id_of_the_element + "').value = '" + keys + "';")
Je suggère d'utiliser PhantomJS . Pour plus d'informations, vous pouvez consulter le site Site officiel de Phantom .
Pour autant que je sache, PhantomJS ne fonctionne qu'avec Firefox...
Après avoir téléchargé PhantomJs.exe, vous devez l'importer dans votre projet comme vous pouvez le voir dans l'image ci-dessous PhantomJS.
J'ai placé le mien à l'intérieur : commun → Bibliothèque → phantomjs.exe
Maintenant, tout ce que vous avez à faire dans votre code Selenium est de changer la ligne
browser = webdriver.Firefox()
A quelque chose comme
import os
path2phantom = os.getcwd() + "\common\Library\phantomjs.exe"
browser = webdriver.PhantomJS(path2phantom)
Le chemin vers PhantomJS peut être différent... changez comme vous voulez :)
Ce hack a fonctionné pour moi, et je suis sûr qu'il fonctionnera pour vous aussi ;)
Il s'agit d'un simple Node.js solution qui fonctionne dans la nouvelle version 4.x (peut-être aussi 3.x) de 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')
Le tout fonctionne en arrière-plan. C'est exactement ce que nous voulons.