Il selenium può interagire con una sessione del browser esistente?

Qualcuno sa se Selenium (preferibilmente WebDriver) è in grado di comunicare e agire attraverso un browser che è già in esecuzione prima di avviare un client Selenium?

Voglio dire se Selenium è in grado di comunicare con un browser senza utilizzare il Selenium Server (con potrebbe essere un Internet Explorer lanciato manualmente per esempio).

Questa è una richiesta di funzionalità piuttosto vecchia: consentire a webdriver di collegarsi a un browser in esecuzione . Quindi non è ufficialmente supportato.

Tuttavia, esiste un codice funzionante che afferma di supportare questo: https://web.archive.org/web/20171214043703/http://tarunlalwani.com/post/reusing-existing-browser-session-selenium-java/ .

Questa è una risposta duplicata ** Riconnetti a un driver in selenium Python ** Questo è applicabile a tutti i driver e per java api.

  1. aprire un driver

    driver = webdriver.Firefox() #python 
  2. estrai a session_id e _url dall’object driver.

     url = driver.command_executor._url #"http://127.0.0.1:60622/hub" session_id = driver.session_id #'4e167f26-dc1d-4f51-a207-f761eaf73c31' 
  3. Usa questi due parametri per connetterti al tuo driver.

     driver = webdriver.Remote(command_executor=url,desired_capabilities={}) driver.session_id = session_id 

    E sei collegato nuovamente al tuo autista.

     driver.get("http://www.mrsmart.in") 

È ansible. Ma devi modificarlo un po ‘, c’è un codice Quello che devi fare è eseguire il server stand-alone e “patch” RemoteWebDriver

 public class CustomRemoteWebDriver : RemoteWebDriver { public static bool newSession; public static string capPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles", "tmp", "sessionCap"); public static string sessiodIdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles", "tmp", "sessionid"); public CustomRemoteWebDriver(Uri remoteAddress) : base(remoteAddress, new DesiredCapabilities()) { } protected override Response Execute(DriverCommand driverCommandToExecute, Dictionary parameters) { if (driverCommandToExecute == DriverCommand.NewSession) { if (!newSession) { var capText = File.ReadAllText(capPath); var sidText = File.ReadAllText(sessiodIdPath); var cap = JsonConvert.DeserializeObject>(capText); return new Response { SessionId = sidText, Value = cap }; } else { var response = base.Execute(driverCommandToExecute, parameters); var dictionary = (Dictionary) response.Value; File.WriteAllText(capPath, JsonConvert.SerializeObject(dictionary)); File.WriteAllText(sessiodIdPath, response.SessionId); return response; } } else { var response = base.Execute(driverCommandToExecute, parameters); return response; } } } 

Questo snippet consente di riutilizzare l’istanza del browser esistente senza tuttavia sollevare il browser duplicato. Trovato al blog di Tarun Lalwani .

 from selenium import webdriver from selenium.webdriver.remote.webdriver import WebDriver # executor_url = driver.command_executor._url # session_id = driver.session_id def attach_to_session(executor_url, session_id): original_execute = WebDriver.execute def new_command_execute(self, command, params=None): if command == "newSession": # Mock the response return {'success': 0, 'value': None, 'sessionId': session_id} else: return original_execute(self, command, params) # Patch the function before creating the driver object WebDriver.execute = new_command_execute driver = webdriver.Remote(command_executor=executor_url, desired_capabilities={}) driver.session_id = session_id # Replace the patched function with original function WebDriver.execute = original_execute return driver bro = attach_to_session('http://127.0.0.1:64092', '8de24f3bfbec01ba0d82a7946df1d1c3') bro.get('http://ya.ru/') 

Tutte le soluzioni finora mancavano di alcune funzionalità. Ecco la mia soluzione:

 public class AttachedWebDriver extends RemoteWebDriver { public AttachedWebDriver(URL url, String sessionId) { super(); setSessionId(sessionId); setCommandExecutor(new HttpCommandExecutor(url) { @Override public Response execute(Command command) throws IOException { if (command.getName() != "newSession") { return super.execute(command); } return super.execute(new Command(getSessionId(), "getCapabilities")); } }); startSession(new DesiredCapabilities()); } } 

Soluzione Javascript:

Ho collegato con successo alla sessione del browser esistente utilizzando questa funzione

 webdriver.WebDriver.attachToSession(executor, session_id); 

La documentazione può essere trovata qui .

Ho trovato una soluzione in python, ho modificato la class del webdriver con il basso sulla class PersistenBrowser che ho trovato.

https://github.com/axelPalmerin/personal/commit/fabddb38a39f378aa113b0cb8d33391d5f91dca5

sostituire il modulo webdriver /usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py

Ej. usare:

 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities runDriver = sys.argv[1] sessionId = sys.argv[2] def setBrowser(): if eval(runDriver): webdriver = w.Remote(command_executor='http://localhost:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME, ) else: webdriver = w.Remote(command_executor='http://localhost:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME, session_id=sessionId) url = webdriver.command_executor._url session_id = webdriver.session_id print url print session_id return webdriver 

Utilizzo Rails + Cucumber + Selenium Webdriver + PhantomJS, e ho utilizzato una versione con patch di Selenium Webdriver, che mantiene aperto il browser PhantomJS tra una serie di test e l’altra. Vedi questo post del blog: http://blog.sharetribe.com/2014/04/07/faster-cucumber-startup-keep-phantomjs-browser-open-between-tests/

Vedi anche la mia risposta a questo post: Come eseguo un comando sul browser già aperto da un file ruby

Questo è piuttosto semplice usando il client JavaScript selenium-webdriver :

Innanzitutto, assicurati di avere un server WebDriver in esecuzione. Ad esempio, scarica ChromeDriver , quindi esegui chromedriver --port=9515 .

Secondo, crea il driver in questo modo :

 var driver = new webdriver.Builder() .withCapabilities(webdriver.Capabilities.chrome()) .usingServer('http://localhost:9515') // < - this .build(); 

Ecco un esempio completo:

var webdriver = require ('selenium-webdriver');

 var driver = new webdriver.Builder() .withCapabilities(webdriver.Capabilities.chrome()) .usingServer('http://localhost:9515') .build(); driver.get('http://www.google.com'); driver.findElement(webdriver.By.name('q')).sendKeys('webdriver'); driver.findElement(webdriver.By.name('btnG')).click(); driver.getTitle().then(function(title) { console.log(title); }); driver.quit(); 

Ispirato alla risposta di Eric, ecco la mia soluzione a questo problema per il selenium 3.7.0. Rispetto alla soluzione su http://tarunlalwani.com/post/reusing-existing-browser-session-selenium/ , il vantaggio è che non ci sarà una finestra del browser vuota ogni volta che mi collego alla sessione esistente.

 import warnings from selenium.common.exceptions import WebDriverException from selenium.webdriver.remote.errorhandler import ErrorHandler from selenium.webdriver.remote.file_detector import LocalFileDetector from selenium.webdriver.remote.mobile import Mobile from selenium.webdriver.remote.remote_connection import RemoteConnection from selenium.webdriver.remote.switch_to import SwitchTo from selenium.webdriver.remote.webdriver import WebDriver # This webdriver can directly attach to an existing session. class AttachableWebDriver(WebDriver): def __init__(self, command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=None, browser_profile=None, proxy=None, keep_alive=False, file_detector=None, session_id=None): """ Create a new driver that will issue commands using the wire protocol. :Args: - command_executor - Either a string representing URL of the remote server or a custom remote_connection.RemoteConnection object. Defaults to 'http://127.0.0.1:4444/wd/hub'. - desired_capabilities - A dictionary of capabilities to request when starting the browser session. Required parameter. - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object. Only used if Firefox is requested. Optional. - proxy - A selenium.webdriver.common.proxy.Proxy object. The browser session will be started with given proxy settings, if possible. Optional. - keep_alive - Whether to configure remote_connection.RemoteConnection to use HTTP keep-alive. Defaults to False. - file_detector - Pass custom file detector object during instantiation. If None, then default LocalFileDetector() will be used. """ if desired_capabilities is None: raise WebDriverException("Desired Capabilities can't be None") if not isinstance(desired_capabilities, dict): raise WebDriverException("Desired Capabilities must be a dictionary") if proxy is not None: warnings.warn("Please use FirefoxOptions to set proxy", DeprecationWarning) proxy.add_to_capabilities(desired_capabilities) self.command_executor = command_executor if type(self.command_executor) is bytes or isinstance(self.command_executor, str): self.command_executor = RemoteConnection(command_executor, keep_alive=keep_alive) self.command_executor._commands['GET_SESSION'] = ('GET', '/session/$sessionId') # added self._is_remote = True self.session_id = session_id # added self.capabilities = {} self.error_handler = ErrorHandler() self.start_client() if browser_profile is not None: warnings.warn("Please use FirefoxOptions to set browser profile", DeprecationWarning) if session_id: self.connect_to_session(desired_capabilities) # added else: self.start_session(desired_capabilities, browser_profile) self._switch_to = SwitchTo(self) self._mobile = Mobile(self) self.file_detector = file_detector or LocalFileDetector() self.w3c = True # added hardcoded def connect_to_session(self, desired_capabilities): response = self.execute('GET_SESSION', { 'desiredCapabilities': desired_capabilities, 'sessionId': self.session_id, }) # self.session_id = response['sessionId'] self.capabilities = response['value'] 

Per usarlo:

 if use_existing_session: browser = AttachableWebDriver(command_executor=('http://%s:4444/wd/hub' % ip), desired_capabilities=(DesiredCapabilities.INTERNETEXPLORER), session_id=session_id) self.logger.info("Using existing browser with session id {}".format(session_id)) else: browser = AttachableWebDriver(command_executor=('http://%s:4444/wd/hub' % ip), desired_capabilities=(DesiredCapabilities.INTERNETEXPLORER)) self.logger.info('New session_id : {}'.format(browser.session_id)) 

Sembra che questa funzione non sia ufficialmente supportata dal selenium. Ma Tarun Lalwani ha creato un codice Java funzionante per fornire la funzionalità. Refer – http://tarunlalwani.com/post/reusing-existing-browser-session-selenium-java/

Ecco il codice di esempio funzionante, copiato dal link precedente:

 public static RemoteWebDriver createDriverFromSession(final SessionId sessionId, URL command_executor){ CommandExecutor executor = new HttpCommandExecutor(command_executor) { @Override public Response execute(Command command) throws IOException { Response response = null; if (command.getName() == "newSession") { response = new Response(); response.setSessionId(sessionId.toString()); response.setStatus(0); response.setValue(Collections.emptyMap()); try { Field commandCodec = null; commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec"); commandCodec.setAccessible(true); commandCodec.set(this, new W3CHttpCommandCodec()); Field responseCodec = null; responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec"); responseCodec.setAccessible(true); responseCodec.set(this, new W3CHttpResponseCodec()); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } else { response = super.execute(command); } return response; } }; return new RemoteWebDriver(executor, new DesiredCapabilities()); } public static void main(String [] args) { ChromeDriver driver = new ChromeDriver(); HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor(); URL url = executor.getAddressOfRemoteServer(); SessionId session_id = driver.getSessionId(); RemoteWebDriver driver2 = createDriverFromSession(session_id, url); driver2.get("http://tarunlalwani.com"); } 

Il tuo test deve avere un RemoteWebDriver creato da una sessione di browser esistente. Per creare quel Driver, devi solo conoscere le “informazioni sulla sessione”, cioè l’indirizzo del server (locale nel nostro caso) dove è in esecuzione il browser e l’ID della sessione del browser. Per ottenere questi dettagli, possiamo creare una sessione del browser con selenium, aprire la pagina desiderata e infine eseguire lo script di test effettivo.

Non so se c’è un modo per ottenere informazioni sulla sessione per una sessione che non è stata creata dal selenium.

Ecco un esempio di informazioni sulla sessione:

Indirizzo del server remoto: http: // localhost: 24266 . Il numero di porta è diverso per ogni sessione. ID sessione: 534c7b561aacdd6dc319f60fed27d9d6.