#python #class #selenium-webdriver #python-descriptors
Вопрос:
Как работает этот класс дескрипторов в руководстве Selenium?
from selenium.webdriver.support.ui import WebDriverWait
class BasePageElement(object):
"""Base page class that is initialized on every page object class."""
def __set__(self, obj, value):
"""Sets the text to the value supplied"""
driver = obj.driver
WebDriverWait(driver, 100).until(
lambda driver: driver.find_element_by_name(self.locator))
driver.find_element_by_name(self.locator).clear()
driver.find_element_by_name(self.locator).send_keys(value)
def __get__(self, obj, owner):
"""Gets the text of the specified object"""
driver = obj.driver
WebDriverWait(driver, 100).until(
lambda driver: driver.find_element_by_name(self.locator))
element = driver.find_element_by_name(self.locator)
return element.get_attribute("value")
Я вижу, что SearchTextElement
класс наследует от него:
class SearchTextElement(BasePageElement):
"""This class gets the search text from the specified locator"""
#The locator for search box where search string is entered
locator = 'q'
Но у этого класса таинственным образом есть только одна строка, в которой объявляется ошибка локатора (которая, предположительно, поступает в self.locator
переменную при __get__()
вызове и __set__()
вызывается).
Затем этот класс, в свою очередь, инициируется в MainPage
классе для «объявления переменной, которая будет содержать полученный текст».:
class MainPage(BasePage):
"""Home page action methods come here. I.e. Python.org"""
# Declares a variable that will contain the retrieved text
search_text_element = SearchTextElement()
Отмечается, что в предоставленном тестовом коде поиск может быть выполнен путем установки этой переменной в строку:
main_page.search_text_element = "pycon"
main_page.click_go_button()
Обычно я бы использовал одну функцию поиска, например:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.python.org")
def search(keyword):
wait = WebDriverWait(driver, 100)
search = wait.until(EC.presence_of_element_located((By.NAME, 'q')))
search.send_keys(keyword)
search.submit()
Then simply call (if this function is in the MainPage
class) main_page.search("pycon")
to trigger the search.
Questions
- Why is this approach not preferred when designing a Selenium
Scraper App? - Создание экземпляра
SearchTextElement()
волшебным образом дает нам переменную для хранения входного текста. Это, по-видимому, вызывает__set__
функцию для выполнения работы. Как его использовать в контексте получения некоторого значения от элемента в результатах поиска? - В этом контексте хорошей практикой должно быть хранение всех локаторов в одном месте,
locators.py
чтобы код можно было легко переделать для использования на других веб — сайтах. В моей собственной функции поиска выше,(By.NAME, 'q')
может быть легко сохранена как КОНСТАНТА вMainPageLocators
классеlocators.py
в. Как следует подходить к исправлениюSearchTextElement.locator
, чтобы оно не было жестко закодировано, как в приведенном выше примере?