Selenium - Web自动化测试的基本操作实现

摘要: 

之前用Selenium做UI自动化测试从初学到熟练碰到过很多问题,这里就不一一细说了,所以把最基本的操作都写在了一起,包括:控制浏览器,操作元素,鼠标事件,键盘事件,设置元素等待,多表单/窗口切换,警告框处理,上传文件,操作Cookie,调用JavaScript控制浏览器滚动条,窗口截图。

时间紧急,没有仔细整理,望读者见谅~~

目录

1.控制浏览器

1.1控制浏览器窗口大小

1.2控制浏览器后退和前进

1.3模拟刷新浏览器

2.元素操作

2.1常用的元素操作

2.2WebElement 接口常用方法

3.鼠标事件

4.键盘事件

5.设置元素等待

5.1显式等待

5.2隐式等待

5.3sleep 休眠方法

6.多表单切换

7.多窗口切换

8.警告框处理

9.上传文件

9.1send_keys 实现上传

9.2AutoIt 实现上传

10.操作cookie

11.调用JavaScript控制浏览器滚动条

12.窗口截图

1 控制浏览器

Selenium 主要提供的是操作页面上各种元素的方法,但它也提供了操作浏览器本身的方法,比如浏览器的大小以及浏览器后退、前进按钮等。

1.1控制浏览器窗口大小

在不同的浏览器大小下访问测试站点,对测试页面截图并保存,然后观察或使用图像比对工具对被测页面的前端样式进行评测。比如可以将浏览器设置成移动端大小(480x800),然后访问移动站点,对其样式进行评估;WebDriver 提供了set_window_size() 方法来设置浏览器的大小。

 

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

driver.get("http://192.168.30.180/Uet-Platform/")

#参数数字为像素点

print "设置浏览器宽480、高800 显示"

driver.set_window_size(480, 800)

driver.quit()

 

在PC 端运行执行自动化测试脚本大多的情况下是希望浏览器在全屏幕模式下执行,那么可以使用maximize_window()方法,其用法与set_window_size()相同,但它不需要传参。

1.2控制浏览器后退和前进

在使用浏览器浏览网页的时候,浏览器提供了后退和前进按钮,可以方便的对浏览过的网页之间切换,那么WebDriver 也提供了对应的back()和forward()方法来模拟后退和前进按钮。下面通过例子来演示这两个方法的使用。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

#访问百度首页

first_url= 'http://www.baidu.com'

print "now access %s" %(first_url)

driver.get(first_url)

#访问新闻页面

second_url='http://news.baidu.com'

print "now access %s" %(second_url)

driver.get(second_url)

 

#返回(后退)到百度首页

print "back to %s "%(first_url)

driver.back()

#前进到新闻页

print "forward to %s"%(second_url)

driver.forward()

driver.quit()

输出:

now access http://www.baidu.com

now access http://news.baidu.com

back to http://www.baidu.com

forward to http://news.baidu.com

1.3模拟刷新浏览器

有时候需要手动的刷新(F5)的刷新页面

driver.refresh() #刷新当前页面

2元素操作

2.1常用的元素操作

1、clear() 清除文本,如果是一个文件输入框

2、send_keys(*value) 在元素上模拟按键输入

3、click() 单击元素

例子:

#coding=utf-8

from selenium import webdriver

import unittest, time, re

 

driver = webdriver.Firefox()

driver.implicitly_wait(30)

base_url ="http://192.168.30.180/Uet-Platform/masterLogin.action"  #30测试环境

driver.get(base_url)

driver.find_element_by_id("txtUserName").clear()

driver.find_element_by_id("txtUserName").send_keys("13554797004")

 

driver.find_element_by_id("txtPassword").clear()

driver.find_element_by_id("txtPassword").send_keys("123123")

driver.find_element_by_link_text(u"登录").click()

driver.switch_to_frame("lj_left")

driver.find_element_by_xpath("//div[@id='left']/table/tbody/tr[6]/td").click()

driver.find_element_by_link_text(u"用户单位管理").click()

……

说明:

clear()方法用于清除文本输入框中的内容,例如登录框内一般默认会有“账号”“密码”等提示信息用于引导用户输入正确的数据,如果直接向输入框中输入数据,可能会与输入框中的提示信息拼接,本来用户输入为“username”,结果与提示信息拼接为“帐号username”,从而造成输入信息的错误;这个时候

可以先使用clear()方法清除输入框内的提示信息再进行输入。

send_keys()方法模拟键盘输入向输入框里输入内容。如上面的例子中通过这个方法向用户名和密码框中输入用户名和密码。

click()方法可以用来单击一个按钮,前提是它是可以被点击元素,它与send_keys()方法是web 页面操作中最常用到的两个方法。其实click()方法不仅仅用于点击一个按钮,还可以单击任何可以点击文字/图片连接、复选框、单选框、甚至是下拉框等。

2.2WebElement 接口常用方法

1、submit()

submit()方法用于提交表单,这里特别用于没提交按钮的情况,例如搜索框输入关键字之后的“回车”操作,那么就可以通过submit()来提交搜索框的内容。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

driver.get("http://www.youdao.com")

driver.find_element_by_id('query').send_keys('hello')

#提交输入框的内容

driver.find_element_by_id('query').submit()

driver.quit()

有些时候submit()可以与click()方法互换来使用,submit()同样可以提交一个按钮。

2、 size 返回元素的尺寸。

3、text 获取元素的文本。

4、get_attribute(name) 获得属性值。

5、is_displayed() 设置该元素是否用户可见。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

#获得输入框的尺寸

size=driver.find_element_by_id('kw').size

print size

#返回百度页面底部备案信息

text=driver.find_element_by_id("cp").text

 

print text

#返回元素的属性值,可以是id、name、type 或元素拥有的其它任意属性

attribute=driver.find_element_by_id("kw").get_attribute('type')

print attribute

#返回元素的结果是否可见,返回结果为True 或False

result=driver.find_element_by_id("kw").is_displayed()

print result

driver.quit()

运行结果:

{'width': 526, 'height': 22}

©2014 Baidu 使用百度前必读京ICP 证030173 号

True

解析:

执行上面的程序并获得执行结果:size 用于获取百度输入框的宽、高。text 用于获得百度底部的备案信息。get_attribute()用于获百度输入的type 属性的值。is_displayed()用于返回一个元素是否可见,如果可见返回True,否则返回False。

3鼠标事件

在现在的web 产品中,随着前端技术的发展,页面越来越华丽,鼠标的操作也不单单只有单击,现在页面中随处可以看到需要右击、双击、鼠标悬停、甚至是鼠标拖动等操作的功能设计。在WebDriver 中这些关于鼠标操作的方法由ActionChains 类提供。

3.1ActionChains 类提供的鼠标操作的常用方法

1、perform() 执行所有ActionChains 中存储的行为

2、context_click() 右击

3、double_click() 双击

4、drag_and_drop() 拖动

5、move_to_element() 鼠标悬停

例子1:鼠标右击操作

对于ActionChains 类下所提供的鼠标方法与前面学过的click()方法有所不同,那么简单context_click()右键点击一个元素。

代码实现:

from selenium import webdriver

#引入ActionChains 类

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

driver.get("http://yunpan.360.cn")

....

#定位到要右击的元素

right_click =driver.find_element_by_id("xx")

#对定位到的元素执行鼠标右键操作

ActionChains(driver).context_click(right_click).perform()

....

说明:

from selenium.webdriver import ActionChains

对于ActionChains 类下面的方法,在使用之前需要先将模块导入。

ActionChains(driver)

调用ActionChains()方法,在使用将浏览器驱动driver 作为参数传入。

context_click(right_click)

context_click()方法用于模拟鼠标右键事件,在调用时需要传入右键的元素。

perform()

执行所有ActionChains 中存储的行为,可以理解成是对整个操作事件的提交动作。

例子2:鼠标悬停

鼠标悬停弹出下拉菜单也是一个非常见的一个功能设计

move_to_element()方法可以模拟鼠标悬停的动作,其用法与context_click()相同。

代码实现:

……

from selenium import webdriver

#引入ActionChains 类

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

....

#定位到要悬停的元素

above =driver.find_element_by_id("xx")

#对定位到的元素执行悬停操作

ActionChains(driver).move_to_element(above).perform()

....

例子3:鼠标双击操作

double_click(on_element)方法用于模拟鼠标双击操作,用法同上。

代码实现:

……

from selenium import webdriver

#引入ActionChains 类

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

....

#定位到要悬停的元素

double_click = driver.find_element_by_id("xx")

#对定位到的元素执行双击操作

ActionChains(driver).double_click(double_click).perform()

....

例子4:鼠标推放操作

drag_and_drop(source, target)在源元素上按下鼠标左键,然后移动到目标元素上释放。

source: 鼠标拖动的源元素。

target: 鼠标释放的目标元素。

代码实现:

……

from selenium import webdriver

#引入ActionChains 类

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

....

#定位元素的源位置

element = driver.find_element_by_name("xxx")

#定位元素要移动到的目标位置

target = driver.find_element_by_name("xxx")

#执行元素的拖放操作

ActionChains(driver).drag_and_drop(element,target).perform()

....

4键盘事件

有时候我们在测试时需要使用Tab 键将焦点转移到下一个元素,Keys()类提供键盘上几乎所有按键的方法,前面了解到send_keys()方法可以模拟键盘输入,除此之外它还可以模拟键盘上的一些组合键,例:Ctrl+A、Ctrl+C 等。

4.1键盘操作

from selenium.webdriver.common.keys import Keys

在使用键盘按键方法前需要先导入keys 类包。

下面经常使用到的键盘操作:

send_keys(Keys.BACK_SPACE) 删除键(BackSpace)

send_keys(Keys.SPACE) 空格键(Space)

send_keys(Keys.TAB) 制表键(Tab)

send_keys(Keys.ESCAPE) 回退键(Esc)

send_keys(Keys.ENTER) 回车键(Enter)

send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)

send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)

send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)

send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)

send_keys(Keys.F1) 键盘F1

……

send_keys(Keys.F12) 键盘F12

例子:

……

#coding=utf-8

from selenium import webdriver

#引入Keys 模块

from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

#输入框输入内容

driver.find_element_by_id("kw").send_keys("seleniumm")

#删除多输入的一个m

driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)

#输入空格键+“教程”

driver.find_element_by_id("kw").send_keys(Keys.SPACE)

driver.find_element_by_id("kw").send_keys(u"教程")

#ctrl+a 全选输入框内容

driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')

#ctrl+x 剪切输入框内容

driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')

#ctrl+v 粘贴内容到输入框

driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')

#通过回车键盘来代替点击操作

driver.find_element_by_id("su").send_keys(Keys.ENTER)

driver.quit()

5设置元素等待

如今大多数的web 应用程序使用AJAX 技术。当浏览器在加载页面时,页面内的元素可能并不是同时被加载完成的, 这给元素的定位添加的困难。如果因为在加载某个元素时延迟而造成ElementNotVisibleException 的情况出现,那么就会降低的自动化脚本的稳定性。

WebDriver 提供了两种类型的等待:显式等待和隐式等待。

5.1显式等待

显式等待使WebdDriver 等待某个条件成立时继续执行,否则在达到最大时长时抛弃超时异常(TimeoutException)。

例子:

#coding=utf-8

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

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

element = WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"kw")))

element.send_keys('selenium')

driver.quit()

WebDriverWait()

它是由webdirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存

在,如果超过设置时间检测不到则抛出异常。具体格式如下:

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

driver - WebDriver 的驱动程序(Ie, Firefox,Chrome 等)

timeout - 最长超时时间,默认以秒为单位

poll_frequency - 休眠时间的间隔(步长)时间,默认为0.5 秒

ignored_exceptions - 超时后的异常信息,默认情况下抛NoSuchElementException 异常。

until()

WebDriverWait()一般由until()(或until_not())方法配合使用,下面是until()和until_not()方法的说明。

until(method, message=’ ’)

调用该方法提供的驱动程序作为一个参数,直到返回值为Ture。

until_not(method, message=’ ’)

调用该方法提供的驱动程序作为一个参数,直到返回值为False。

Expected Conditions

在本例中,我们在使用expected_conditions 类时对其时行了重命名,通过as 关键字对其重命名为EC,

并调用presence_of_element_located()判断元素是否存在。

expected_conditions 类提供一些预期条件的实现。

title_is 用于判断标题是否xx。

title_contains 用于判断标题是否包含xx 信息。

presence_of_element_located 元素是否存在。

visibility_of_element_located 元素是否可见。

visibility_of 是否可见

presence_of_all_elements_located 判断一组元素的是否存在

text_to_be_present_in_element 判断元素是否有xx 文本信息

text_to_be_present_in_element_value 判断元素值是否有xx 文本信息

frame_to_be_available_and_switch_to_it 表单是否可用,并切换到该表单。

invisibility_of_element_located 判断元素是否隐藏

element_to_be_clickable 判断元素是否点击,它处于可见和启动状态

staleness_of 等到一个元素不再是依附于DOM。

element_to_be_selected 被选中的元素。

element_located_to_be_selected 一个期望的元素位于被选中。

element_selection_state_to_be 一个期望检查如果给定的元素被选中。

element_located_selection_state_to_be 期望找到一个元素并检查是否选择状态

alert_is_present 预期一个警告信息

除了expected_conditions 所提供的预期方法,我们也可以使用前面学过的is_displayed()方法来判断元素是否可。

例子:

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

input_ = driver.find_element_by_id("kw")

element = WebDriverWait(driver,5,0.5).until(

lambda driver : input_.is_displayed()

)

input_.send_keys('selenium')

driver.quit()

5.2隐式等待

隐式等待是通过一定的时长等待页面所元素加载完成。哪果超出了设置的时长元素还没有被加载测抛NoSuchElementException 异常。WebDriver 提供了implicitly_wait()方法来实现隐式等待,默认设置为0。它的用法相对来说要简单的多。

例子:

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()

driver.implicitly_wait(10)

driver.get("http://www.baidu.com")

input_ = driver.find_element_by_id("kw22")

input_.send_keys('selenium')

driver.quit()

implicitly_wait()默认参数的单位为秒,本例中设置等待时长为10 秒,首先这10 秒并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它并不真对页面上的某一元素进行等待,当脚本执行到某个元素定位时,如果元素可定位那么继续执行,如果元素定位不到,那么它将以轮询的方式不断的判断元素

是否被定位到,假设在第6 秒钟定位到元素则继续执行。直接超出设置时长(10 秒)还没定位到元素则抛出异常。

在上面的例子中,显然百度输入框的定位id=kw22 是有误的,那么在超出10 秒后将抛出异常。

5.3sleep 休眠方法

有时间我们希望脚本执行到某一位置时做固定时间的休眠,尤其是在脚本调试的过程中。那么可以使用sleep()方法,需要说明的是sleep()由Python 的time 模块提供。

例子:

#coding=utf-8

from selenium import webdriver

from time import sleep

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

sleep(2)

driver.find_element_by_id("kw").send_keys("webdriver")

driver.find_element_by_id("su").click()

sleep(3)

driver.quit()

当执行到sleep()方法时会固定的休眠所设置的时长,然后再继续执行。sleep()方法默认参数以秒为单位,如果设置时长小于1 秒,可以用小数点表示,如:sleep(0.5)

6多表单切换

在web 应用中经常会遇到frame 嵌套页面的应用,页WebDriver 每次只能在一个页面上识别元素,对于frame 嵌套内的页面上的元素,直接定位是定位是定位不到的。这个时候就需要通过switch_to_frame()方法将当前定位的主体切换了frame 里。

例子:

#coding=utf-8

from selenium import webdriver

import time

import os

driver = webdriver.Firefox()

file_path = 'file:///' + os.path.abspath('frame.html')

driver.get(file_path)

#切换到iframe(id = "if")

driver.switch_to_frame("if")

#下面就可以正常的操作元素了

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

time.sleep(3)

driver.quit()

switch_to_frame() 默认可以直接取表单的id 或name 属性进行切换。

……

#id = "if"

driver.switch_to_frame("if")

#name = "nf"

driver.switch_to_frame("nf")

……

那么如果iframe 没有可用的id 和name 可以通过下面的方式进行定位:

……

#先通过xpth 定位到iframe

xf = driver.find_element_by_xpath('//*[@class="if"]')

#再将定位对象传给switch_to_frame()方法

driver.switch_to_frame(xf)

……

driver.switch_to_default_content()

如果完成了在当前表单上的操作可以通过switch_to_default_content()方法返回到上一层单。该方法不用指定某个表单的返回,默认对应与它最近的switch_to_frame()方法。

7多窗口切换

有时候需要在不同的窗口切换,从而操作不同的窗口上的元素,WebDriver 提供了switch_to_window()方法可以切换到任意的窗口。

图 多窗口

这里以百度首页与注册页为例,演示在不同窗口切换。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Firefox()

driver.implicitly_wait(10)

driver.get("http://www.baidu.com")

#获得百度搜索窗口句柄

sreach_windows= driver.current_window_handle

driver.find_element_by_link_text(u'登录').click()

driver.find_element_by_link_text(u"立即注册").click()

#获得当前所有打开的窗口的句柄

all_handles = driver.window_handles

 

#进入注册窗口

for handle in all_handles:

if handle != sreach_windows:

driver.switch_to_window(handle)

print 'now register window!'

driver.find_element_by_name("account").send_keys('username')

driver.find_element_by_name('password').send_keys('password')

#……

#进入搜索窗口

for handle in all_handles:

if handle == sreach_windows:

driver.switch_to_window(handle)

print 'now sreach window!'

driver.find_element_by_id('TANGRAM__PSP_2__closeBtn').click()

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

time.sleep(5)

driver.quit()

说明

整个脚本的处理过程:首先打开百度首页,通过current_window_handle 获得当前窗口的句柄,并给变量sreach_handle。接着打开登录弹窗,在登录窗口上点击“立即注册”从而打开新的注册窗口。通过window_handles 获得当前打开的所窗口的句柄,赋值给变量all_handles。

第一个循环遍历all_handles,如果handle 不等于sreach_handle,那么一定是注册窗口,因为脚本执行只打开的两个窗口。所以,通过switch_to_window()切换到注册页进行注册操作。第二个循环类似,不过这一次判断如果handle 等于sreach_handle,那么切换到百度搜索页,关闭之前打开的登录弹窗,然后时行搜索操作。

在本例中所有用到的新方法:

current_window_handle 获得当前窗口句柄

window_handles 返回的所有窗口的句柄到当前会话

switch_to_window()

用于切换到相应的窗口,与上一节的switch_to_frame() 是类似,前者用于不同窗口的切换,后者用于不同表单之间的切换。

8警告框处理

在WebDriver 中处理JavaScript 所生成的alert、confirm 以及prompt 是很简单的。具体做法是使用switch_to_alert()方法定位到alert/confirm/prompt。然后使用text/accept/dismiss/send_keys 按需进行操做。

1、text 返回alert/confirm/prompt 中的文字信息。

2、accept 点击确认按钮。

3、dismiss 点击取消按钮,如果有的话。

4、send_keys 输入值,这个alert\confirm 没有对话框就不能用了,不然会报错。

图  百度搜索保存设置弹窗

如图 百度搜索设置的弹出的弹窗是不能通过前端工具对其进行定位的,这个时候就可以通过switch_to_alert()方法接受这个弹窗。

例子:

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()

driver.implicitly_wait(10)

driver.get('http://www.baidu.com')

#鼠标悬停相“设置”链接

link = driver.find_element_by_link_text(u'设置')

ActionChains(driver).move_to_element(link).perform()

#打开搜索设置

driver.find_element_by_class_name('setpref').cick()

#保存设置

driver.find_element_by_css_selector('#gxszButton > a.prefpanelgo').click()

#接收弹窗

driver.switch_to_alert().accept()

driver.quit()

9上传文件

文件上传操作也比较常见功能之一,上传功能操作webdriver 并没有提供对应的方法,关键上传文件的思路。

对web 页面的上功能,点击“上传”按钮需要打开本地的Window 窗口,从窗口选择本地文件进行上传,那么WebDriver 对于Windows 的控件是无能为力的

对于web 页面的上传功能一般会有以下几种方式。

普通上传:普通的附件上传都是将本地文件的路径作为一个值放input 标签中,通过form 表单提交的时候将这个值提交给服务器。

插件上传:一般是指基于Flash 与JavaScript 或Ajax 等技术所实现的上传功能或插件。

9.1send_keys 实现上传

对于通过input 标签实现的通过上传,可以将其看作一个输入框,通过send_keys()传入本地文件路径从而模拟上传功能。

例子:

#coding=utf-8

from selenium import webdriver

import os

driver = webdriver.Firefox()

 

#打开上传功能页面

file_path = 'file:///' + os.path.abspath('upfile.html')

driver.get(file_path)

#定位上传按钮,添加本地文件

driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')

driver.quit()

通过这种方法上传,就绕开了操作Windows 控件的步骤。如果能找上传的input 标签,那么基本都可以通过send_keys()方法向其输入一个文件地址来实现上传。

9.2AutoIt 实现上传

AutoIt 目前最新是v3 版本,这是一个使用类似BASIC 脚本语言的免费软件,它设计用于WindowsGUI(图形用户界面)中进行自动化操作。它利用模拟键盘按键,鼠标移动和窗口/控件的组合来实现自动化任务。

官方网站:https://www.autoitscript.com/site/

从网站上下载AutoIt 并安装,安装完成在菜单中会看到图的目录:

图  AutoIt 菜单

AutoIt Windows Info 用于帮助我们识Windows 控件信息。

Compile Script to.exe 用于将AutoIt 生成exe 执行文件。

Run Script 用于执行AutoIt 脚本。

SciTE Script Editor 用于编写AutoIt 脚本。

下面以操作upload.html 上传弹出的窗口为例讲解AutoIt 实现上传过程。

1、首先打开AutoIt Windows Info 工具,鼠标点击Finder Tool,鼠标将变成一个小风扇形状的图标,按住鼠标左键拖动到需要识别的控件上。

图 AutoIt Windows Info 识别“文件名”输入框控件

图 AutoIt Windows Info 识别“打开”按钮控件

如图,通过AutoIt Windows Info 获得以下信息。

窗口的title 为“选择要加载的文件”,标题的Class 为“#32770”。

文件名输入框的class 为“Edit”,Instance 为“1” ,所以ClassnameNN 为“Edit1”。

打开按钮的class 为“Button”,Instance 为“1” ,所以ClassnameNN 为“Button1”。

2、根据AutoIt Windows Info 所识别到的控件信息打开SciTE Script Editor 编辑器,编写脚本。

;ControlFocus("title","text",controlID) Edit1=Edit instance 1

ControlFocus("选择要加载的文件", "","Edit1")

; Wait 10 seconds for the Upload window to appear

WinWait("[CLASS:#32770]","",10)

; Set the File name text on the Edit field

ControlSetText("选择要加载的文件", "", "Edit1", "D:\\upload_file.txt")

Sleep(2000)

; Click on the Open button

ControlClick("选择要加载的文件", "","Button1");

说明:

ControlFocus()方法用于识别Window 窗口。WinWait()设置10 秒钟用于等待窗口的显示,其用法与WebDriver 所提供的implicitly_wait()类似。ControlSetText()用于向“文件名”输入框内输入本地文件的路径。这里的Sleep()方法与Python 中time 模块提供的Sleep()方法用法一样,不过它是以毫秒为单位,Sleep(2000)表示固定休眠2000 毫秒。ControlClick()用于点击上传窗口中的“打开”按钮。

AutoIt 的脚本已经写好了,可以通过菜单栏“Tools”-->“Go” (或按键盘F5)来运行一个脚本吧!

注意在运行时上传窗口当前处于打开状态。

3、脚本运行正常,将其保存为upfile.au3,这里保存的脚本可以通过Run Script 工具将其打开运行,

但我们的目的是希望这个脚本被Python 程序调用,那么就需要将其生成exe 程序。打开Compile Script to.exe

工具,将其生成为exe 可执行文件。如下图

图  Compile Script to.exe 生成exe 程序

点击“Browse”选择upfile.au3 文件,点击“Convert”按钮将其生成为upfile.exe 程序。

4、下面就是通过自动化测试脚本调用upfile.exe 程序实现上传了。

例子:

#coding=utf-8

from selenium import webdriver

import os

driver = webdriver.Firefox()

#打开上传功能页面

file_path = 'file:///' + os.path.abspath('upfile.html')

driver.get(file_path)

#点击打开上传窗口

driver.find_element_by_name("file").click()

#调用upfile.exe 上传程序

os.system("D:\\upfile.exe")

driver.quit()

通过Python 的os 模块的system()方法可以调用exe 程序并执行。

10操作cookie

有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie 的测试是无法通过白盒和集成测试完成的。WebDriver 提供了操作Cookie 的相关方法可以读取、添加和删除cookie 信息。

10.1操作cookie方法

webdriver 操作cookie 的方法有:

1、get_cookies() 获得所有cookie 信息

2、get_cookie(name) 返回有特定name 值有cookie 信息

3、add_cookie(cookie_dict) 添加cookie,必须有name 和value 值

4、delete_cookie(name) 删除特定(部分)的cookie 信息

5、delete_all_cookies() 删除所有cookie 信息

下面通过get_cookies()来获取当前浏览器的cookie 信息。

程序实现:

#coding=utf-8

from selenium import webdriver

import time

driver = webdriver.Chrome()

driver.get("http://www.youdao.com")

# 获得cookie 信息

cookie= driver.get_cookies()

#将获得cookie 的信息打印

print cookie

driver.quit()

执行结果:

>>> ============= RESTART ===============

>>>

[{u'domain': u'.youdao.com',

u'secure': False,

u'value': u'aGFzbG9nZ2VkPXRydWU=',

u'expiry': 1408430390.991375,

u'path': u'/',

u'name': u'_PREF_ANONYUSER__MYTH'},

{u'domain': u'.youdao.com',

u'secure': False,

u'value': u'1777851312@218.17.158.115',

u'expiry': 2322974390.991376,

u'path': u'/', u'name':

u'OUTFOX_SEARCH_USER_ID'},

{u'path': u'/',

u'domain': u'www.youdao.com',

u'name': u'JSESSIONID',

u'value': u'abcUX9zdw0minadIhtvcu',

u'secure': False}]

通过打印结果可以看出,cookie 是以字典的形式进行存放的,知道了cookie 的存放形式,那么我们就可以按照这种形式向浏览器中写入cookie 信息。

例子:

#coding=utf-8

from selenium import webdriver

import time

driver = webdriver.Firefox()

driver.get("http://www.youdao.com")

 

#向cookie 的name 和value 添加会话信息。

driver.add_cookie({'name':'key-aaaaaaa', 'value':'value-bbbbbb'})

#遍历cookies 中的name 和value 信息打印,当然还有上面添加的信息

for cookie in driver.get_cookies():

print "%s -> %s" % (cookie['name'], cookie['value'])

driver.quit()

执行结果:

>>> ======================= RESTART ======================

>>>

YOUDAO_MOBILE_ACCESS_TYPE -> 1

_PREF_ANONYUSER__MYTH -> aGFzbG9nZ2VkPXRydWU=

OUTFOX_SEARCH_USER_ID -> -1046383847@218.17.158.115

JSESSIONID -> abc7qSE_SBGsVgnVLBvcu

key-aaaaaaa -> value-bbbbbb

从打印结果可以看到最后一条cookie 信息是在脚本执行过程中通add_cookie()方法添加的。通过遍历得到的所cookie 信息从而找到key 为“name”和“value”的特定cookie 的value。

那么在什么情况下会用到cookie 的操作呢?例如开发人员开发一个功能,当用户登录后,会将用户的用户名写入浏览器cookie,指定的key 为“username”,那么我们就可以通过get_cookies() 找到useranme,打印vlaue,如果找不到username 或对应的value 为空,那么说明保存浏览器的cookie 是有问题的。

delete_cookie() 和delete_all_cookies() 的使用也很简单,前者通过name 值到一个特定的cookie 将其删除,后者直接删除浏览器中的所有cookies()信息。

11调用JavaScript控制浏览器滚动条

WebDiver 不能操作本地Windows 控件,但对于浏览器上的控件也不是都可以操作的。比哪浏览器上的滚动条,虽然WebDriver 提供操作浏览器的前进和后退按钮,但对于滚动条并没有提供相应用的方法。那么在这种情况下就可以借助JavaScript 方法来控制浏览器滚动条。WebDriver 提供了execute_script()方法来执行JavaScript 代码。

一般用到操作滚动条的会两个场景:

(1)注册时的法律条文的阅读,判断用户是否阅读完成的标准是:滚动条是否拉到最下方。

(2)要操作的页面元素不在视觉范围,无法进行操作,需要拖动滚动条。

用于标识滚动条位置的代码

例子:

……

……

 

document.body.scrollTop

网页被卷去的高。scrollTop 设置或获取滚动条与最顶端之间的距离。如果想让滚动条处于顶部,那么可以设置scrollTop 的值为0,如果想让滚动条处于最底端,可以将这个值设置的足够大,大个窗口的高度即可。scrollTop 的值以像素为单位。

例子:

#coding=utf-8

from selenium import webdriver

import time

#访问百度

driver=webdriver.Firefox()

driver.get("http://www.baidu.com")

#搜索

driver.find_element_by_id("kw").send_keys("selenium")

driver.find_element_by_id("su").click()

time.sleep(3)

#将页面滚动条拖到底部

js="document.documentElement.scrollTop=10000"

driver.execute_script(js)

time.sleep(3)

#将滚动条移动到页面的顶部

js_="document.documentElement.scrollTop=0"

driver.execute_script(js_)

time.sleep(3)

driver.quit()

通过浏览器打开百度进行搜索,搜索的一屏无法完全显示将会出现滚动条。这个时候就可以通过JavaScript 代码控制滚动条在任意位置,需要改变的就是scrollTop 的值。通过execute_script()方法来执行这段JavaScript 代码。

有时候滚动条不仅上下有,如上图,其它左右也有,那么可以通过下面JavaScript 代码来实现上下与左右滚动条的任意推动。

例子:

……

#window.scrollTo(左边距,上边距);

window.scrollTo(0,450);

……

js=" window.scrollTo(200,1000);"

driver.execute_script(js)

用法与同上,通过execute_script()调用此代码,修改scrollTo()的参数即可。

当然,JavaScript 的作用不仅于此,它同样可操作页面上的元素或让,或让这个元素隐藏。

12窗口截图

自动化脚本是交给工具去执行,有时候打印的错误信息并不十分明确,如果在脚本执行出错的时候将对当前窗口截图保存,那么通过图片信息会更只观帮助我们找到脚本出错的原因。Webdriver 提供了截图函数get_screenshot_as_file()来截取当前窗口。

例子:

#coding=utf-8

from selenium import webdriver

driver = webdriver.Chrome()

driver.get('http://www.baidu.com')

try:

driver.find_element_by_id('kw_error').send_key('selenium')

driver.find_element_by_id('su').click()

except :

driver.get_screenshot_as_file("D:\\baidu_error.jpg")

driver.quit()

在本例中用到了Python 的异常处理,要本例中百度输入框的id=kw_error 会定位不到元素,那么try就会捕捉到这个异常,从而执行except,在except 中执行get_screenshot_as_file()对当前窗口进行截图,这里需要指定图片的保存路径及文件名,并且关闭当前驱动。

脚本运行完成打开D 盘就可以找到baidu_error.jpg 图片文件了。

推荐阅读更多精彩内容