Удаленная сетка селена через https не работает
Компания, в которой я работаю, требует / впечатляет, что весь наш тестовый трафик селена будет проходить через https при использовании удаленного грид-сервера селена, который мы размещали в AWS внутри экземпляра докера.
До сих пор это, кажется, работало, но с самой последней версией селена 3.14. Сейчас я получаю сотни "InsecureRequestWarnings" даже для самого простого теста. Я диагностировал, что это вызвано подключением https к сетке селена, а не целевым URL-адресом теста, потому что если я запускаю одни и те же тесты с локального сервера селена и веб-драйвера, у меня не возникает таких же проблем.
Я использую следующее: python 3.6.4, pytest 3.7.2, pytest-selenium 1.13, селен 3.14 (как локально, так и в удаленной сетке селена), chromedriver 2.41 (локально и удаленно), certifi 2018.8.13, urllib3 1,23
запустить из различных окон Windows (Server 2008, Windows 10 и т. д...)
после запуска приведенного ниже кода (в основном это комбинация моего conftest.py и простого сценария тестирования входа в систему), я получаю следующие предупреждения (62 из них повторены).
D:\Work\PyTestFramework\VirtEnv3_6\lib\site-packages\urllib3\connectionpool.py:857: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
Мой пример кода:
import pytest
import webdriverwrapper
import webdriverwrapper.wrapper
from webdriverwrapper import DesiredCapabilities
# testtools are just my reusable helper libraries
from testtools import credentials_helper, login_helper, appointment_helper
def pytest_addoption(parser):
parser.addoption('--url', action='store', default='https://bookingportal.mycompany.com.au/OBP',
help='target machine url')
@pytest.fixture(scope='session')
def url(request):
return request.config.getoption('url')
@pytest.fixture(scope='function')
def browser(request):
desired_cap = DesiredCapabilities.CHROME
desired_cap['chromeOptions'] = {}
desired_cap['chromeOptions']['args'] = ['--disable-plugins', '--disable-extensions']
desired_cap['browserName'] = 'chrome'
desired_cap['javascriptEnabled'] = True
hostname = "https://selenium.mygriddocker.com.au/wd/hub"
executor = webdriverwrapper.wrapper.remote.remote_connection.RemoteConnection(hostname, resolve_ip=False)
b = webdriverwrapper.Remote(executor, desired_cap)
request.addfinalizer(lambda *args: b.quit())
return b
@pytest.fixture(scope='function')
def driver(browser, url):
driver = browser
driver.set_window_size(1260, 1080)
driver.get(url)
return driver
# ------------ put test script here
@pytest.mark.usefixtures("driver")
def test_OBP_Login(driver):
testId = 'LogIn01'
credentials_list = credentials_helper.get_csv_data('OBP_LoginDetails.csv', testId)
assert driver.title == 'Booking Portal'
rslt1 = login_helper.login_user(driver, credentials_list)
assert rslt1
rslt2 = appointment_helper.logout_OBP(driver)
assert rslt2
как вы можете видеть адрес сервера сетки селена, который я звоню, https://selenium.mygriddocker.com.au/wd/hub (не фактический реальный адрес)
и я подтвердил, что у него есть действительный сертификат, выданный государственным органом (Comodo). Примечание. У меня нет этой проблемы, если я возвращаюсь к urllib3 и certifi, но я не уверен, в какой момент он перестает работать
Многие люди просто подавляют предупреждения, но я действительно хочу, чтобы сертификат работал.
Очевидное решение - перейти по ссылкам и добавить проверку сертификата, как они предлагают, но проблема в том, как отправить параметры диспетчера пула соединений через класс selenium RemoteConnection?
Предлагаемое исправление: https://urllib3.readthedocs.io/en/latest/user-guide.html:
import certifi
import urllib3
http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
Когда я покопался в библиотеке селена, я обнаружил, что использование urllib3.PoolManager было расположено в модуле remote_connection, но у него не было доступных параметров для отправки через дополнительную информацию для PoolManager при его вызове. Вы можете видеть в моем примере кода объект executor, где я вызываю remote_connection (посредством webdriverwrapper, в обычном селене путь - selenium / webdriver / remote / remote_connection)
В классе RemoteConnection нет условий для установки PoolManager, который я мог видеть.
Я попытался просто отредактировать remote_connection в надежде жестко запрограммировать сертифицирующую информацию в файл в надежде выяснить, как обернуть ее позже. Итак, я добавил cert_reqs='CERT_REQUIRED', ca_certs=certifi.where()
Строки, где я когда-либо видел urllib3.PoolManager() (я также импортировал сертификат в этот модуль). По какой-то удивительной глупости это действительно сработало. Теперь я не могу понять, как это обернуть.
Кто-нибудь получил какие-либо другие идеи о том, как заставить удаленный селен работать через https?
2 ответа
Итак, я обнаружил, что между селеном 3.13 и 3.14 они изменили библиотеку http-запросов с httplib на urllib3 и, похоже, не обрабатывали сертификаты должным образом.
Итак, я обнаружил, что у меня есть следующие варианты: 1) использовать селен 3.13 на стороне клиента 2) использовать селен 3.14 на стороне клиента и отключить импорт InsecureRequestWarnings urllib3 urllib3.disable_warnings (urllib3.exceptions.InsecureRequestWarning)
3) использовать клиентскую часть selenium 3.14 и взломать файл remote_connections.py, заменив все экземпляры urllib3.PoolManager() на urllib3.PoolManager(cert_reqs='CERT_REQUIRED', ca_certs=certifi.where())
другая вещь, которую стоит отметить, это то, что я думаю, что Pycharm кэширует библиотеки, поэтому, если я делаю обновление в пипсах и не очищаю кеш, я получаю смешанные результаты
4) Каким-то образом заверните remote_connection.py в мою собственную библиотеку и импортируйте добавление класса в параметры PoolManager - это выше моих возможностей.
Это уже не вопрос, а информация, которую я могу помочь некоторым другим, которые получают небезопасные предупреждения urllib3 при использовании https для удаленных вызовов селена.
Я смог заставить это работать, введя наш пользовательский сертификат CA, используя следующий подход (это проверено на версии 4.2.0):
# context: https://github.com/SeleniumHQ/selenium/pull/6536/files
rc = RemoteConnection(self.hub_url, keep_alive=False, ignore_proxy=False)
rc.set_certificate_bundle_path(self.ca_cert_path)
driver = webdriver.Remote(
command_executor=rc,
desired_capabilities=cap
)
важно, чтобы вы установили keep_alive=False, чтобы он не пытался создать сеанс до вызова создания удаленного сеанса (см. MR)