selenium学习(二)

第八课–元素定位八种方式

要想操作Web界面上的元素,首先要定位到该元素,Selenium提供了定位元素的API,这些方法都被定义在WebDriver类中,浙西额方法都是以find开头。

方法名称描述可能带来的问题
find_element_by_id通过id定位元素开发代码id应该是唯一的,常用的id进行定位
find_element_by_xpath通过xpath定位元素通过浏览器插件来获得xpath路径,选中元素右键copy- copy xpath
find_element_by_link_text通过链接文本定位元素
find_element_by_partial_link_text通过部分链接文本定位元素链接部分文本可能会存在同一个界面多个链接,返回结果就可能是个集合
find_element_by_name通过属性名称定位元素可能会返回多个元素,因为名字重复,仅返回第一个;使用find_elements_by_name()返回一个集合
find_element_by_tag_name通过标签名称定位元素一个界面可能会存在多个相同标签的组建,返回的是一个集合
find_element_by_class_name通过css class定位元素class的name不重复的情况下可用,反之会返回一个集合
find_element_by_css_selector通过css选择器定位元素通过浏览器插件来获取selector,选中元素右键copy- copy selector

将以上定位元素的方法封装一下,使用的是driver.find_element(*loc),通过哪种方式定位引入By,例如By.ID

def get_element(driver, *loc):
    element = driver.find_element(*loc)
    return element

if __name__ == '__main__':
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com/')
    input = get_element(driver,By.ID,'kw')  #使用方式
    # loc = (By.ID, 'kw')
    # input = get_element(driver, *loc)  #第二种方式
    input.send_keys('即可时间')
    sleep(1)
    get_element(driver,By.ID,'su').click()
    sleep(1)
    driver.quit()

传参的时候注意也需要加*号

第九课–webdirver的工作原理

客户端API怎样和驱动进行通信,驱动又怎么驱动浏览器进行工作,其之间的通信协议是什么,又是怎样协同工作的

WebDriver的工作原理

举一个打车的例子,会有三个角色:

  • 乘客:告诉出租车司机去哪里,大概怎么走
  • 出租车司机:按照乘客的要求来操控出租车
  • 出租车:按照司机的操控完成行驶任务,把乘客送到目的地

与WebDriver映射关系:

  • 工程师写的自动化测试代码:自动化测试代码发送请求给浏览器的驱动(如火狐驱动、谷歌驱动)
  • 浏览器的驱动:解析这些自动化代码,解析后把他们发送给浏览器
  • 浏览器:执行浏览器驱动发来的指令,并最终完成工程师想要的操作

WebDriver和浏览器是如何通信

在这里插入图片描述
API和驱动之间是一个C/S,驱动中包含一个http 服务器,有一个端口用来监听请求

  • 对于每一条Selenium脚本,一个http请求会被创建并且发送给浏览器的驱动
  • 浏览器驱动中包含一个http Server ,用来接收这些http请求
  • http Server 接收到请求后根据请求来具体操控对应的浏览器
  • 浏览器执行具体的测试步骤
  • 浏览器将步骤执行结果返回给http Server
  • Http Server 又将结果返回给Selenium的脚本,如果是错误的http代码就会在控制台看到对应的报错信息

WebDriver的协议

webdriver使用的协议是:JSON Wire protocol
通信的数据格式是JSON

第十课–WebDriver核心方法和属性的使用

属性

#属性属性描述
1driver.name浏览器名称
2driver.title当前页面的标题
3driver.current_url当前页面url
4driver.page_source当前页面源码
5driver.current_window_handle窗口句柄
6driver.window_handles当前窗口所有句柄

方法

#方法方法描述
1driver.back()后退一个界面
2driver.refresh()刷新界面
3driver.forward()前进一个界面
4driver.close()关闭当前窗口
5driver.quit()退出浏览器
6driver.switch_to.frame()切换到frame
7driver.switch_to.alert切换到alert
8driver.switch_to.active_element切换到活动元素

通过window_handles以及switch_to.window方法实现不同窗口切换:

self.driver.get('https://www.baidu.com')
        self.driver.find_element_by_link_text('新闻').click()
        handles = self.driver.window_handles
        while 1:    #往复切换
            for handle in handles:
                self.driver.switch_to.window(handle)
                sleep(2)

第十一课–WebElement核心方法和属性的使用

测试网站:https://sahitest.com/demo/
元素属性

#属性属性描述
1element.id元素id
2element.tag_name标签名称(input)
3element.size元素宽高
4element.rect宽高以及坐标
5element.text文本内容

没有value的属性

元素方法

#方法方法描述
1element.send_keys()输入框中输入内容
2element.clear()清空内容
3element.click()按钮或者超链接点击
4element.get_attribute()获得元素属性值(type、text、value)
5element.is_selected()是否被选中(返回true、false)
6element.is_enabled()是否可用(返回true、false)
7element.is_displayed()是否显示(返回true、false)
8element.value_of_css_property()css属性值(font、color)

第十二课–form表单操作步骤

form表单的流程:

  1. 定位表单元素
  2. 输入测试值
  3. 判断表单元素属性
  4. 获得表单元素属性
  5. 提交表单进行验证

代码举例
本地建立html界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form表单事例</title>
</head>
<body>
<form action="javascript:alert('提交成功')">
    Username:<input type = 'text' name = 'username' id = 'username'><br/>
    Password:<input type = 'password' name = 'password' id = 'password'><br/>
    <input type="submit" value="submit" id="submit">
</form>
</body>
</html>

获取本地建立的html界面并打开

    def __init__(self):
        self.driver = webdriver.Chrome()
        #os.path.abspath(__file__)  当前文件的路径
        #os.path.dirname(path)  当前路径的文件所在的文件夹
        path = os.path.dirname(os.path.abspath(__file__))
        file_path = 'file:///' + path + '/formex.html'
        self.driver.get(file_path)

进行form的系列操作

username = self.driver.find_element_by_id('username')
        username.send_keys('wqq')
        password = self.driver.find_element_by_id('password')
        password.send_keys('123456')
        sleep(2)
        print(username.get_attribute('value'))   #获取元素属性,可以进行校验
        print(password.get_attribute('value'))
        self.driver.find_element_by_id('submit').click()
        sleep(2)
        self.driver.switch_to.alert.accept()  #     进入alert界面后选择接受后,关闭alert
        sleep(2)
        username.clear()  #清空输入框
        password.clear()
        self.driver.quit()

第十三课-- checkbox和ratiobutton定位技巧

checkbox-多选框,定位到之后,可以先判断一下是否已经选择,以防已经选择再click一下就取消选择了

swimming = self.driver.find_element_by_name('swimming')
if not swimming.is_selected():
   swimming.click()

ratio-单选框

gender:<input type="radio" name="gender" value="male"><input type="radio" name="gender" value="female"><br/>

可以发现那么是一样的,所以元素定位后返回的是一个集合,ratio没有判断是否被选中的属性,所以可以根据下标判断选中哪个

gender = self.driver.find_elements_by_name('gender')
        gender[0].click()

第十四课-select操作

select-下拉框,分位单选和多选
单选

城市:
    <select name="provide" id="provide">
        <option value="bj">Beijing</option>
        <option value="sd">Shandong</option>
        <option value="sh">Shanghai</option>
    </select>

多选,区别在于加一个multiple参数

城市:
    <select name="provide" id="provide" multiple>
        <option value="bj">Beijing</option>
        <option value="sd">Shandong</option>
        <option value="sh">Shanghai</option>
    </select>

select定位需要两步,先找到下拉框元素,然后定义成Select类型

se = self.driver.find_element_by_id('provide')
select = Select(se)
#方法/属性方法/属性描述
1select.select_by_value(‘sd’)根据值选择
2select.select_by_index(0)根据索引下标选择(下标从0开始)
3select.select_by_visible_text(‘Shanghai’)根据界面显示文本选择
4select.deselect_all()取消选择所有
5select.deselect_by_index(1)根据索引下标取消选择
6select.deselect_by_value(‘sd’)根据值取消选择
7select.deselect_by_visible_text(‘Shanghai’)根据界面显示文本取消选择
8select.options所有选项
9select.all_selected_options所有被选中的选项
10select.first_selected_option第一个被选中的选项

属性8、9返回的是一个list,需要通过循环输出,展示内容使用option.text

第十五课–弹框处理(alert、confirm、prompt)

页面弹框有三种:

  • alert:用来提示
  • confirm:用来二次确认
  • prompt:输入内容
#方法/属性方法/属性描述适用弹窗
1accept()接受alert、confirm、prompt
2dismiss()取消alert(右上角取消)、confirm(右上角以及取消按钮)、prompt(右上角取消以及取消按钮)
3text显示弹框内容alert、confirm、prompt
4send_keys(‘20’)输入内容prompt

弹窗元素定位到后,需要切换到弹窗界面,再进行后续操作

self.driver.find_element_by_id('alert').click()  #元素定位
alert = self.driver.switch_to.alert #切换到弹窗

注:confirm、prompt的切换到弹窗也是使用self.driver.switch_to.alert

第十六课-- Selenium的三种的等待方式

在UI自动化测试中,必然会遇到环境不稳定、网络慢的情况,这时不做任何处理的话代码会由于没有找到元素而报错;另外一种情况就是页面使用ajax异步加载机制;这时就要用到wait,而在Selenium中,一共有三种等待方式。

#等待方式优点缺点
1time.sleep(2)脚本调试过程中,方便快捷python自带模块的time的sleep方式进行等待,虽然可以自定义等待时间,但是当网络条件良好时,依旧会按照预设的时间继续等待,导致整个项目的自动化时间无限长。不建议使用
2self.driver.implicitly_wait(10)隐式等待实际是设置了一个最长的等待时间,如果在规定时间内页面加载完成,则执行下一步;否则一致等待到时间结束,然后执行下一步。 隐式等待在整个driver周期都起作用,在最开始这只一次就可以了Javascript一般都是放在body的最后进行加载,实际这个页面的元素已经加载完毕,我们却还在等待全部页面加载结束,也会导致时间很长
3WebDriverWait(driver=self.driver,timeout=10)显式等待,可以设置等待到什么条件后执行下一步,在任何地方都可以设置

WebDriverWait介绍

  • Selenium提供的显式等得模块引入路径
  • 导入from selenium.webdriver.support.wait import WebDriverWait
  • WebDriverWait参数
    poll_frequency和 ignored_exception参数有需要可以随意设置
wait = WebDriverWait(driver=self.driver,timeout=10)
#参数参数说明
1driver传入WebDriver事例
2timeout设置超时时间,等待的最长时间
3poll_frequency调用until或者until_not中的方法的间隔时间,默认是0.5s
4ignored_exceptions忽略异常,默认是None
  • 有两种方法until与until_not
#参数参数说明
1method在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False
2message如果超时,跑出TimeoutException,将message传入异常

获取当前界面的内容

from selenium.webdriver.support import expected_conditions as EC


wait = WebDriverWait(driver=self.driver,timeout=10)  #定义等待参数
wait.until(method=EC.title_is('百度一下,你就知道'),message='')  #循环到是true

等待条件下一课详细讲解

第十七课–selenium等待条件

使用以下等待条件需要提前导入一个python自带的模块,from selenium.webdriver.support import expected_conditions as EC

#等待条件说明返回结果
1EC.title_is()判断title,是否出现布尔
2EC.title_contains()判断title,是否包含某些字符布尔
3EC.presence_of_element_located((By.ID, ‘div2’))判断某个元素是否被加到了dom树里,并不代表该元素一定可见WebElement
4EC.visibility_of_element_located((By.ID, ‘div2’))判断某个元素是否被添加到了dom里并且可见,宽和高都大于0WebElement
5EC.visibility_of(self.driver.find_element_by_id(‘btn’))判断元素是否可见,如果可见久返回这个元素WebElement
6EC.presence_of_all_elements_located()判断是否至少有1个元素存在于dom树中列表
7EC.visibility_of_any_elements_located()判断是否至少有一个元素在页面中可见列表
8EC.text_to_be_present_in_element()判断指定的元素中是否包含了预期的字符串布尔
9EC.text_to_be_present_in_element_value()判断指定元素的属性值中是否包含了预期的字符串布尔
10EC.frame_to_be_available_and_switch_to_it()判断该frame是否可以switch进去布尔
11EC.invisibility_of_element_located()判断某个元素是否存在于dom或者不可见布尔
12EC.element_to_be_clickable()判断某个元素中是否可见并且是enable的,代表可点击布尔
13EC.staleness_of()等待某个元素从dom树中移除布尔
14EC.element_to_be_selected()判断某个元素是否被选中了,一般用在下拉列表布尔
15EC.element_selection_state_to_be()判断某个元素的选中状态是否符合预期布尔
16EC.element_located_selection_state_to_be()判断某个元素的选中状态是否符合预期布尔
17EC.alert_is_present()判断页面上是否存在alertalert

dom树-这个元素不一定能看到,可能是被隐藏

第十八课-- 鼠标和键盘的操作

Selenium中的鼠标和键盘事件被封装在ActionChains类中,正确的使用方法,先事例化,再使用,执行用到perform()

action = ActionChains(self.driver)
action.double_click(btn).perform()

鼠标、键盘操作方法

#方法介绍
1click(on_element=None)单击鼠标左键
2click_and_hold(on_element=None)点击鼠标左键,不松开
3content_click(on_element=None)点击鼠标右键
4double_click(on_element=None)双击鼠标左键
5drag_and_drop(source,target)拖拽到某个元素然后松开
6drag_and_drop_by_offset(source,xoffset,yoffset)拖拽到某个坐标然后放开
7action.key_down(value, element=None)按下键盘上某个见
8action.key_up(value, element=None)松开某个键
9action.move_by_offset(xoffset, yoffset)鼠标从当前位置移动到某个坐标
10action.move_to_element(to_element)鼠标从当前位置移动到某个元素
11action.move_to_element_with_offset(to_element, xoffset, yoffset)鼠标从当前位置移动到距某个元素(左上角坐标)多少距离的位置
12action.release(on_element=None)在某个元素位置松开鼠标左键
13action.send_keys(*keys_to_send)发送某个键到当前焦点的元素
14action.send_keys_to_element(element, *keys_to_send)发送某个键到指定的元素
15perform()执行上面方法的动作

对于键盘的操作,还需要引入Keys模块,包含键盘上的按钮kw.send_keys(Keys.CONTROL,'a'),意思是Control+a

第十九课-- Selenium执行JavaScript脚本

WebDriver又两个方法来执行JavaScript

  • execute_script 同步执行
  • execute_async_script 异步执行

举例
alert弹框

    def test1(self):
        self.driver.get("http://www.baidu.com")
        self.driver.execute_script("alert('test')")
        sleep(2)
        self.driver.switch_to.alert.accept()
        sleep(2)
        self.driver.quit()

返回页面title

    def test2(self):
        self.driver.get("http://www.baidu.com")
        js = 'return document.title'  #返回title
        title = self.driver.execute_script(js)
        print(title)
        sleep(2)
        self.driver.quit()

改变组建样式-未成功

    def test3(self):
        self.driver.get("http://www.baidu.com")
        sleep(2)
        #改变组件样式
        js = 'var q = document.getElementById("kw");q.style.border="2px solid red"'
        self.driver.execute_script(js)
        sleep(2)
        self.driver.quit()

界面滚动条拉到最下面

    def test4(self):
        self.driver.get("http://www.baidu.com")
        sleep(2)
        self.driver.find_element_by_id('kw').send_keys('selenium')
        self.driver.find_element_by_id('su').click()
        sleep(2)
        js = 'window.scrollTo(0,document.body.scrollHeight)'
        self.driver.execute_script(js)
        sleep(2)
        self.driver.quit()

第二十课 捕获屏幕

#方法方法描述
1self.driver.save_screenshot(filename)获取当前屏幕截图并保存为指定文件,filename指保存的文件名或者图片的文件名
2self.driver.get_screenshot_as_base64()获取当前屏幕截图base64位编码字符串
3self.driver.get_screenshot_as_file(file_path)获取当前屏幕截图,参数是保存路径
4self.driver.get_screenshot_as_png()获取当前屏幕截图的二进制数据

在实际项目中,常常或是用当前时间来命名文件,代码如下

st = strftime("%Y-%m-%d-%H-%M-%S",localtime(time()))  #获取当前时间
file_name = st+'.png'
path = os.path.abspath('screenshot')
file_path = path + '/' + file_name  #图片存放位置在screenshot文件夹下面
self.driver.get_screenshot_as_file(file_path)

第二十一课–WebDriver定位frame、iframe

frame标签有frame set、frame、iframe三种,frameset跟其他标签没有区别,不会影响正常定位,而frame、iframe对selenium定位而言是一样的

#方法方法描述
1self.driver.switch_to.frame(reference)切换frame,reference是传入参数,用来定位frame,可以传入id、name、index以及webelement
2self.driver.switch_to.default_content()返回主文档,焦点移到主文档,不能再访问frame中的内容
3self.driver.switch_to.parent_frame()返回父文档,可以访问框架外部

事例代码

    def test_frame(self):
        self.driver.get('https://sahitest.com/demo/framesTest.htm')
        sleep(2)
        top = self.driver.find_element_by_name('top')
        self.driver.switch_to.frame(top) #先进入到frame窗口再进行窗口内操作
        self.driver.find_element_by_xpath('/html/body/table/tbody/tr/td[1]/a[1]').click()
        sleep(3)
        self.driver.switch_to.default_content()  #焦点回到主文档
        sleep(3)
        second = self.driver.find_element_by_xpath('/html/frameset/frame[2]')
        sleep(2)
        self.driver.switch_to.frame(second)
        self.driver.find_element_by_xpath('/html/body/table/tbody/tr/td[1]/a[1]').click()
        sleep(2)
        self.driver.quit()

补充内容-- PyAutoGUI

PyAutoGUI是一个图形用户界面自动化工具,通过屏幕xy坐标系统确认目标位置,控制鼠标和键盘发送虚拟击键和鼠标点击,完成点击按钮、填写表单等操作。常用在常规方法定位不到元素的情况。
需要安装PyAutoGUI插件

#方法方法描述
1pyautogui.position()确认鼠标当前位置
2pyautogui.moveTo(x=None, y=None[, duration=t])移动
3pyautogui.mouseDown()、pyautogui.mouseUp()、pyautogui.click()、pyautogui.doubleClick()、pyautogui.rightClick()、pyautogui.middleClick()点击
4pyautogui.dragTo(x=None, y=None[, duration=t])拖动
5pyautogui.typewrite(x=None, y=None[, duration=t])控制键盘
element = self.driver.find_element_by_id('agree')
rect = element.rect  #元素所在位置
pyautogui.click(rect['x']+10,rect['y']+130)  #点击位置内容

元素位置返回的是一个字典类型

方法描述
self.driver.maximize_window()窗口放大全屏命令
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值