WebDriver功能
功能/属性 | 描 述 | 实 例 |
---|---|---|
current_url | 获取当前页面的URL地址 | driver.current_url |
current_window_handle | 获取当前窗口的句柄 | driver.current_window_handle |
name | 获取该实例底层的浏览器名称 | driver.name |
orientation | 获取当前设备的方位 | driver.orientation |
page_source | 获取当前页面的源代码 | driver.page_source |
title | 获取当前页面的标题 | driver.title |
window_handles | 获取当前session里所有窗口的句柄 | driver.window_handles |
WebDriver方法
WebDirver通过一些方法来实现与浏览器窗口、网页和页面元素的交互。下表是一些重要的方法。
方 法 | 描 述 | 参 数 | 实 例 |
---|---|---|---|
back() | 后退一步到当前会话的浏览器历史记录中最后一步操作前的页面 | driver.back() | |
close() | 关闭当前浏览器窗口 | driver.close() | |
forward() | 前进一步到当前会话的浏览器历史记录中前一步操作后的页面 | driver.forward() | |
get(url) | 访问目标URL并加载网页到当前的浏览器会话 | URL是目标网页的网站地址 | driver.get(“http://www.google.com") |
maximize_window() | 最大化当前浏览器窗口 | driver.maximize_window() | |
quit() | 退出当前driver并且关闭所有的相关窗口 | driver.quit() | |
refresh() | 刷新当前页面 | driver.refresh() | |
switch_to_active_element() | 返回当前页面唯一焦点所在的元素或者元素体 | driver.switch_to_active_element() | |
switch_to_alert() | 把焦点切换至当前页面弹出的警告 | driver.switch_to_alert() | |
switch_to_default_content() | 切换焦点至默认框架内 | driver.switch_to_default_content() | |
switch_to-frame(frame_reference) | 通过索引、名称和网页元素将焦点切换到指定的框架,这种方法也适用于IFRAMES | frame_reference: 要切换的目标窗口的名称、整数类型的索引或者要切换的目标框架的网页元素 | driver.switch_to_frame(‘frame_name’) |
switch_to_window(window_name) | 切换焦点到指定的窗口 | window_name: 要切换的目标窗口的名称或者句柄 | driver.switch_to_window(‘main’) |
implicitly_wait(time_to_wait) | 超时设置等待目标元素被找到,或者目标指令执行完成。该方法在每个session只需要调用一次。execute_async_script的超时设置,请参阅set_script_timeout方法 | time_to_wait: 等待时间(单位为秒) | |
set_page_load_timeout(time_to_wait) | 设置一个页面完全加载完成的超时等待时间 | time_to_wait: 等待时间(单位为秒) | driver.set_page_load_timeout(30) |
set_script_timeout(time_to_wait) | 设置脚本执行的超时时间,应该在execute_async_script抛出错误之前 | time_to_wait: 等待时间(单位为秒) | driver.set_script_timeout(30) |
WebElement接口
WebElement功能
功能/属性 | 描 述 | 实 例 |
---|---|---|
size | 获取元素的大小 | element.size |
tag_name | 获取元素的HTML标签名称 | element.tag_name |
text | 获取元素的文本值 | element.text |
WebElement方法
方 法 | 描 述 | 参 数 | 实 例 |
---|---|---|---|
clear() | 清除文本框或者文本域中的内容 | element.clear() | |
click() | 单击元素 | element.click() | |
get_attribute(name) | 获取元素的属性值 | name:元素的名称 | element.get_attribute(“value”) 或者 element.get_attribute(“maxlength”) |
is_displayed() | 检查元素对于用户是否可见 | element.is_displayed() | |
is_enabled() | 检查元素是否可用 | element.is_enabled() | |
is_selected() | 检查元素是否被选中。该方法应用于复选框和单选按钮 | element.is_selected() | |
send_keys(*value) | 模拟输入文本 | value:待输入的字符串 | element.send_keys(“foo”) |
submit() | 用于提交表单。如果对一个元素应用此方法,将会提交该元素所属的表单 | element.submit() | |
value_of_css_property (property_name) | 获取CSS属性的值 | property_name: CSS属性的名称 | element.value_of_css_property (“backgroundcolor”) |
操作表单、文本框、复选框、单选按钮
使用WebElement实现与各种HTML控件的自动化交互,例如在一个文本框输入文本、单击一个按钮、选择单选按钮或者复选框、获取元素的文本和属性值等。
eg:填写5个文本框并且选择一个复选框
(1)首先,创建一个新的测试类 RegisterNewUser,下面是实例代码。
1 | from selenium import webdriver |
(2)添加一个测试方法 test_register_new_user(self) 到RegisterNewUser类中。
(3)为了打开登录页面,我们需要单击主页的登录链接。用于登录的代码如下。
1 | def test_register_new_user(self): |
检查元素是否启用或显示
当元素在屏幕上可见的时候(visible属性设置为TRUE),调用is_displayed() 方法返回为TRUE,反之就会返回FALSE。类似地,当元素是可用的时候,调用is_enabled() 方法返回为TRUE,这时用户就可以执行点击和输入文本等操作。当元素是不可用的时候,该方法返回FALSE。
用户登录页面提供了使用已有账户登录和创建新用户的选项。我们可以通过调用is_displayed()方法和is_enabled()方法检查创建新账户按钮对于用户是否可见并且可用。添加下面的代码到测试类中。
1 | # get the Create Account button |
我们要测试创建账户功能,因此要单击创建账户按钮,然后将会展示创建新账户的页面。我们可以通过检查WebDriver 的 title 属性来校验打开的页面是否符合预期结果,代码如下。
1 | # click on Create Account button. This will display |
在创建新账户页面,可以通过调用 find_element_by_* 方法来查找定位所有的元素。
1 | # get all the fields from Create an Account form |
获取元素对应的值
get_attribute()方法可以用来获取元素的属性值。例如,单个测试是用来验证输入姓和名字的文本框的最大字符限制是255,字符限制就是通过maxlength属性来实现的,如下代码所示设置值为255。
1 | <input type="text" id="firstname" name="firstname" value="" |
可以通过调用get_attribute()方法来校验maxlength 属性是否正确。
(1)需要把属性名称作为参数传递给get_attribute()方法。
1 | # check maxlength of first name and last name textbox |
(2)添加以下代码到测试脚本中,以确保所有的字段对于用户都是可见和可用的。
1 | # check all fields are enabled |
is_selected方法
is_selected() 方法是针对单选按钮和复选框的。我们可以通过调用该方法来得知一个单选按钮或复选框是否被选中。
单选按钮或复选框可以通过WebElement 的 click() 方法来执行点击操作,从而选中该元素。如下面的例子,检查Sign UP for Newsletter 复选框是否默认为不被选中的,示例代码如下。
1 | # check Sign Up for Newsletter is unchecked |
clear()与send_keys()方法
clear() 和 send_keys()方法适用于文本框和文本域,分别用于清除元素的文本内容和模拟用户操作键盘来输入文本信息。待输入的文本作为send_keys() 方法的参数。
(1)添加下面的代码,通过send_keys() 方法来给对应的字段填写值。
1 | # fill out all the fields |
(2)最终通过校验欢迎信息来检查用户是否创建成功。
我们可以通过text 属性来获取元素的文本内容。
1 | # check new user is registered |
完整测试脚本
1 | from selenium import webdriver |
操作下拉菜单
Selenium WebDriver提供了特定的Select类实现与网页上的列表和下拉菜单的交互。
下面的样例程序,可以看到一个为店铺选择语言的下拉菜单。
下拉菜单和列表是通过HTML的<select>
元素实现的。选择项是通过<select>
中的<option>
元素实现的,如下HTML代码。
1 | <select id="select-language" title="Your Language" |
每个<option>
元素都有属性值和文本内容,是用户可见的。例如,在下面的代码中,<option>
设置的是店铺的URL,后面参数设置的是语言种类,这里是French。
1 | <option value="http://demo.magentocommerce.com/customer/ |
Select原理
Select 类是Selenium的一个特定的类,用于与下拉菜单和列表交互。它提供了丰富的功能和方法来实现与用户交互。
Select功能
功能/属性 | 描 述 | 实 例 |
---|---|---|
all_selected_options | 获取下拉菜单和列表中被选中的所有选项内容 | select_element.all_selected_options |
first_selected_option | 获取下拉菜单和列表的第一个选项/当前选择项 | select_element.first_selected_option |
options | 获取下拉菜单和列表的所有选项 | select_element.options |
Select方法
功能/属性 | 描 述 | 参 数 | 实 例 |
---|---|---|---|
deselect_all() | 清除多选下拉菜单和列表的所有选择项 | select_element.deselect_all() | |
deselect_by_index(index) | 根据索引清除下拉菜单和列表的选择项 | index:要清除的目标选择项的索引 | select_element.deselect_by_index(1) |
deselect_by_value(value) | 清除所有选项值和给定参数匹配的下拉菜单和列表的选择项 | value:要清除的目标选择项的value属性 | select_element.deselect_by_value(“foo”) |
deselect_ by_visible_text(text) | 清除所有展示的文本和给定参数匹配的下拉菜单和列表的选择项 | text:要清除的目标选择项的文本值 | select_element.deselect_by_visible_text(“bar”) |
select_by_index(index) | 根据索引选择下拉菜单和列表的选择项 | index:要选择的目标选择项的索引 | select_element.select_by_index(1) |
select_by_value(value) | 选择所有选项值和给定参数匹配的下拉菜单和列表的选择项 | value:要选择的目标选择项的value属性 | select_element.select_by_value(“foo”) |
select_by_visible_text(text) | 选择所有展示的文本和给定参数匹配的下拉菜单和列表的选择项 | text:要选择的目标选择项的文本值 | select_element.select_by_visible_text(“bar”) |
回到刚才被测网站的语言选择功能,创建好的主页面的测试类添加一个新的测试用例。这个测试用例用来验证是否有8种语言可供用户选择。我们将首先使用options 属性来验证选项的个数是否和预期结果一致,然后通过获取每个选项的文本来与预期的选项列表相比较,从而校验是否一致,代码如下所示。
1 | def test_language_options(self): |
options属性返回一个下拉选项和列表里的所有<option>
元素。选项列表里的每个选项都是一个WebElement类的实例。
也可以通过用first_selected_option属性来校验默认/当前选择项是否正确。
用下面的代码来实现:选择一个语言选项,然后校验保存的URL是否能够随着语言选项的改变而正确地变化。
1 | # select an option using select_by_visible text |
操作警告和弹出框
开发人员使用JavaScript 警告或者模态对话框来提示校验错误信息、报警信息、执行操作后的返回信息,甚至用来接收输入值等。本节我们将了解如何使用Selenium来操控警告和弹出框。
### Alert原理
Selenium WebDriver 通过Alert 类来操控 JavaScript 警告。Alert 包含的方法有接受、驳回、输入和获取警告的文本。
Alert功能
功能/属性 | 描 述 | 实 例 |
---|---|---|
text | 获取警告窗口的文本 | alert.text |
Alert方法
方 法 | 描 述 | 参 数 | 实 例 |
---|---|---|---|
accept() | 接受JavaScript 警告信息,单击OK 按钮 | alert.accept() | |
dismiss() | 驳回JavaScript 警告信息,单击取消按钮 | alert.dismiss() | |
send_ keys(*value) | 模拟给元素输入信息 | value:待输入目标字段的字符串 | alert.send_keys(“foo”) |
设计一个测试来验证单击COMPARE PRODUCTS(产品比较)功能中的Clear All链接时,是否会弹出警告提醒用户。
创建一个新的测试类CompareProducts,并添加测试场景的代码,搜索并添加一个产品到比较列表中,代码如下。
1 | from selenium import webdriver |
当单击Add to Compare 链接将一个产品添加到比较列表时,将会看到一个产品添加到COMPARE PRODUCTS 下面。这个时候还可以添加其他的产品到比较列表。如果想从比较列表移除所有的产品,可以在COMPARE PRODUCTS 模块单击Clear All 链接。这个时候可以看到一个警告提示“是否确认移除所有的产品”。我们可以通过Alert来操控这个警告。调用WebDirver 的Switch_to_alert() 方法可以返回一个Alert的实例。我们可以利用这个Alert 实例来获取警告信息,并通过单击OK按钮来接受这个警告信息,或者通过单击Cancel 按钮来拒绝这个警告。添加下面的代码到测试脚本中,这部分代码用来读取并且校验警告信息是否正确,然后通过调用accept() 方法来接受警告。
1 | # click on Remove this item link, this will display |
浏览器自动化处理
通过单击浏览器工具栏上的后退、前进、刷新/重新加载按钮,可以实现访问历史页面、刷新当前页面等操作。Selenium WebDriver API 提供了很多操控这些按钮的方法,我们可以使用这些方法来验证浏览器的行为。WebDriver 类提供了以下方法来操控浏览器的后退、前进和刷新等操作。
方 法 | 描 述 | 参 数 | 实 例 |
---|---|---|---|
back() | 后退到浏览器当前会话的历史记录中的前一步操作 | 无 | driver.back() |
forward() | 向前一步到浏览器当前会话的历史记录中的后一步操作 | 无 | driver.forward() |
refresh() | 刷新浏览器中的当前页面 | 无 | driver.refresh() |
下面的例子是通过浏览器API操控浏览器历史记录并验证程序的状态。
1 | import unittest |
元素等待机制
1.隐式等待
隐式等待对于解决由于网络延迟或利用Ajax动态加载元素所导致的程序响应时间不一致,是非常有效的。
当设置了隐式等待时间后,WebDriver会在一定的时间内持续检测和搜寻DOM,以便于查找一个或多个不是立即加载成功并可用的元素。一般情况下,隐式等待的默认超时时间设置为0。
一旦设置,隐式等待时间就会作用于这个WebDriver实例的整个生命周期或者一次完整测试的执行期,并且WebDriver会使其对所有测试步骤中包含整个页面的元素的查找时都有效,除非把默认超时时间设置回0。
WebDriver类提供了implicitly_wait()方法来配置超时时间。已经创建了SearchProductTest测试类,是基于unittest写的测试。我们将基于这个类进行修改,在setUp() 方法中加入隐式等待时间并且设置为10秒,代码如下面的例子所示。当一个测试用例执行的时候,WebDirver在找不到一个元素的时候,将会等待10秒。当达到10秒超时时间后,将会抛出一个NoSuchElementException 的异常。
1 | import unittest |
显式等待
显式等待是WebDriver中用于同步测试的另外一种等待机制。显式等待比隐式等待具备更好的操控性。与隐式等待不同,我们可以为脚本设置一些预置或定制化的条件,等待条件满足后再进行下一步测试。
显式等待可以只作用于仅有同步需求的测试用例。WebDriver提供了WebDriverWait类和expected_conditions类来实现显式等待。
expected_conditions类提供了一些预置条件,来作为测试脚本进行下一步测试的判断依据。让我们创建一个包含显式等待的简单的测试,条件是等待一个元素可见,代码如下。
1 | from selenium import webdriver |
在上面的测试中,显式等待条件是等到Log In链接在DOM中可见。
expected_conditions类
expected_conditions类支持的在执行网页浏览器自动化操作时常常用到的一些通用的等待条件。
预 期 条 件 | 描 述 | 参 数 | 实 例 |
---|---|---|---|
element_to_be_clickable(locator) | 等待通过定位器查找的元素可见并且可用,以便确定元素是可点击的。 此方法返回定位到的元素 | locator: 一组(by,locator) | WebDriverWait(self.driver, 10).until(expected_conditions.element_to_be_clickable((By.NAME,”is_subscribed”))) |
element_to_be_selected(element) | 等待直到指定的元素被选中 | element: 是个WebElement | subscription = self.driver.find_element_by_name(“is_subscribed”) WebDriverWait(self.driver, 10). until(expected_conditions. element_to_be_selected(subscription) |
invisibility_of_element_located(locator) | 等待一个元素在DOM中不可见或不存在 | locator: 一组(by,locator) | WebDriverWait(self.driver, 10). until(expected_conditions. invisibility_of_element_located((By. ID,”loading_banner”))) |
presence_of_all_elements_located(locator) | 等待直到至少有一个定位器查找匹配到的目标元素出现在网页中。 该方法返回定位到的一组WebElement | locator: 一组(by,locator) | WebDriverWait(self.driver, 10). until(expected_conditions.presence_of_all_elements_located((By.CLASS _NAME,”input-text”))) |
presence_of_element_located(locator) | 等待直到定位器查找匹配到的目标元素出现在网页中或可以在DOM中找到。 该方法返回一个被定位到的元素 | locator: 一组(by,locator) | WebDriverWait(self.driver, 10). until(expected_conditions.presence_of_element_located((By.ID,”search”))) |
text_to_be_present_in_element(locator,text_) | 等待直到元素能被定位到并且带有相应的文本信息 | locator: 一组(by,locator) text:需要被校验的文本内容 | WebDriverWait(self.driver,10). until(expected_conditions.text_to_be_present_in_element((By.ID,”select-language”),”English”)) |
title_contains(title) | 等待网页标题包含指定的大小写敏感的字符串。 该方法在匹配成功时返回True,否则返回False | title: 被校验的包含在标题中的字符串 | WebDriverWait(self.driver, 10). until(expected_conditions.title_contains(“Create NewCustomer Account”)) |
title_is(title) | 等待网页标题与预期的标题相一致。 该方法在匹配成功时返回True,否则返回False | title:网页的标题 | WebDriverWait(self.driver, 10). until(expected_conditions.title_is(“Create New CustomerAccount -MagentoCommerce Demo Store”)) |
visibility_of(element) | 等待直到元素出现在DOM中,是可见的,并且宽和高都大于0。 一旦其变成可见的,该方法将返回(同一个)WebElement | element : 目标WebElement | first_name = self.driver.find_element_by_id(“firstname”) WebDriverWait(self.driver, 10). until(expected_conditions.visibility_of(first_name)) |
visibility_of_element_located(locator) | 等待直到根据定位器查找的目标元素出现在DOM中,是可见的,并且宽和高都大于0。 一旦其变成可见的,该方法将返回WebElement | locator: 一组(by,locator) | WebDriverWait(self.driver, 10). until(expected_conditions.visibility_of_element_located((By.ID,”firstname”))) |
判断某个元素是否存在
1 | def test_create_new_customer(self): |
判断是否存在Alerts
例如,一个复杂的JavaScript处理过程或后端处理过程需要花费较多的时间把警告反馈给用户,这时可以用alert_is_present这个预期判断条件来实现
1 | from selenium import webdriver |
预期条件判断的实践
实现一个自定义的预期条件判断,来检测下拉列表中可选项的数量。
1 | def testLoginLink(self): |
使用Python的lambda表达式,并且基于WebDriverWait来实现自定义的预期条件判断