这是我的 WebUtils 类:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def wait_for_element(func):
def wrapper(*args, **kwargs):
loctype, locvalue = args[-1]
driver = args[0]
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((loctype, locvalue)))
element.click()
return func(driver, *args, **kwargs)
return wrapper
class WebUtils:
@wait_for_element
def sendKeys(self, driver, string, element):
loctype, locvalue = element
print(loctype, locvalue)
driver.find_element(loctype, locvalue).send_keys(string)
@wait_for_element
def clickElement(self, driver, element):
loctype, locvalue = element
print(loctype, locvalue)
driver.find_element(loctype, locvalue).click()
此外,PFA 我的文件/文件夹树的图像。我的目标是编写一个装饰器来处理显式等待所有元素。 (我知道这可以通过修改函数轻松完成,但我想使用装饰器来完成,因为这不是 python 中的装饰器的用途吗?)。 我收到此错误:
FAILED test/test_register.py::TestReg::test_launch_url[test_case1] - AttributeError: 'WebUtils' object has no attribute 'find_element'
FAILED test/test_register.py::TestReg::test_launch_url[test_case2] - AttributeError: 'WebUtils' object has no attribute 'find_element'
我什至尝试将装饰器放在类中。这也没有帮助
我什至无法理解为什么这是一个
find_element
是 WebUtils
类的属性的问题。有人可以帮我解决这个问题吗?这是文件夹树:
您可以像这样用
WebDriverWait
和 expected_conditions
包装方法,以简化脚本并自动等待:
import sys
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from unittest import TestCase
class RefinedRawSelenium(TestCase):
def setUp(self):
self.driver = None
options = webdriver.ChromeOptions()
options.add_argument("--disable-notifications")
if "linux" in sys.platform:
options.add_argument("--headless=new")
options.add_experimental_option(
"excludeSwitches", ["enable-automation", "enable-logging"],
)
prefs = {
"credentials_enable_service": False,
"profile.password_manager_enabled": False,
}
options.add_experimental_option("prefs", prefs)
service = Service(service_args=["--disable-build-check"])
self.driver = webdriver.Chrome(options=options, service=service)
def tearDown(self):
if self.driver:
try:
if self.driver.service.process:
self.driver.quit()
except Exception:
pass
def wait_for_element_visible(
self, selector, by="css selector", timeout=10
):
try:
return WebDriverWait(self.driver, timeout).until(
EC.visibility_of_element_located((by, selector))
)
except Exception:
raise Exception(
"Element {%s} was not visible after %s seconds!"
% (selector, timeout)
)
def wait_for_element_clickable(
self, selector, by="css selector", timeout=10
):
try:
return WebDriverWait(self.driver, timeout).until(
EC.element_to_be_clickable((by, selector))
)
except Exception:
raise Exception(
"Element {%s} was not visible/clickable after %s seconds!"
% (selector, timeout)
)
def wait_for_element_not_visible(
self, selector, by="css selector", timeout=10
):
try:
return WebDriverWait(self.driver, timeout).until(
EC.invisibility_of_element((by, selector))
)
except Exception:
raise Exception(
"Element {%s} was still visible after %s seconds!"
% (selector, timeout)
)
def open(self, url):
self.driver.get(url)
def click(self, selector, by="css selector", timeout=7):
el = self.wait_for_element_clickable(selector, by=by, timeout=timeout)
el.click()
def type(self, selector, text, by="css selector", timeout=10):
el = self.wait_for_element_clickable(selector, by=by, timeout=timeout)
el.clear()
if not text.endswith("\n"):
el.send_keys(text)
else:
el.send_keys(text[:-1])
el.submit()
def assert_element(self, selector, by="css selector", timeout=7):
self.wait_for_element_visible(selector, by=by, timeout=timeout)
def assert_text(self, text, selector="html", by="css selector", timeout=7):
el = self.wait_for_element_visible(selector, by=by, timeout=timeout)
self.assertIn(text, el.text)
def assert_exact_text(self, text, selector, by="css selector", timeout=7):
el = self.wait_for_element_visible(selector, by=by, timeout=timeout)
self.assertEqual(text, el.text)
def assert_element_not_visible(
self, selector, by="css selector", timeout=7
):
self.wait_for_element_not_visible(selector, by=by, timeout=timeout)
def test_add_item_to_cart(self):
self.open("https://www.saucedemo.com")
self.type("#user-name", "standard_user")
self.type("#password", "secret_sauce\n")
self.assert_element("div.inventory_list")
self.assert_text("Products", "span.title")
self.click('button[name*="backpack"]')
self.click("#shopping_cart_container a")
self.assert_exact_text("Your Cart", "span.title")
self.assert_text("Backpack", "div.cart_item")
self.click("#remove-sauce-labs-backpack")
self.assert_element_not_visible("div.cart_item")
self.click("#react-burger-menu-btn")
self.click("a#logout_sidebar_link")
self.assert_element("input#login-button")
# When run with "python" instead of "pytest" or "python -m unittest"
if __name__ == "__main__":
from unittest import main
main()
SeleniumConf 2023(YouTube Playlist)的 Python 演示中对此进行了描述,作为构建使用简化脚本并具有自动等待功能的 Python Selenium 框架的最佳方式。