browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Remote()
| execute_script() | запустить скрипт |
browser.execute_script("return arguments[0].scrollIntoView(true);",
web_element)
|
| find_element() | найти элемент на странице |
browser.find_element(By.CSS_SELECTOR, "a.user-account") |
| get() | открыть ссылку - link |
browser.get('http://iktex.ru')
|
| implicitly_wait() | неявное ожидание |
browser.implicitly_wait(5) |
| refresh() | перезагрузить страницу |
browser.refresh() |
|
| перезагрузить страницу |
|
Идея: найти по селектору webelement и применить к нему действие.
webelement = browser.find_element(By.CSS_SELECTOR, "a.user-account")
Для webelement-а часто применяются функции:
| Selenium | Selene | Действие | Комментарий | |
|
from selenium. webdriver. remote. webelement import WebElement element: WebElement |
from selene. coreb. entity import Element from selene import be, have, query element: Element | |||
| element. get_element( 'inside_ locator_ name') | element. s('inside_ locator_ name') | Получить вложенный (дочерний) элемент по внутреннему локатору | ||
| element. send_keys() | отправить символы в element - либо эмулировать нажатия клавиш, либо записать текст в объект (если в объекте есть текст, то send_keys() добавляет текст в конец существующего) |
Отправить (записать) текст в поле edit_field:
edit_field.send_keys("New Text")
Очистить поле в edit_field: edit_field.send_keys(Keys.CONTROL + "a") #edit_field.send_keys(Keys.SHIFT, Keys.ARROW_UP) edit_field.send_keys(Keys.DELETE) | ||
| element. clear() | Очистить текстовое поле elemnt-а, но почему-то не срабатывает - лучше очищать способом выше | |||
| element. text | Получить надпись на объекте, если она есть. Если текста нет, то получим ошибку. | |||
| element. click() | 'Нажать' (Кликнуть) на element - нажать на кнопку или передать фокус объекту | |||
| element. get_attribute( 'attribute_name' ) | element. get( query. attribute( 'attribute_name' )) | Получить значение атрибута у element-а. Если текстовое значение объекта дублируется в атрибуте объекта, например в атрибуте title, то иногда удобнее и правильнее получать текст из атрибута. | ||
| element. value_of_css_property( 'property_name' ) | Получить значение CSS-свойства у element-а (например свойства color). | |||
| element. is_displayed() | element. should( be.visible) | Элемент видим / отображается на странице | ||
|
| element. should( be.hidden) | |||
| element. is_enabled() | element. should( be.enable) | для кнопок (button) | ||
| element. is_disabled() | element. should( be.disable) | для кнопок (button) | ||
| element. is_selected() | что-то есть, но не срабатывает пока | для checkbox-ов | ||
| element. matching( be.blank) | Поле должно быть пустым | |||
| element. should( be. not_.blank) | Поле не должно быть пустым | |||
Неявные ожидания - Implicitly Wait
browser.implicitly_wait(5)
Явные ожидания - Explicit Waits (WebDriverWait и expected_conditions)
Selenium 4.15.2 documentation → selenium.webdriver.support.expected_conditions
| title_is | соответствует ли заголовок текущей страницы ожидаемому |
| title_contains | содержит ли заголовок текущей страницы ожидаемую строку |
| presence_of_element_located | добавлен ли элемент в дерево DOM, это не означает, что элемент должен быть видимым |
| visibility_of_element_located | является ли элемент видимым. Видимый означает, что элемент не скрыт, а ширина и высота элемента не равны 0 |
| visibility_of | сделайте то же самое, что и вышеупомянутый метод, за исключением того, что вышеупомянутый метод должен быть передан локатору, и этот метод напрямую передает позиционированный элемент. |
| presence_of_all_elements_located | существует ли хотя бы один элемент в дереве DOM. Например, если класс из n элементов на странице - 'column-md-3', то, пока существует 1 элемент, этот метод вернет True. |
| text_to_be_present_in_element | соответствует ли текст Ожидаемому тексту в элементе |
| text_to_be_present_in_element_value | соответствует ли значение в value Ожидаемому значению в элементе |
| frame_to_be_available_and_switch_to_it | можно ли переключить кадр, если возможно, вернуть True и переключиться, в противном случае вернуть False |
| invisibility_of_element_located | элемент в дереве DOM не существует или он (элемент) не виден |
| element_to_be_clickable | является ли элемент видимым и активным, в этом случае он называется интерактивным (it is Displayed and Enabled) |
| staleness_of | подождите, пока элемент будет удален из дерева DOM. Обратите внимание, что этот метод также возвращает True или False |
| element_to_be_selected | выбран ли элемент, обычно используется в раскрывающемся списке |
| element_located_to_be_selected | |
| element_selection_state_to_be | соответствует ли выбранное состояние элемента ожиданиям. |
| element_located_selection_state_to_be | та же функция, что и вышеупомянутый метод, за исключением того, что вышеупомянутый метод передает обнаруженный элемент, а этот метод передает локатор |
| alert_is_present | есть ли на странице предупреждение |
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
link = "http://selenium1py.pythonanywhere.com/catalogue/coders-at-work_207/"
def test_check_present_basket_button(browser):
browser.get(link)
button = WebDriverWait(browser, 5).until(
EC.visibility_of_element_located((By.CSS_SELECTOR,
'button.btn-add-to-basket'))
)
assert button is not None, "There is Basket button?"
conftest.py
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as Options_Chrome
import os
def pytest_addoption(parser):
parser.addoption('--browser_name', action='store', default='chrome',
help='Choose browser: chrome or firefox')
parser.addoption('--language', action='store', default="en",
help='Choose language: ru, en, es, ... etc')
parser.addoption('--headless', action='store', default='true',
help='Open a browser invisible, without GUI is used by default')
parser.addoption('--no_gpu', action='store_true', default='false',
help='NO GPU')
parser.addoption('--no_img', action='store_true', default='false',
help='Load pictures OFF')
parser.addoption('--size', action='store', default="1600x900",
help='Open a browser with window size WWWWxHHHH, e.g. 1600x900')
@pytest.fixture(scope='function')
def browser(request):
browser_name = request.config.getoption('browser_name')
user_language = request.config.getoption('language')
headless = request.config.getoption('headless')
no_gpu = request.config.getoption('no_gpu')
no_img = request.config.getoption('no_img')
browser = None
if browser_name == 'chrome':
print('\nstart chrome browser for test..')
chrome_options = Options_Chrome() #
if headless == 'true':
chrome_options.add_argument('-headless')
if no_gpu == 'true':
chrome_options.add_argument('--disable-gpu')
if no_img == 'true':
chrome_options.add_argument(
'--blink-settings=imagesEnabled=false'
)
size = request.config.getoption('size')
width, height = map(int, size.split('x'))
# chrome_options.add_argument(f'--window-size={width},{height}')
# chrome_options.add_argument('--window-size=1350,800')
chrome_options.add_experimental_option(
'prefs', {'intl.accept_languages': user_language}
)
browser = webdriver.Chrome(options=chrome_options)
browser.set_window_size(width, height)
elif browser_name == 'firefox':
print('\nStart firefox browser for test..')
if headless == 'true':
os.environ['MOZ_HEADLESS'] = '1'
fp = webdriver.FirefoxProfile()
fp.set_preference('intl.accept_languages', user_language)
browser = webdriver.Firefox(firefox_profile=fp)
browser.implicitly_wait(5)
elif browser_name == "hub":
# desired_capabilities={
'browserName': 'firefox', 'javascriptEnabled': True
})
browser = webdriver.Remote(
command_executor='http://localhost:4444/wd/hub',
desired_capabilities={'browserName': 'chrome', 'javascriptEnabled': True})
else:
raise pytest.UsageError(
'--browser_name should be chrome or firefox'
)
yield browser
print('\nQuit browser..')
browser.quit()
Проскроллировать до конца страницы (scroll to bottom)
© How to scroll to the end of the page using selenium in Python?
def scroll_to_bottom(driver, stop_position: int = 11600, wait_time: float = 0.4):
"""
Проскроллировать страницу до низу
:param wait_time: время ожидания прогрузки следующих элементов страницы
:param stop_position: позиция остановки, при превышении которой
остановить скроллинг страницы
0 - игнорировать stop_position
"""
old_position = 0
new_position = -1
while (new_position != old_position) and \
((stop_position == 0) or (stop_position > new_position)):
# Получить текущую позицию скроллера
old_position = driver.execute_script(
("return (window.pageYOffset !== undefined) ?"
" window.pageYOffset : (document.documentElement ||"
" document.body.parentNode || document.body);"))
# Подождать и проскроллировать
time.sleep(wait_time)
driver.execute_script((
"var scrollingElement = (document.scrollingElement ||"
" document.body);scrollingElement.scrollTop ="
" scrollingElement.scrollHeight;"))
# Получить новую позицию скроллера
new_position = driver.execute_script(
("return (window.pageYOffset !== undefined) ?"
" window.pageYOffset : (document.documentElement ||"
" document.body.parentNode || document.body);"))
scroll_to_bottom(driver)
Нажать Esc, Ctrl + Tab
© How to send ESC key to close pop up window using Python and Selenium?from selen... import browser from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys # Закрыть всплывающее окно (например, окно печати) ActionChains(browser.driver).send_keys(Keys.ESCAPE).perform() # Ctrl + Tab - переключиться на соседнюю вкладку actions = ActionChains(browser.driver) actions.key_down(Keys.CONTROL).key_down(Keys.TAB).key_up(Keys.TAB).key_up(Keys.CONTROL).perform()
Закрыть всплывающее alert-окно, если появится
© How to send ESC key to close pop up window using Python and Selenium?
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
try:
WebDriverWait(
browser.driver, timeout=3
).until(EC.alert_is_present(),'время ожидания Alert-окна истекло')
alert = browser.driver.switch_to_alert()
alert.accept()
# alert.dismiss()
print('Alert-окно закрыто')
except Exception as e:
print('Alert-окна не было')
Получить свойство CSS/стиль используя JavaScript:
def get_z_index(self, element: ElementWithName):
return browser.driver.execute_script(
"return window.getComputedStyle(arguments[0]).zIndex",
element()
)
@allure.step("Получить '{style_prop}' элемента [{element}]")
def get_element_style_js(self, element: Element, style_prop: str = "zIndex"):
return self.driver.execute_script(
"return arguments[0].style.arguments[1]",
element(), style_prop
)
@allure.step("Получить '{style_prop}' элемента [{element}]")
def get_element_style_v2(self, element: Element, style_prop: str = "zIndex"):
return self.driver.execute_script(
"if (window.getComputedStyle) "
"{return document.defaultView.getComputedStyle(arguments[0],null).getPropertyValue(arguments[1]);}"
"else if (arguments[0].currentStyle) "
"{return arguments[0].currentStyle[arguments[1]];}",
element(), style_prop
)
@allure.step("Получить '{style_prop}' элемента [{element}]")
def get_element_style_v3(self, element: Element, style_prop: str = "z-index"):
return self.driver.execute_script(
"window.getZIndex = function (e) "
"{var z = window.getComputedStyle(e).getPropertyValue(arguments[1]);"
"if (isNaN(z)) return window.getZIndex(e.parentNode);"
"return z;};"
"return window.getZIndex(arguments[0]);",
element(), style_prop
)
Получить атрибут у WebElement-а (например, содержимое class):
from typing import List
from bs4 import BeautifulSoup
from selenium.webdriver.remote.webelement import WebElement
def get_webelement_list_attrs(self, element: WebElement, attr: str = 'class') -> List[str]:
elementHTML = element.get_attribute('outerHTML')
elementSoup = BeautifulSoup(elementHTML, 'html.parser')
list_tags = elementSoup.find_all()
list_attrs = []
for tag in list_tags:
if tag:
tag_attrs = tag.get(attr)
if tag_attrs:
list_attrs.extend(tag_attrs)
return list_attrs
Получить WebElement, который перекрывает указанный WebElement:
© Selenium can't click element because other element obscures it -> искать getOverlappingElement(driver, button)
from typing import Optional
from selenium import webdriver
from selenium.webdriver.remote.webelement import WebElement
def get_overlapping_element(driver: webdriver, element: WebElement) -> Optional[WebElement]:
"""
Определить элемент, расположенный по центру прямоугольника
предполагаемого элемента. Если элементы совпадают, то перекрытия нет!
"""
rect = element.get(query.rect)
result = driver.execute_script(
"return document.elementFromPoint(arguments[0], arguments[1]);",
rect['x'] + rect['width'] // 2, rect['y'] + rect['height'] // 2
)
if result == element:
result = None
return result