J'essaie d'exécuter des tests d'intégration sur un hôte local (sans HTTPS) à l'aide de Selenium avec ChromeDriver.
Chrome nécessite un certificat https, mais de this question je comprends que je peux contourner cela en utilisant l'arg --ignore-certificate-errors
J'ai également ajouté à mes capacités acceptInsecureCerts
, car cela semble être le plan d'action approprié ( docs )
La réponse du chromedriver n'est toujours pas ce que j'attendais:
Ce site ne peut pas fournir une application de connexion sécurisée envoyée une réponse non valide. ERR_SSL_PROTOCOL_ERROR
Mon code est ci-dessous:
from Selenium import webdriver
from Selenium.webdriver.chrome.options import Options
# make options (principally to ignore certificate)
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
# add acceptInsecureCerts
capabilities = options.to_capabilities()
capabilities['acceptInsecureCerts'] = True
print(capabilities) # see below
driver = webdriver.Remote(
command_executor=Selenium_HUB,
desired_capabilities=capabilities
)
print(driver.__dict__) # see further below
app_login_url = 'http://app:8000/accounts/login/'
driver.get(app_login_url)
Mes capacités:
{'acceptInsecureCerts': True,
'browserName': 'chrome',
'goog:chromeOptions': {'args': ['--ignore-certificate-errors'],
'extensions': []},
'platform': 'ANY',
'version': ''}
Voici mes informations de pilote, il semble que seul l'argument acceptInsecureCerts
ait été pris en compte:
{'_file_detector': <Selenium.webdriver.remote.file_detector.LocalFileDetector object at 0x7fb42bde10f0>,
'_is_remote': True,
'_mobile': <Selenium.webdriver.remote.mobile.Mobile object at 0x7fb42bb5e400>,
'_switch_to': <Selenium.webdriver.remote.switch_to.SwitchTo object at 0x7fb42bdd4898>,
'capabilities': {'acceptInsecureCerts': True,
'acceptSslCerts': True,
'applicationCacheEnabled': False,
'browserConnectionEnabled': False,
'browserName': 'chrome',
'chrome': {'chromedriverVersion': '74.0.3729.6 '
'(255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29})',
'userDataDir': '/tmp/.com.google.Chrome.vc1ZvB'},
'cssSelectorsEnabled': True,
'databaseEnabled': False,
'goog:chromeOptions': {'debuggerAddress': 'localhost:40815'},
'handlesAlerts': True,
'hasTouchScreen': False,
'javascriptEnabled': True,
'locationContextEnabled': True,
'mobileEmulationEnabled': False,
'nativeEvents': True,
'networkConnectionEnabled': False,
'pageLoadStrategy': 'normal',
'platform': 'Linux',
'proxy': {},
'rotatable': False,
'setWindowRect': True,
'strictFileInteractability': False,
'takesHeapSnapshot': True,
'takesScreenshot': True,
'timeouts': {'implicit': 0,
'pageLoad': 300000,
'script': 30000},
'unexpectedAlertBehaviour': 'ignore',
'version': '74.0.3729.169',
'webStorageEnabled': True,
'webdriver.remote.sessionid': '1cf77f237e966bac6ca15d4d9c107423'},
'command_executor': <Selenium.webdriver.remote.remote_connection.RemoteConnection object at 0x7fb42be0cf98>,
'error_handler': <Selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7fb427d08a20>,
'session_id': '1cf77f237e966bac6ca15d4d9c107423',
'w3c': False}
Pourquoi est-ce que je vois toujours le ERR_SSL_PROTOCOL_ERROR
?
Ce message d'erreur ...
This site can’t provide a secure connection app sent an invalid response. ERR_SSL_PROTOCOL_ERROR
... implique que le ChromeDriver n'a pas pu lancer/générer un nouveau WebBrowser ie session du navigateur Chrome sur votre hôte local.
Comme vous voyez ce problème sur votre hôte local (sans HTTPS) selon ce commentaire une solution de pli aveugle serait d'ajouter le argument
--allow-insecure-localhost
à chromeOptions()
comme suit:
'goog:chromeOptions': {'args': ['--allow-insecure-localhost'],
'extensions': []}
Cependant, votre problème principal semble être avec les capacités où vous avez défini platform
étant défini s ANY
comme suit:
{'acceptInsecureCerts': True,
'browserName': 'chrome',
'goog:chromeOptions': {'args': ['--ignore-certificate-errors'],
'extensions': []},
'platform': 'ANY',
'version': ''}
Selon WebDriver - Document vivant W3C la section platformName mentionne, les noms de plate-forme suivants sont couramment utilisés avec une sémantique bien comprise et, lors de l'adéquation des capacités, la plus grande interopérabilité peut être obtenue en les honorant comme des synonymes valides pour des systèmes d'exploitation bien connus:
Key System
--- ------
"linux" Any server or desktop system based upon the Linux kernel.
"mac" Any version of Apple’s macOS.
"windows" Any version of Microsoft Windows, including desktop and mobile versions.
Remarque : Cette liste n'est pas exhaustive.
Lors du retour de fonctionnalités à partir d'une nouvelle session, il est valide de renvoyer un nom de plateforme plus spécifique, permettant aux utilisateurs d'identifier correctement le système d'exploitation sur lequel l'implémentation WebDriver s'exécute.
Ainsi, au lieu de passer "platform":"ANY"
Dans l'objet desireCapabilities, une approche plus spécifique "platform":"linux"
Sera plus souhaitable.
Vous pouvez trouver une discussion pertinente et connexe dans Erreur de boucle renvoyée pour http POST vers/session avec les paramètres: {"desireCapabilities": {"browserName": "chrome", "platform" ":" TOUT "avec Selenium et PHPUnit
Quelques informations supplémentaires sur la ChromeDriver, Chrome et Selenium Client vrsion nous auraient aidés à mieux analyser le problème. Cependant, selon ChromeDriver historique, les problèmes suivants liés à la gestion des erreurs de certificat ont été résolus dans les dernières versions de ChromeDriver:
--ignore-certificate-errors
) ont été ignorés en silence et ne peuvent être définis que via devtools. Il était donc nécessaire de remplacer et de gérer les événements certificateError
sur le client DevTools cible du navigateur. Un correctif a été publié implémentant l'utilisation de la nouvelle méthode DevTools pour remplacer la gestion des erreurs de certificat à l'échelle du navigateur, ce qui a également permis d'ignorer les erreurs de certificat en mode sans tête.Security.enable
/Security.setOverrideCertificateErrors
assez rapidement avant de tenter une navigation. Un correctif a été publié avec un mode plus simple "ignorer toutes les erreurs de certificat" à la place, il a déconseillé l'ancienne commande de remplacement au profit d'une nouvelle commande setIgnoreCertificateErrors
qui expose également le domaine de sécurité sur la cible du navigateur à faciliter l'application globale de ce remplacement pour l'ensemble du navigateur.--allow-insecure-localhost
acceptInsecureCerts
--ignore-certificate-errors
'chromedriverVersion': '74.0.3729.6'
, Assurez-vous que vous utilisez également 'chrome': '74.0'
(Selon ChromeDriver v74.0.3729.6 Notes de version)Selon Correction des plantages de page "Aw, Snap!" Et autres erreurs de chargement de page - Ordinateur - Google Chrome (développez la section "Codes et problèmes d'erreur de chargement de page") ), Chrome donne ERR_SSL_PROTOCOL_ERROR
pour TOUTE erreur liée à SSL. Cela comprend:
Étant donné que vous ne pouvez pas obtenir plus de détails de Chrome, ouvrez la page dans une autre application (par exemple, Firefox ou avec openssl s_client
) pourrait vous donner plus de détails sur ce qui se passe.
Renifler des paquets avec par exemple Wireshark peut montrer les étapes initiales de la connexion, y compris l'étape de négociation; si le serveur est le vôtre (vous avez donc sa clé privée), vous pourrez également décrypter les parties cryptées - ce qui vous donnera l'image complète.
Vous demandez la page via HTTP
et non HTTPS
. Chrome ne se connectera pas à un serveur HTTP
non sécurisé.
Cela entraîne l'échec de la négociation TLS/SSL.
Vous devez vous assurer que votre serveur exécute HTTPS
sur TCP port 8000.
Avec le --ignore-certificate-errors
option, vous pouvez générer un certificat auto-signé et l'appliquer au serveur Web.
Modifiez ensuite la ligne d'URL pour utiliser HTTPS
.
app_login_url = 'https://app:8000/accounts/login/'