Selenium

Установка: 

pip install selenium==4.*

Поиск элементов с помощью Selenium

find_element(By.ID, value) — поиск по уникальному атрибуту id элемента. Если ваши разработчики проставляют всем элементам в приложении уникальный id, то вам повезло, и вы чаще всего будет использовать этот метод, так как он наиболее стабильный;

find_element(By.CSS_SELECTOR, value) — поиск элемента с помощью правил на основе CSS. Это универсальный метод поиска, так как большинство веб-приложений использует CSS для вёрстки и задания оформления страницам. Если find_element_by_id вам не подходит из-за отсутствия id у элементов, то скорее всего вы будете использовать именно этот метод в ваших тестах;

find_element(By.XPATH, value) — поиск с помощью языка запросов XPath, позволяет выполнять очень гибкий поиск элементов;

find_element(By.NAME, value) — поиск по атрибуту name элемента;

find_element(By.TAG_NAME, value) — поиск элемента по названию тега элемента;

find_element(By.CLASS_NAME, value) — поиск по значению атрибута class;

find_element(By.LINK_TEXT, value) — поиск ссылки на странице по полному совпадению;

find_element(By.PARTIAL_LINK_TEXT, value) — поиск ссылки на странице, если текст селектора совпадает с любой частью текста ссылки.

Пример:

from selenium import webdriver

from selenium.webdriver.common.by import By

try:

    browser = webdriver.Edge()

    browser.get("http://suninjuly.github.io/huge_form.html")

    elements = browser.find_elements(By.TAG_NAME, "input")

    for element in elements:

        element.send_keys("Мой ответ")

    button = browser.find_element(By.CSS_SELECTOR, "button.btn")

    button.click()

finally:

    # успеваем скопировать код за 30 секунд

    time.sleep(30)

    # закрываем браузер после всех манипуляций

    browser.quit()

Скрыть запуск браузера:

browser = webdriver.EdgeOptions()

browser.add_argument("--headless")

browser.add_argument("--incognito")

browser = webdriver.Edge(options=browser)

browser.get("https://astorchak.blogspot.com/")

Запуск браузера с расширениями

Для Linux:
Путь в Linux: ~/.config/google-chrome/Default/Extensions
# Путь к файлу с расширением Google Translate
extension_path = "chrome/2.0.13_0.crx"

# Создание экземпляра драйвера с загрузкой расширения
options = webdriver.ChromeOptions()
options.add_extension(extension_path)
driver = webdriver.Chrome(options=options)

# Открыть Google Translate
driver.get('https://translate.google.com/')

Как работать с элементами типа checkbox и radiobutton

option = browser.find_element(By.CSS_SELECTOR, "[value='python']")

option.click()

Метод get_attribute

<input class="check-input" type="radio" name="ruler" id="peopleRule" value="people" checked>

Найдём этот элемент с помощью WebDriver:

people_radio = browser.find_element(By.ID, "peopleRule")

Найдём атрибут "checked" с помощью встроенного метода get_attribute и проверим его значение:

people_checked = people_radio.get_attribute("checked")

print("value of people radio: ", people_checked)

assert people_checked is not None, "People radio is not selected by default"

Работа со списками

<label for="dropdown">Выберите язык программирования:</label>

<select id="dropdown" class="custom-select">

 <option selected>--</option>

 <option value="1">Python</option>

 <option value="2">Java</option>

 <option value="3">JavaScript</option>

</select>

from selenium.webdriver.support.ui import Select

select = Select(browser.find_element(By.TAG_NAME, "select"))

select.select_by_value("1") # ищем элемент с текстом "Python"

Можно использовать еще два метода: select.select_by_visible_text("text") и select.select_by_index(index). Первый способ ищет элемент по видимому тексту, например, select.select_by_visible_text("Python") найдёт "Python" для нашего примера.

Метод execute_script

from selenium import webdriver

browser = webdriver.Chrome()

browser.execute_script("alert('Robots at work');")

В итоге, чтобы кликнуть на перекрытую кнопку, нам нужно выполнить следующие команды в коде:

button = browser.find_element(By.TAG_NAME, "button")

browser.execute_script("return arguments[0].scrollIntoView(true);", button)

button.click()

Также можно проскроллить всю страницу целиком на строго заданное количество пикселей. Эта команда проскроллит страницу на 100 пикселей вниз:

browser.execute_script("window.scrollBy(0, 100);")

Загрузка файлов

Пример кода, который позволяет указать путь к файлу 'file.txt', находящемуся в той же папке, что и скрипт, который вы запускаете:

import os 

current_dir = os.path.abspath(os.path.dirname(__file__))    # получаем путь к директории текущего исполняемого файла 

file_path = os.path.join(current_dir, 'file.txt')           # добавляем к этому пути имя файла 

element.send_keys(file_path)

Alerts

Для этого нужно сначала переключиться на окно с alert, а затем принять его с помощью команды accept():

alert = browser.switch_to.alert

alert.accept()

Чтобы получить текст из alert, используйте свойство text объекта alert:

alert = browser.switch_to.alert

alert_text = alert.text

Другой вариант модального окна, который предлагает пользователю выбор согласиться с сообщением или отказаться от него, называется confirm. Для переключения на окно confirm используется та же команда, что и в случае с alert:

confirm = browser.switch_to.alert

confirm.accept()

Для confirm-окон можно использовать следующий метод для отказа:

confirm.dismiss()

Третий вариант модального окна — prompt — имеет дополнительное поле для ввода текста. Чтобы ввести текст, используйте метод send_keys():

prompt = browser.switch_to.alert

prompt.send_keys("My answer")

prompt.accept()

Переход на новую вкладку браузера

Для переключения на новую вкладку надо явно указать, на какую вкладку мы хотим перейти. Это делается с помощью команды switch_to.window:

browser.switch_to.window(window_name)

Чтобы узнать имя новой вкладки, нужно использовать метод window_handles, который возвращает массив имён всех вкладок. Зная, что в браузере теперь открыто две вкладки, выбираем вторую вкладку:

new_window = browser.window_handles[1]

Также мы можем запомнить имя текущей вкладки, чтобы иметь возможность потом к ней вернуться:

first_window = browser.window_handles[0]

Implicit Waits

Улучшим наш тест с помощью неявных ожиданий. Для этого нам нужно будет убрать time.sleep() и добавить одну строчку с методом implicitly wait:

from selenium import webdriver

from selenium.webdriver.common.by import By

browser = webdriver.Chrome()

# говорим WebDriver искать каждый элемент в течение 5 секунд

browser.implicitly_wait(5)

browser.get("http://suninjuly.github.io/wait1.html")

button = browser.find_element(By.ID, "verify")

button.click()

message = browser.find_element(By.ID, "verify_message")

assert "successful" in message.text

Теперь мы можем быть уверены, что при небольших задержках в работе сайта наши тесты продолжат работать стабильно. На каждый вызов команды find_element WebDriver будет ждать 5 секунд до появления элемента на странице прежде, чем выбросить исключение NoSuchElementException.

Explicit Waits (WebDriverWait и expected_conditions)

Чтобы тест был надежным, нам нужно не только найти кнопку на странице, но и дождаться, когда кнопка станет кликабельной. Для реализации подобных ожиданий в Selenium WebDriver существует понятие явных ожиданий (Explicit Waits), которые позволяют задать специальное ожидание для конкретного элемента. Задание явных ожиданий реализуется с помощью инструментов WebDriverWait и expected_conditions. Улучшим наш тест:

from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from selenium import webdriver

browser = webdriver.Chrome()

browser.get("http://suninjuly.github.io/wait2.html")

# говорим Selenium проверять в течение 5 секунд, пока кнопка не станет кликабельной

button = WebDriverWait(browser, 5).until(

        EC.element_to_be_clickable((By.ID, "verify"))

    )

button.click()

message = browser.find_element(By.ID, "verify_message")

assert "successful" in message.text

element_to_be_clickable вернет элемент, когда он станет кликабельным, или вернет False в ином случае.

Обратите внимание, что в объекте WebDriverWait используется функция until, в которую передается правило ожидания, элемент, а также значение, по которому мы будем искать элемент. В модуле expected_conditions есть много других правил, которые позволяют реализовать необходимые ожидания:

title_is

title_contains

presence_of_element_located

visibility_of_element_located

visibility_of

presence_of_all_elements_located

text_to_be_present_in_element

text_to_be_present_in_element_value

frame_to_be_available_and_switch_to_it

invisibility_of_element_located

element_to_be_clickable

staleness_of

element_to_be_selected

element_located_to_be_selected

element_selection_state_to_be

element_located_selection_state_to_be

alert_is_present

Работа со скриншотами

webdriver.get_screenshot_as_file("../file_name.jpg") - Сохраняет скриншот страницы в файл по указанному пути. Возвращает True если всё прошло успешно, и False при ошибках ввода-вывода.

webdriver.save_screenshot("file_name.jpg") - Сохраняет скриншот в папке с проектом.

webdriver.get_screenshot_as_png() - Возвращает скриншот в виде двоичных данных (binary data), которые можно передать или сохранить в файл в конструкторе with/as;

webdriver.get_screenshot_as_base64() - Возвращает скриншот в виде строки в кодировке Base64. Удобно для встроенных изображений в HTML.

Открытие и закрытие страниц и браузера

webdriver.get("http://example_url.ru") - Открывает указанный URL в браузере.

webdriver.quit() - Закрывает все вкладки и окна, завершает процесс драйвера, освобождает ресурсы.

webdriver.close() - Закрывает только текущую вкладку.

Исполнение JavaScript

webdriver.execute_script("script_code") - Выполняет JavaScript код на текущей странице.

webdriver.execute_async_script("script_code" , *args ) - Асинхронно выполняет JavaScript код. Удобно для работы с AJAX и промисами.

Время ожидания

webdriver.set_page_load_timeout() - Устанавливает таймаут на загрузку страницы. Выбрасывает исключение, если время вышло.

Поиск элементов

webdriver.find_element(By.ID, 'example_id') - Возвращает первый найденный элемент по заданному локатору.

webdriver.find_elements(By.ID, 'example_id') - Возвращает список всех элементов, соответствующих локатору.

Работа с окном браузера

webdriver.get_window_position() - Возвращает словарь с текущей позицией окна браузера ({'x': 10, 'y': 50}).

webdriver.maximize_window() - Разворачивает окно на весь экран.

webdriver.minimize_window() - Сворачивает окно.

webdriver.fullscreen_window()  - Переводит окно в полноэкранный режим, как при нажатии F11.

webdriver.get_window_size() - Возвращает размер окна в виде словаря ({'width': 945, 'height': 1020}).

webdriver.set_window_size(800,600) - Устанавливает новый размер окна.

Работа с cookies

webdriver.get_cookies()  - Возвращает список всех cookies.

webdriver.get_cookie(name_cookie) - Возвращает конкретную cookie по имени.

webdriver.add_cookie(cookie_dict) - Добавляет новую cookie к вашему текущему сеансу;

webdriver.delete_cookie(name_cookie) - Удаляет cookie по имени.

webdriver.delete_all_cookies() - удаляет все файлы cookie в рамках текущего сеанса;

Ожидание элементов

webdriver.implicitly_wait(10) - Устанавливает неявное ожидание на поиск элементов или выполнение команд.

webdriver.WebDriverWait(driver, timeout).until(condition)

Работа с элементами

element.click() - Симулирует клик по элементу.

element.send_keys("text") - Вводит текст в текстовое поле. Очень полезно для автоматизации ввода данных.

element.clear() - Очищает текстовое поле.

element.is_displayed() - Проверяет, отображается ли элемент на странице.

element.is_enabled() - Проверяет, доступен ли элемент для взаимодействия (например, не заблокирован).

element.is_selected() - Проверяет, выбран ли элемент (актуально для радиокнопок и чекбоксов).

element.get_attribute("attribute") - Возвращает значение указанного атрибута элемента.

element.text - Возвращает текст элемента.

element.submit() - Отправляет форму, в которой находится элемент.

Фреймы

webdriver.switch_to.frame("frame_name") - Переключает фокус на указанный фрейм.

webdriver.switch_to.default_content() - Возвращает фокус на основное содержимое страницы, выходя из фрейма.

JavaScript Alerts

webdriver.switch_to.alert - Переключает фокус на всплывающее окно JavaScript.


Признаки "плохого кода"

Кратко рассмотрим 12 признаков, когда код можно улучшить: 1. Duplicated Code  — иногда повторяющийся код не всегда несет в себе пользу. Выде...