web-dev-qa-db-fra.com

Comment puis-je me reconnecter au navigateur ouvert par webdriver avec sélénium?

Pour des raisons inconnues, mon navigateur ouvre très lentement les pages de test de mon serveur distant. Je pense donc que si je peux me reconnecter au navigateur après avoir quitté le script mais que je n'exécute pas webdriver.quit() cela laissera le navigateur ouvert. Il s'agit probablement d'une poignée de CROCHET ou de tournevis. J'ai recherché le document d'API Selenium mais je n'ai trouvé aucune fonction. J'utilise Chrome 62, x64, windows 7, Selenium 3.8.0. Je serai très reconnaissant si la question peut être résolue ou non.

11
imbaiye

Non , vous ne pouvez pas vous reconnecter au précédent Web Browser session après avoir quitté le script. Même si vous pouvez extraire le Session ID, Cookies et d'autres attributs de session des précédents Browsing Session vous ne pourrez toujours pas transmettre ces attributs comme un CROCHET au WebDriver.

Une façon plus propre serait d'appeler webdriver.quit() puis d'en créer une nouvelle Browsing Session.

L'histoire :

Auparavant, il y avait eu des discussions et des tentatives pour reconnecter WebDriver à une session de navigation en cours. Vous pouvez trouver les discussions dans ces AQ:

8
DebanjanB

Oui, c'est en fait assez facile à faire.

Une session Selenium <-> webdriver est représentée par une URL de connexion et session_id, il vous suffit de vous reconnecter à une session existante.

Disclaimer - l'approche utilise les propriétés internes de Selenium ("privées", en quelque sorte), qui peuvent changer dans les nouvelles versions; vous feriez mieux de ne pas l'utiliser pour le code de production; il est préférable de ne pas être utilisé contre SE distant (le vôtre hub ou un fournisseur comme BrowserStack/Sauce Labs), en raison d'une mise en garde/drainage des ressources expliquée à la fin.

Lorsqu'une instance de pilote Web est lancée, vous devez obtenir les propriétés susmentionnées; échantillon:

from Selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.google.com/')

# now Google is opened, the browser is fully functional; print the two properties
# command_executor._url (it's "private", not for a direct usage), and session_id

print(f'driver.command_executor._url: {driver.command_executor._url}')
print(f'driver.session_id: {driver.session_id}')

Avec ces deux propriétés maintenant connues, une autre instance peut se connecter; l'astuce consiste à lancer un pilote Remote et à fournir le _url ci-dessus - il se connectera donc au processus Selenium en cours d'exécution:

driver2 = webdriver.Remote(command_executor=the_known_url)  
# when the started Selenium is a local one, the url is in the form 'http://127.0.0.1:62526'

Lorsque cela est exécuté, vous verrez une nouvelle fenêtre de navigateur s'ouvrir.
En effet, lors du lancement du pilote, la bibliothèque Selenium démarre automatiquement une nouvelle session pour lui - et vous avez maintenant 1 processus de pilote Web avec 2 sessions (instances de navigateurs).

Si vous accédez à une URL, vous verrez qu'elle est exécutée sur cette nouvelle instance de navigateur, pas celle qui est restée depuis le démarrage précédent - ce qui n'est pas le comportement souhaité.
À ce stade, deux choses doivent être faites - a) fermer la session SE actuelle ("la nouvelle"), et b) basculer cette instance vers la session précédente:

if driver2.session_id != the_known_session_id:   # this is pretty much guaranteed to be the case
    driver2.close()   # this closes the session's window - it is currently the only one, thus the session itself will be auto-killed, yet:
    driver2.quit()    # for remote connections (like ours), this deletes the session, but does not stop the SE server

# take the session that's already running
driver2.session_id = the_known_session_id

# do something with the now hijacked session:
driver.get('https://www.bing.com/')

Et c'est tout - vous êtes maintenant connecté à la session précédente/déjà existante, avec toutes ses propriétés (cookies, LocalStorage, etc.).

Soit dit en passant, vous n'avez pas à fournir desired_capabilities Lors du lancement du nouveau pilote distant - ceux-ci sont stockés et hérités de la session existante que vous avez prise en charge.


Avertissement - l'exécution d'un processus SE peut entraîner un certain drainage des ressources dans le système.

Chaque fois que l'un est démarré puis fermé - comme dans la première partie du code - il y restera jusqu'à ce que vous le tuiez manuellement. J'entends par là - dans Windows par exemple - vous verrez un processus "chromedriver.exe", que vous devez terminer manuellement une fois que vous en avez terminé. Il ne peut pas être fermé par un pilote qui s'y est connecté comme pour un processus Sélénium distant.
La raison - chaque fois que vous lancez une instance de navigateur local, puis appelez sa méthode quit(), elle contient 2 parties - la première consiste à supprimer la session de l'instance Selenium fait dans le deuxième morceau de code là-haut), et l'autre consiste à arrêter le service local (le chrome/geckodriver) - qui fonctionne généralement bien.

Le fait est que, pour les sessions à distance, la deuxième pièce est manquante - votre machine locale ne peut pas contrôler un processus distant, c'est le travail du concentrateur de cette télécommande. De sorte que la 2ème partie est littéralement un pass python - un no-op.

Si vous démarrez trop de services Selenium sur un concentrateur distant et que vous n'avez aucun contrôle sur celui-ci, cela entraînera un drainage des ressources à partir de ce serveur. Les fournisseurs de cloud comme BrowserStack prennent des mesures contre cela - ils ferment des services sans activité depuis 60 ans, etc. - c'est quelque chose que vous ne voulez pas faire.

Et comme pour les services SE locaux - n'oubliez pas de nettoyer occasionnellement le système d'exploitation des pilotes Sélénium orphelins que vous avez oubliés :)

5
Todor Minakov

Sans expliquer pourquoi pensez-vous que laisser des fenêtres de navigateur ouvertes résoudra le problème de la lenteur, vous n'avez pas vraiment besoin d'une poignée pour le faire. Continuez simplement à exécuter les tests sans fermer la session ou, en d'autres termes, sans appeler driver.quit() comme vous l'avez mentionné vous-même. La question ici si le framework est livré avec son propre runner? Comme le concombre?

Dans tous les cas, vous devez avoir du code "setup" et "cleanup". Donc, ce que vous devez faire est de vous assurer pendant la phase de "nettoyage" que le navigateur est de retour à son état initial. Cela signifie:

  • Une page vierge s'affiche
  • Les cookies sont effacés pour la session
0
Eugene S