Браузер находится под удаленным управлением selenium
Для тех, кто имеет опыт работы с QTP / UFT, возможность протестировать один и тот же браузер после разрыва соединения обычно несложно.
Если мы запустим приведенный выше код в QTP / UFT, он выдаст ошибку в строке № 2, и мы сможем повторно запустить код из строки № 3, и он будет работать и перемещаться внутри браузера, который мы открыли ранее.
UFT также работает, когда браузер запускается вручную, а не через скрипт. Однако в Selenium это невозможно из-за архитектурных различий.
Поскольку разработчики Selenium не видят в этом особого смысла, они категорически против добавления этого в код Selenium.
В этой статье мы увидим более чистый и эффективный способ добиться повторного использования браузера.
Запуск браузера в Selenium
Чтобы запустить браузер в Selenium с использованием Python, мы просто импортируем веб-драйвер и запускаем браузер.
Если мы запустим приведенный выше код, он запустит браузер и выйдет. Поскольку созданный нами объект браузера был уничтожен, мы больше не можем управлять этим браузером с помощью скрипта. Это зомби-браузер с точки зрения Selenium.
Теперь, когда мы создаем объект WebDriver (Firefox, сhromer или любой другой браузер) в Selenium, происходит несколько вещей:
- Запускается предполагаемый агент браузера (chromedriver для chrome, geckodriver для Firefox и т. Д.)
- Создается исполнитель команд. Этот объект отвечает за отправку команд агенту.
- Устанавливается новый сеанс с агентом, который, в свою очередь, связывается с браузером. session_id создается для идентификации сеанса.
Информация из шагов №2 и №3 важна для нас, чтобы мы могли воссоздать объект драйвера. Итак, давайте обновим наш скрипт, чтобы вывести эту информацию.
Пример вывода приведенного выше кода приведен ниже:
Создание драйвера с использованием идентификатора сеанса и Command Executor
Итак, теперь у нас есть session_id и executor_url . Попробуем воссоздать сеанс.
Моей первой попыткой было создать драйвер с помощью RemoteWebDriver или WebDriver
Тестирование в браузере Firefox
Мы протестировали наш предыдущий подход в браузере Chrome. Давайте также протестируем наше решение в Firefox:
Ошибка в нашем скрипте в следующем:
driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities=<>)
Ошибка возникает в response = self.execute(Command.NEW_SESSION, parameters) . Проблема в том, что снова geckodriver не поддерживает newSession . Следовательно, нужен способ переопределить функцию выполнения при создании драйвера.
Мы создаем новую функцию, которая возвращает фиктивный ответ на newSession с нашим sessionId. Обновленный код приведен ниже:
Этот код отлично работает. Единственное предостережение в том, что мы теряем фактические возможности, которые браузер возвращал при запуске. В большинстве случаев это не должно иметь большого значения.
Браузер в режиме ожидания
В одном из наших проектов парсинга мы хотим завершить наш скрипт и оставить браузер в режиме ожидания. При повторном запуске скрипта он повторно использует последний браузер и продолжает работу. Это может стать важным фактором при очистке сайтов с более высокой степенью защиты.
Функциональность фреймворка
Одна из наших платформ автоматизации, позволяющая пользователям выполнять коды автоматизации из любой точки. Для реализации такой функции было важно иметь возможность воссоздать последний драйвер сеанса.
You can use WebDriver remotely the same way you would use it locally. The primary difference is that a remote WebDriver needs to be configured so that it can run your tests on a separate machine.
A remote WebDriver is composed of two pieces: a client and a server. The client is your WebDriver test and the server is simply a Java servlet, which can be hosted in any modern JEE app server.
To further customize our test configuration, we can add other desired capabilities.
Browser options
For example, suppose you wanted to run Chrome on Windows XP, using Chrome version 67:
Local file detector
The Local File Detector allows the transfer of files from the client machine to the remote server. For example, if a test needs to upload a file to a web application, a remote WebDriver can automatically transfer the file from the local machine to the remote web server during runtime. This allows the file to be uploaded from the remote machine running the test. It is not enabled by default and can be enabled in the following way:
Once the above code is defined, you can upload a file in your test in the following way:
Tracing client requests
For client-side setup, follow the steps below.
Add the required dependencies
Installation of external libraries for tracing exporter can be done using Maven. Add the opentelemetry-exporter-jaeger and grpc-netty dependency in your project pom.xml:
Add/pass the required system properties while running the client
Please refer to Tracing Setup for more information on external dependencies versions required for the desired Selenium version.
More information can be found at:
Selenium Level Sponsors
Support the Selenium Project
Want to support the Selenium project? Learn more or view the full list of sponsors.
In order to create a new session by Selenium WebDriver, the local end should provide the basic capabilities to the remote end. The remote end uses the same set of capabilities to create a session and describes the current session features.
WebDriver provides capabilities that each remote end will/should support the implementation. The following capabilities are supported by WebDriver:
browserName:
This capability is used to set the browserName for a given session. If the specified browser is not installed at the remote end, the session creation will fail.
browserVersion:
This capability is optional, this is used to set the available browser version at remote end. For Example, if ask for Chrome version 75 on a system that only has 80 installed, the session creation will fail.
pageLoadStrategy:
When navigating to a new page via URL, by default Selenium will wait until the Document’s Ready State is “complete.” The document.readyState property of a document describes the loading state of the current document. By default, WebDriver will hold off on completing a navigation method (e.g., driver.navigate().get() ) until the document ready state is complete . This does not necessarily mean that the page has finished loading, especially for sites like Single Page Applications that use a lot of JavaScript to dynamically load content after the Ready State returns complete. Note also that this behavior does not apply to navigation that is a result of clicking an element or submitting a form.
If a page takes a long time to load as a result of downloading assets (e.g., images, css, js) that aren’t important to the automation, you can change from the default parameter of normal to eager or none to speed up the session. This value applies to the entire session, so make sure that your waiting strategy is sufficient to minimize flakiness.
The page load strategy queries the document.readyState as described in the table below:
Strategy | Ready State | Notes |
---|---|---|
normal | complete | Used by default, waits for all resources to download |
eager | interactive | DOM access is ready, but other resources like images may still be loading |
none | Any | Does not block WebDriver at all |
normal
This will make Selenium WebDriver to wait for the entire page is loaded. When set to normal, Selenium WebDriver waits until the load event fire is returned.
By default normal is set to browser if none is provided.
Selenium — это инструмент для автоматизированного управления браузерами. Наиболее популярной областью применения Selenium является автоматизация тестирования веб-приложений. Однако можно автоматизировать любые другие рутинные действия, выполняемые через браузер.
Для браузера Firefox загружаем драйвер geckodriver для своей версии ОС и прописываем путь к нему в переменной окружения PATH .
Пробуем управлять браузером удаленно:
Объект WebDriver имеет большое количество методов, предназначенных для поиска элементов на странице. Эти методы можно поделить на две группы: find_element_*() и find_elements_*() . Методы первой группы возвращают одиночный объект WebElement , который представляет первый из найденных на странице элементов. Методы второй группы возвращают список объектов WebElement , соответствующих запросу.
- find_element_by_id() — элемент с указанным id
- find_element_by_name() — элемент с указанным значением атрибута name
- find_element_by_tag_name() — элемент с указанным именем тега
- find_element_by_class_name() — элемент с указанным CSS-классом
- find_element_by_css_selector() — элемент с указанным CSS-селектором
- find_element_by_link_text() — элемент с указанным текстом
- find_element_by_partial_link_text() — элемент , содержащий указанный текст
- find_elements_by_name() — элементы с указанным значением атрибута name
- find_elements_by_tag_name() — элементы с указанным именем тега
- find_elements_by_class_name() — элементы с указанным CSS-классом
- find_elements_by_css_selector() — элементы с указанным CSS-селектором
- find_elements_by_link_text() — элементы с указанным текстом
- find_elements_by_partial_link_text() — элементы , содержащие указанный текст
Находим поля «Имя пользователя» и «Пароль»:
Свойства и методы объекта WebElement :
- tag_name — имя тега
- get_attribute() — значение атрибута с указанным именем
- text — текст, содержащийся в элементе
- clear() — удаляет текст, введенный в текстовое поле
- is_displayed() — возвращает True , если элемент видимый и False в противном случае
- is_enabled() — возвращает True для элемента ввода, если элемент активизирован и False в противном случае
- is_selected() — возвращает True для checkbox , если элемент выбран и False в противном случае
- location — словарь с ключами x и y позиции элемента на странице
Клик на элементе страницы
Объект WebElement имеет метод click() , имитирующий клик мышкой на элементе. Этот метод можно использовать для перехода по ссылке, для отправки данных формы или инициирования любого другого действия, которое может быть запущено кликом на элементе.
Заполнение и отправка формы
Для отправки данных формы:
- находим нужные поля
- заполняем их, используя метод send_keys()
- вызываем метод submit() для любого элемента формы или метод click() для кнопки Submit
Отправка кодов специальных клавиш
Selenium включает модуль для отправки в браузер нажатий специальных клавиш: Up, Down, Left, Right, Enter, Return, Home, PageUp, PageDown, End, Escape, BackSpace, Delete, F1…F12, Tab.
Щелчки на кнопках браузера
Модуль Selenium также может имитировать щелчки на кнопках браузера:
Дополнительно
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
По неизвестным причинам мой браузер очень медленно открывает тестовые страницы моего удаленного сервера. Поэтому я думаю, смогу ли я снова подключиться к браузеру после выхода из скрипта, но не выполнять webdriver.quit() , это оставит браузер открытым. Это, вероятно, вид крючка или ручки веб-драйвера. Я просмотрел документацию по selenium API, но не нашел никакой функции. Я использую Chrome 62, x64, Windows 7, Селен 3.8.0. Я буду очень признателен за решение вопроса.
3 ответа
Нет , вы не можете повторно подключиться к предыдущей Web Browser после выхода из сценария. Даже если вы можете извлечь Session ID , Cookies и другие атрибуты сеанса из предыдущего Browsing Session тем не менее вы не сможете передать эти атрибуты как HOOK WebDriver .
Более понятным способом было бы позвонить в webdriver.quit() и указать новый Browsing Session
История:
Ранее были некоторые обсуждения и попытки повторно подключить WebDriver к существующему текущему сеансу просмотра. Вы можете найти обсуждения в этих QA:
Да , это довольно легко сделать.
Селен Сеанс веб-драйвера представлен URL-адресом соединения и сессионным идентификатором, вы просто переподключаетесь к существующему.
Отказ от ответственности - в этом подходе используются внутренние свойства селена (в некотором роде "private"), которые могут изменяться в новых выпусках; вам лучше не использовать его для производственного кода; Лучше не использовать его против удаленного SE (вашего хаба или провайдера, такого как BrowserStack /Sauce Labs), потому что в конце объясняется утечка caveat /resource.
Когда запускается экземпляр веб-драйвера, вам необходимо получить вышеупомянутые свойства; Образец:
Теперь, когда эти два свойства известны, может подключиться другой экземпляр; «хитрость» заключается в том, чтобы инициировать драйвер Remote и предоставить _url выше - таким образом, он подключится к запущенному процессу селена:
Когда он будет запущен, вы увидите, что открывается новое окно браузера.
Это связано с тем, что после запуска драйвера библиотека selenium автоматически запускает для него новый сеанс - и теперь у вас есть 1 процесс веб-драйвера с двумя сеансами (экземплярами браузера).
Если вы перейдете к URL-адресу, вы увидите, что он выполняется на том новом экземпляре браузера, а не на том, который остался от предыдущего запуска, что не соответствует желаемому поведению.
На этом этапе необходимо сделать две вещи: а) закрыть текущий сеанс SE («новый») и б) переключить этот экземпляр на предыдущий сеанс:
И это все - теперь вы подключены к предыдущему /уже существующему сеансу со всеми его свойствами (куки, LocalStorage и т. д.).
Кстати, вам не нужно указывать desired_capabilities при запуске нового удаленного драйвера - они сохраняются и наследуются от существующего сеанс, который вы взяли на себя.
Предупреждение - запуск процесса SE может привести к некоторому истощению ресурсов в системе.
Каждый раз, когда кто-то запускается, а затем не закрывается - как в первом фрагменте кода, - он будет оставаться там до тех пор, пока вы не убьете его вручную. Под этим я подразумеваю - например, в Windows - вы увидите процесс «chromedriver.exe», который вы должны завершить вручную, как только закончите с ним. Он не может быть закрыт драйвером, который подключился к нему, как к процессу удаленного селена.
Причина - всякий раз, когда вы запускаете локальный экземпляр браузера, а затем вызываете его метод quit() , он состоит из двух частей - первая удалить сеанс из экземпляра Selenium (что там сделано во втором фрагменте кода), а другой - остановить локальный сервис (chrome /geckodriver) - который обычно работает нормально.
Дело в том, что для удаленных сеансов отсутствует вторая часть - ваш локальный компьютер не может управлять удаленным процессом, это работа центра удаленного управления. Так что эта 2-я часть буквально является pass оператором python - запретом.
Если вы запустите слишком много служб Selen на удаленном концентраторе и не будете управлять им - это приведет к истощению ресурсов с этого сервера. Облачные провайдеры, такие как BrowserStack, принимают меры против этого - они закрывают сервисы без активности в течение последних 60-х и т. Д., И все же - это то, что вы не хотите делать.
А что касается локальных сервисов SE - просто не забывайте время от времени очищать ОС от потерянных драйверов селена, о которых вы забыли:)
Не вдаваясь в вопрос, почему вы думаете, что если оставить открытые окна браузера, это решит проблему медлительности, вам не нужен дескриптор для этого. Просто продолжайте выполнять тесты, не закрывая сеанс или, другими словами, не вызывая driver.quit() , как вы упомянули сами. Вопрос здесь, хотя рамки, которые идут со своим собственным бегуном? Нравится огурец?
В любом случае у вас должен быть какой-то код «настройки» и «очистки». Поэтому вам нужно убедиться, что на этапе «очистки» браузер вернулся в исходное состояние. Это значит:
- Отображается пустая страница
- Файлы cookie удаляются для сеанса
Похожие вопросы
Популярные теги
Читайте также: