5 键盘操作
前面已经提到过,send_keys()可以用来模拟键盘输入,我们还可以用它来输入键盘上的按键,例如:ctrl+a,ctrl+c等
from selenium import webdriver
from selenium.webdriver.common.keys import Keys # 需要导入Keys类
import time # 使用time.sleep()就是为了看到每一步操作的效果
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("seleniumm") # 在输入框输入内容
# time.sleep(2)
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE) # 删除最后一个字符
# time.sleep(2)
# 输入 空格+教程
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
# time.sleep(2)
driver.find_element_by_id("kw").send_keys("教程")
# time.sleep(2)
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, "a") # 输入ctrl+a全选内容
# time.sleep(2)
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, "x") # 输入ctrl+x,剪切内容
# time.sleep(2)
driver.find_element_by_id("kw").send_keys(Keys.CONTROL, "v") # 输入ctrl+v, 粘贴内容到输入框
# time.sleep(2)
driver.find_element_by_id("su").send_keys(Keys.ENTER) # 用回车代替点击操作
# time.sleep(2)
# driver.quit()
以下为常用的键盘操作:
send_keys(Keys.BACK_SPACE) # 删除键
send_keys(Keys.SPACE) # 空格键
send_keys(Keys.TAB) # Tab键/制表符
send_keys(Keys.ESCAPE) # 回退键Esc
send_keys(Keys.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......F12
6 获得验证信息
在进行Web自动化测试中,用的最多的几种验证信息时title, current_url 和 text
title:用于获取当前页面的标题
current_url:用于获取当前页面的url
text:用于获取当前页面的文本信息
下面以百度搜索为例,对比搜索前后的差异
from selenium import webdriver
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
from time import sleep
driver.get("http://www.baidu.com")
print("before search......")
title = driver.title # 获取当前页面的title
print("title------>", title)
now_url = driver.current_url # 获取当前页面的url
print("current_url----->", now_url)
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
sleep(2)
print("after search......")
title = driver.title # 获取当前页面的title
print("title------>", title)
now_url = driver.current_url # 获取当前页面的url
print("current_url----->", now_url)
nums = driver.find_element_by_class_name("nums").text # 获取搜索结果条数
print("nums------>", nums)
# driver.quit()
下面是运行结果:通过下面的运行结果可以看出前后的差异,这些差异可以拿来作为自动化测试的断言点
7 设置元素等待
WebDriver提供了两种类型的元素等待:显示等待和隐式等待
7.1 显示等待
显示等待是WebDriver等待某个条件成立则继续执行,否则在达到最大时长时抛出超时异常
from selenium import webdriver
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.get("http://www.baidu.com")
element = WebDriverWait(driver, 5, 0.5).until(
EC.visibility_of_element_located((By.ID, "kw"))
)
element.send_keys("selenium")
# driver.quit()
WebDriverWait类是WebDriver提供的等待方法,在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超时设置时间仍然检测不到,则抛出异常。格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver:浏览器驱动
timeout:最长超时时间,默认以秒为单位
poll_frequency:检测的间隔时间,默认为0.5秒
ignored_exceptions:超时后的异常信息,默认情况下抛出NoSuchElementException异常
WebDriverWait()一般与until()或until_not()方法配合使用,下面是until()和until_not()方法说明:
until(method, message="")
调用该方法提供的驱动程序作为一个参数,知道返回值为True
until_not(method, message="")
调用该方法提供的驱动程序作为一个参数,知道返回值为False
在本例中,通过as关键字将expected_conditions重命名为EC,并调用visibility_of_element_located方法判断元素是否存在
expected_conditions类提供的部分预期条件判断方法如下:
title_is 判断当前页面的标题是否等于预期
title_contains 判断当前页面的标题是否包含预期字符串
presence_of_element_located 判断元素是否被加载到DOM树里,并不代表该元素一定可见
visibility_of_element_located 判断元素是否可见(可见代表非隐藏,且元素宽高都不为0)
visibility_of 与上一个方法相同,上一个方法的参数为定位,该方法接受的参数为定位后的元素
presence_of_all_elements_located 判断是否至少有一个元素存在于DOM树中,例如,在页面中有N个元素的class为w,那么只要有一个元素存在于DOM树中就返回True
text_to_be_present_in_element 判断某个元素中的text是否包含预期的字符串
text_to_be_present_in_element_value 判断某个元素的value属性是否包含预期的字符串
frame_to_be_available_and_switch_to_it 判断该表单是否可以切换进去,如果可以,返回True并且切换进去,否则返回False
invisibility_of_element_located 判断某个元素是否不再DOM树中或不可见
element_to_be_clickable 判断某个元素是否可见并且是可以点击的
staleness_of 等到一个元素从DOM树中移除
element_to_be_selected 判断某个元素是否被选中,一般用在下拉列表中
element_located_to_be_selected 判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be 与上一个方法相同,只是上一个方法参数为定位后的元素,该方法接受的参数为定位
alert_is_present 判断页面上的是否存在alert
除了expected_conditions类提供的丰富的预期条件判断方法以外,还可以利用前面提到过的is_displayed()方法实现元素显示等待
from selenium import webdriver
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
driver.get("http://www.baidu.com")
from time import ctime, sleep
print(ctime())
for i in range(10):
try:
el = driver.find_element_by_id("kw22")
if el.is_displayed():
break
except:
pass
sleep(1)
else:
print("time out")
print(ctime())
# driver.quit()
结果如下:因为这里是获取的kw22,故意写错的,为了验证该方法
7.2 隐式等待
WebDriver提供的implicitly_wait()方法可以用来实现隐式等待
from selenium import webdriver
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
from time import ctime
from selenium.common.exceptions import NoSuchElementException
driver.implicitly_wait(10) # 设置隐式等待10s
driver.get("http://www.baidu.com")
try:
print(ctime())
driver.find_element_by_id("kw22").send_keys("selenium")
except NoSuchElementException as e:
print(e)
finally:
print(ctime())
# driver.quit()
8 定位一组元素
WebDriver还提供了8中用于定位一组(相同的)元素的方法,和定位单个元素类似,只是element变为复数即可
find_elements_by_id()
find_elements_by_name()
find_elements_by_class_name()
find_elements_by_tag_name()
find_elements_by_link_text()
find_elements_by_partial_link_text()
find_elements_by_xpath()
find_elements_by_css_selector()
例:定位一组元素
from selenium import webdriver
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
from time import sleep
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
sleep(2)
# 定位一组元素
texts = driver.find_elements_by_xpath("//div[@tpl='se_com_default']/h3/a")
# 计算匹配结果个数
print(len(texts))
# driver.quit()
9 多表单切换
在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面是对元素进行识别和定位,无法直接定位到frame/iframe表单内嵌页面上的元素,这时就需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面
例:登录126邮箱
from selenium import webdriver
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)、
driver.get("http://www.126.com")
import time
time.sleep(2)
# 获取页面上的iframe登录框
login_frame = driver.find_element_by_css_selector("iframe[id^='x-URS-iframe']")
# 切换到登录iframe
driver.switch_to.frame(login_frame)
# 输入用户名
driver.find_element_by_name("email").send_keys("username")
# 输入密码
driver.find_element_by_name("password").send_keys("password")
# 点击登录按钮
driver.find_element_by_id("dologin").click()
# 回到最外层页面
driver.switch_to.default_content()
# driver.quit()
注意:switch_to.frame()默认可以直接对表单的id属性或name属性传参,因而可以定位到元素的对象
10 多窗口切换
在页面的操作过程中,有时候单击谋和链接会弹出新的窗口,这时就需要切换到新打开的窗口进行操作,WebDriver提供的switch_to.window()方法可以实现在不同的窗口间切换
current_window_handle:获取当前窗口句柄
window_handles:返回所有窗口的句柄到当前会话
switch_to.window():切换到响应的窗口
例:百度首页和注册页
from selenium import webdriver
chrome_driver_path = r"C:\Users\Administrator\Envs\selenuimAutoTest\Lib\site-packages\selenium\webdriver\chrome\chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
# 获取百度搜索窗口句柄
search_window_handle = driver.current_window_handle
driver.find_element_by_link_text("登录").click()
driver.find_element_by_link_text("立即注册").click()
# 获取当前所有打开的窗口句柄
all_handles = driver.window_handles
# 进入注册窗口
for handle in all_handles:
if handle != search_window_handle:
driver.switch_to.window(handle)
print("title---->",driver.title)
driver.find_element_by_name("userName").send_keys("闯王")
driver.find_element_by_name("phone").send_keys("1520156****")
import time
time.sleep(2)
driver.close()
driver.switch_to.window(search_window_handle)
print("title---->", driver.title)
# driver.quit()