Selenium自动化测试之道(三)
第三章 Selenium WebDriver
3.1
3.1.1 主流浏览器
Firefox
Chrome:Mac、Linux、windows
IE: Windows(32位、64位)Edge:windows 10
Safari:仅支持Mac系统
3.1.2 Headless浏览器
1.HtmlUnit Driver:java编写,Rhino引擎。
从Selenium 2.53开始,HtmlUnit Driver不再包含在Selenium Server中。
2.PhantomJS Driver: 与Chrom和Safari一样,都基于开源浏览器引擎Webkit。
3.2 常用API概览
Selenium WebDriver 对象实例创建后,执行浏览器的操作方法。
这些方法与浏览器、页面元素无关。
3.2.2 ActionChains
ActionChains是Selenium WebDriver的一个类,在ActionChains初始化的时候,要将WebDriver对象作为参数,从而完成ActionChains的初始化。
场景:
控制鼠标移动、右击、双击、焦点设置。 例如,悬浮菜单(Hover)、鼠标拖放
控制键盘事件
使用:
把一系列操作插入一个队列中,在最后用perform()执行队列中的所有命令。
脚本:
menu=driver.find_element_by_css_selector(".nav") #定位菜单
hidden_submenu=driver.find_element_by_css_selector(".nav #submenu1") #定位隐藏子菜单
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform() # 移动到菜单下,点击隐藏子菜单
或
menu=driver.find_element_by_css_selector(".nav")
hidden_submenu=driver.find_element_by_css_selector(".nav #submenu1")
actions=ActionChains(driver) #ActionChains对象实例
actions.move_to_element(menu) #实例移动到菜单
actions.click(hidden_submenu) #实例点击隐藏的子菜单
actions.perform() #执行实例的一连串操作
3.2.3 Alert
处理弹出框
场景:
执行“取消”、“接受”、“输入” 、从弹框界面获取内容
注意:
弹框实现方式有多种。如果弹框不是原生JavaScript的Alert方法,那脚本可能无效
脚本:
Alert(driver).accept() #接受弹框
Alert(driver).dismiss() #取消弹框
name_prompt=Alert(driver) #创建弹框实例
name_prompt.send_keys“( Willian Shakesphere”) #向弹框实例输入内容
name_prompt.accept() #接受弹框实例
3.2.4 By
By用于指定在页面上寻找元素的方式(ID、XPATH、LINK_TEXT、PARTIAL_LINK_TEXT、NAME、TAG_NAME、CLASS_NAME、CSS_SELECTOR)
脚本:
driver.find_element(by=By.ID, "sb_form_q")
driver.find_element_by_id("sb_form_q")
3.2.5 Desired Capabilities
连接Selenium Server或Selenium Grid进行测试时,需要先创建一个Desired Capabilities对象来实例化Remote WebDriver。
DesiredCapabilities 定义的浏览器和平台有:
FIREFOX、INTERNETEXPLORER、EDGE、CHROME、OPERA、SAFARI、HTMLUNIT、HTMLUNITWITHJS、IPHONE、IPAD、ANDRIOD、PHANTOMJS
脚本:DesiredCapabilities是字典
HTMLUNIT={
"browserName": "htmlunit",
"version": "",
"platform": "ANY",
}
HTMLUNITWITHJS={
"browserName": "htmlunit",
"version": "firefox",
"platform": "ANY",
"javascriptEnabled": True,
}
或自定义:
desired_caps=dict()
desired_caps['appPackage']='com.android.settings'
desired_caps['appActivity']='Settings'
desired_caps['platformName']='Android'
desired_caps['platformVersion']='6.0.0'
desired_caps['deviceName']='Google Galaxy Nexus'
driver=webdriver.Remote('http://127.0.0.1:4444/wd/hub', desired_caps)
或在已经以的基础上更新部分值:
capabilities=DesiredCapabilities.FIREFOX.copy()
capabilities['platform']="WINDOWS"
capabilities['version']="10"
driver.Remote(desired_capabilities=capabilities,
command_executor='http://127.0.0.1:4444/wd/hub')
3.2.6 Keys
场景:
完成特殊键的输入,如ENTER、Tab、F1-F12、上下左右方向键
脚本:
ActionChains(driver).click(to_station_element).send_keys(Keys.ENTER).perform()
3.2.7 Wait
场景:Ajax异步加载技术,页面元素逐步加载
显示等待:Explicit Wait
wait=WebDriverWait(driver, 5)
element=wait.until(expected_conditions.element_to_be_clickable((By.ID, 'spnUid')))
隐式等待:Implicit Wait
注意:隐式等待是全局性的,不考虑界面情况,一直要过了等待时间才能进行下一步,很抵消。与time.sleep(5)一样,避免使用
driver.implicitly_wait(5)
3.2.8 execute_script
场景:Selenium无法支持或解决不了的问题时,可以考虑用js
脚本:
driver.execute_script('return navigator.userAgent')
3.2.9 switch_to
场景:解决父页面与子页面、页面与弹出框之间的切换问题
支持switch_to的元素:active_element、alert、window、frame、parent_frame
使用:
先通过WebDriver获得窗口句柄,然后再切换
脚本:
driver.switch_to.window(driver.window_handles[1])
3.3 场景演练
同样的页面效果实现方式可能完全不同,而导致自动化脚本处理方式完全不一样
3.3.1 弹出框
1.Alert:消息提示框
<html>
<head>
<script type="text/javascript">
function disp_alert()
{
alert("Just for testing")
}
</script>
</head>
<body>
<input type="button" onclick="disp_alert()" value="Click Me" />
</body>
</html>
脚本:Alert(driver).accept() or Alert(driver).dismiss()
2.Window.open:弹窗
点击之后,会打开一个新的HTML页面
<html>
<head>
<script LANGUAGE="javascript">
function openwin() {
window.open ("https://help.pingxx.com/", "newwindow", "height=800, width=800, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
}
</script>
</head>
<body onload="openwin()">
<input type="button" onclick="openwin()" value="Click Me"></body>
</html>
脚本:switch_to.window
3. Bootbox:Div 弹出层
基于第三方的JavaScript库Bootbox来实现
<! --prompt.html-->
<! DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo for Prompt</title>
<! -- CSS dependencies -->
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
</head>
<body>
<p>You could open the console to check result. </p>
<p>Now Click:<a class="alert" href=#>Alert! </a></p>
<! -- JS dependencies -->
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="bootstrap.min.js"></script>
<! -- bootbox code -->
<script src="bootbox.min.js"></script>
<script>
$(document).on("click", ".alert", function(e) {
bootbox.prompt("What is your name? ", function(result) {
if (result === null) {
console.log("Prompt dismissed");
} else {
console.log("Hi <b>"+result+"</b>");
}
});
});
</script>
</body>
</html>
脚本:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
driver=webdriver.Firefox()
driver.get('file:///Users/applewu/Documents/iCode/selenium/ch03/Prompt/prompt.html')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'alert')))
driver.find_element_by_class_name('alert').click()
WebDriverWait(driver, 2).until(EC.visibility_of_element_located((By.TAG_NAME, 'input'))) #确保窗口已经弹出
driver.find_element_by_tag_name('input').send_keys('Tester')
driver.find_element_by_tag_name('input').send_keys(Keys.ENTER)
driver.quit()
实现:
Bootbox实现的弹出窗是一个Div层,属于原窗口DOM的一部分。所以只要确保窗口已经弹出,就可以直接使用Driver找到窗口元素,从而完成弹出框操作
3.3.2 悬浮菜单
悬浮菜单是通过css.hover实现的
3.3.3 表格
3.3.4 iframe
html 的 iframe标签一般应用于在页面中包含其他页面
上传:控件是一个input元素<input type="file" name="file" /> 脚本:定位input元素,然后send_keys 上传文件
driver.find_element_by_name("file").send_keys(os.path.abspath('./web_page/upload_file.txt'))
对于控件是非input元素,要用autoit
下载:下载链接是a元素 脚本:设置好浏览器下载路径,然后点击链接下载
from selenium import webdriver import os options = webdriver.ChromeOptions() prefs = {'profile.default_content_settings.popups': 0, #设置为禁止弹出下载窗口 'download.default_directory': os.getcwd() #设置为文件下载路径 } options.add_experimental_option('prefs', prefs) driver = webdriver.Chrome(chrome_options=options) driver.get("http://pypi.Python.org/pypi/selenium") #文件下载地址 driver.find_element_by_link_text("Download files").click() #切换到下载页面 driver.find_element_by_partial_link_text("selenium-3.141.0.tar.gz").click() #单击下载文件