强制 Python 中的 Selenium 等待浏览器完成加载
Force Selenium in Python to wait until the browser is done loading
我目前正在编写“Test-Driven Development with Python”中的示例,更具体地说是第一个功能测试。
我的代码的关键部分如下:
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(20)
我告诉 Selenium 隐式等待 20 秒,直到它找到它要查找的内容。
inputbox = self.browser.find_element_by_id('id_new_item')
self.assertEqual(
inputbox.get_attribute('placeholder'),
'Enter a To-Do item'
)
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('tr')
self.assertIn('1: Buy feather peacocks', [row.text for row in rows])
这里最大的问题在于以下几行:
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
table = self.browser.find_element_by_id('id_list_table')
- 在输入框中写"Buy peacock feathers"。
- 它按回车键。
- 它在 之后立即尝试在table.
中查找项目
问题是我的电脑没有那么快。找到项目时,浏览器仍在尝试加载脚本,断言失败。
我知道有两种等待 Selenium 的类型:隐式(已经应用)和显式(对此做了一些研究)。我对两者的问题如下:
- 隐式等待是无用的,因为找到了项目,不管这些项目是否是我要找的。
- 显式等待是没有用的,因为表单发送前后页面都是一样的,因此没有什么可等待的。
time.sleep()
如果使用过多,脚本会挂起。
- 是的,我还检查了
item_text
是否被正确引用,包括 name
属性 :)
我还有哪些其他选择?我该怎么做才能强制 Selenium 等到页面加载完毕?预先谢谢你。
编辑:视图如下,按照书中的例子。
<html>
<head>
<title>Lista de Quehaceres</title>
</head>
<body>
<h1>Tu Lista de Quehaceres</h1>
<form method="POST">
<input id="id_new_item" name="item_text" placeholder="Entre un ítem de quehacer" />
{% csrf_token %}
</form>
<table id="id_list_table">
<tr><td>1: {{ new_item_text }}</td></tr>
</table>
</body>
</html>
您可以等待特定的 text to be present in element using WebDriverWait
:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
table = WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element((By.CSS_SELECTOR, "table#id_list_table tr td"), "Buy peacock feathers")
)
我目前正在编写“Test-Driven Development with Python”中的示例,更具体地说是第一个功能测试。
我的代码的关键部分如下:
def setUp(self):
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(20)
我告诉 Selenium 隐式等待 20 秒,直到它找到它要查找的内容。
inputbox = self.browser.find_element_by_id('id_new_item')
self.assertEqual(
inputbox.get_attribute('placeholder'),
'Enter a To-Do item'
)
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
table = self.browser.find_element_by_id('id_list_table')
rows = table.find_elements_by_tag_name('tr')
self.assertIn('1: Buy feather peacocks', [row.text for row in rows])
这里最大的问题在于以下几行:
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
table = self.browser.find_element_by_id('id_list_table')
- 在输入框中写"Buy peacock feathers"。
- 它按回车键。
- 它在 之后立即尝试在table. 中查找项目
问题是我的电脑没有那么快。找到项目时,浏览器仍在尝试加载脚本,断言失败。
我知道有两种等待 Selenium 的类型:隐式(已经应用)和显式(对此做了一些研究)。我对两者的问题如下:
- 隐式等待是无用的,因为找到了项目,不管这些项目是否是我要找的。
- 显式等待是没有用的,因为表单发送前后页面都是一样的,因此没有什么可等待的。
time.sleep()
如果使用过多,脚本会挂起。- 是的,我还检查了
item_text
是否被正确引用,包括name
属性 :)
我还有哪些其他选择?我该怎么做才能强制 Selenium 等到页面加载完毕?预先谢谢你。
编辑:视图如下,按照书中的例子。
<html>
<head>
<title>Lista de Quehaceres</title>
</head>
<body>
<h1>Tu Lista de Quehaceres</h1>
<form method="POST">
<input id="id_new_item" name="item_text" placeholder="Entre un ítem de quehacer" />
{% csrf_token %}
</form>
<table id="id_list_table">
<tr><td>1: {{ new_item_text }}</td></tr>
</table>
</body>
</html>
您可以等待特定的 text to be present in element using WebDriverWait
:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
inputbox.send_keys('Buy peacock feathers')
inputbox.send_keys(Keys.ENTER)
table = WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element((By.CSS_SELECTOR, "table#id_list_table tr td"), "Buy peacock feathers")
)