• selenium之WebDriver API


    自动化只要掌握四步操作:获取元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告,元素定位在这四个环节中是至关重要的,如果说按学习精力分配的话,元素定位占70%;操作元素10%,获取返回结果10%;断言10%。如果一个页面上的元素不能被定位到,那后面的操作就无法继续了。而WebDriver 属于Selenium体系设计出来操作浏览器的一套API,它支持多种语言,Selenium WebDriver只是python的一个第三方框架,也就是说是一个实现web自动化的第三方框架。

    一、从如何定位元素开始

    1、元素定位:find_element_by_id()

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过id定位百度搜索框并输入python
    d.find_element_by_id('kw').send_keys('python')

    2、元素定位:find_element_by_name()

         说明:如果这里运行后报错,说明这个搜索框的name属性不是唯一的,无法通过name属性直接定位到输入框

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过name定位百度搜索框并输入python
    d.find_element_by_name('wd').send_keys('python')

    3、元素定位:find_element_by_class_name()

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过class_name定位百度搜索框并输入python
    d.find_element_by_class_name('s_ipt').send_keys('python')

    4、元素定位:find_element_by_tag_name()

      1.从上面定位到的元素属性中,可以看到每个元素都有tag(标签)属性,如搜索框的标签属性,就是最前面的input

      2.很明显,在一个页面中,相同的标签有很多,所以一般不用标签来定位。仅供参考和理解,运行肯定报错

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过tag_name定位百度搜索框并输入python
    d.find_element_by_tag_name('input').send_keys('python')

    5、元素定位:find_element_by_link_text()

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过link_text定位百度搜索框并输入python
    d.find_element_by_link_text('登录').click()

    6、元素定位:find_element_by_partial_link_text()

     1.有时候一个超链接它的字符串可能比较长,如果输入全称的话,会显示很长,这时候可以用一模糊匹配方式,截取其中一部分字符串就可以了

     2.如“hao123”,只需输入“ao123”也可以定位到

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过partial_link_text定位百度搜索框并输入python
    d.find_element_by_partial_link_text('ao123').click()

    7、元素定位:find_element_by_xpath()

        以上定位方式都是通过元素的某个属性来定位的,如果一个元素它既没有id、name、class属性也不是超链接,这么办呢?或者说它的属性很多重复的。这个时候就可以用       xpath解决

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    d.find_element_by_xpath('//*[@id="kw"]').send_keys('selenium')

    8、元素定位:find_element_by_css_selector()

    总结:

    selenium的webdriver提供了八种基本的元素定位方法,前面六种是通过元素的属性来直接定位的,后面的xpath和css定位更加灵活,需要重点掌握其中一个。

    二、WebDriver API

    1、控制浏览器的简单方法

     

    ---恢复内容结束---

    自动化只要掌握四步操作:获取元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告,元素定位在这四个环节中是至关重要的,如果说按学习精力分配的话,元素定位占70%;操作元素10%,获取返回结果10%;断言10%。如果一个页面上的元素不能被定位到,那后面的操作就无法继续了。而WebDriver 属于Selenium体系设计出来操作浏览器的一套API,它支持多种语言,Selenium WebDriver只是python的一个第三方框架,也就是说是一个实现web自动化的第三方框架。

    一、从如何定位元素开始

    1、元素定位:find_element_by_id()

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过id定位百度搜索框并输入python
    d.find_element_by_id('kw').send_keys('python')

    2、元素定位:find_element_by_name()

         说明:如果这里运行后报错,说明这个搜索框的name属性不是唯一的,无法通过name属性直接定位到输入框

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过name定位百度搜索框并输入python
    d.find_element_by_name('wd').send_keys('python')

    3、元素定位:find_element_by_class_name()

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过class_name定位百度搜索框并输入python
    d.find_element_by_class_name('s_ipt').send_keys('python')

    4、元素定位:find_element_by_tag_name()

      1.从上面定位到的元素属性中,可以看到每个元素都有tag(标签)属性,如搜索框的标签属性,就是最前面的input

      2.很明显,在一个页面中,相同的标签有很多,所以一般不用标签来定位。仅供参考和理解,运行肯定报错

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过tag_name定位百度搜索框并输入python
    d.find_element_by_tag_name('input').send_keys('python')

    5、元素定位:find_element_by_link_text()

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过link_text定位百度搜索框并输入python
    d.find_element_by_link_text('登录').click()

    6、元素定位:find_element_by_partial_link_text()

     1.有时候一个超链接它的字符串可能比较长,如果输入全称的话,会显示很长,这时候可以用一模糊匹配方式,截取其中一部分字符串就可以了

     2.如“hao123”,只需输入“ao123”也可以定位到

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    # 通过partial_link_text定位百度搜索框并输入python
    d.find_element_by_partial_link_text('ao123').click()

    7、元素定位:find_element_by_xpath()

        以上定位方式都是通过元素的某个属性来定位的,如果一个元素它既没有id、name、class属性也不是超链接,这么办呢?或者说它的属性很多重复的。这个时候就可以用       xpath解决

    from selenium import webdriver
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.maximize_window()
    """
    <input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">
    """
    d.find_element_by_xpath('//*[@id="kw"]').send_keys('selenium')

    8、元素定位:find_element_by_css_selector()

    总结:

    selenium的webdriver提供了八种基本的元素定位方法,前面六种是通过元素的属性来直接定位的,后面的xpath和css定位更加灵活,需要重点掌握其中一个。

    二、WebDriver API

    1、鼠标常用方法

    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    el = d.find_element_by_link_text('设置')
    """
    ACtionChains()提供的方法:
    perform() 执行所有的ActionChains中存储的行为
    context_click() 右击
    double_click() 双击
    drag_and_drop(el,el2) 拖动,从el拖动到el2
    move_to_element() 鼠标悬停
    """
    # el.click()
    # 鼠标悬停ActionChains(d).move_to_element(el).perform()

    2、键盘常用属性方法

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    import time
    """
    键盘操作被封装到类keys中
    """
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    d.find_element_by_id('kw').send_keys('selenuimm')
    time.sleep(2)
    
    # 删除多输入的一个m
    d.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)
    time.sleep(2)
    
    # 输入空格键+python
    d.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)
    d.find_element_by_id('kw').send_keys('python')
    time.sleep(2)
    
    # ctrl+a 全选输入框内容
    d.find_element_by_id('kw').send_keys(Keys.CONTROL,'a')
    time.sleep(2)
    
    # ctrl+x 剪切输入框内容
    d.find_element_by_id('kw').send_keys(Keys.CONTROL,'x')
    time.sleep(2)
    
    # ctrl+v 粘贴输入框内容
    d.find_element_by_id('kw').send_keys(Keys.CONTROL,'v')
    time.sleep(2)
    
    # ctrl+v 粘贴输入框内容
    d.find_element_by_id('su').send_keys(Keys.ENTER)
    time.sleep(2)

    3、webelement基本方法

    from selenium import webdriver
    """
    size 返回元素的尺寸
    text 获取元素的文本
    get_attribute(name) 获得属性值
    is_displayed() 设置该元素是否是用户可见
    """
    # 获得输入框的尺寸
    size = d.find_element_by_id('kw').size
    print("size:",size)
    
    # 返回百度页面底部备案信息
    text = d.find_element_by_id('cp').text
    print("text:",text)
    
    # 返回元素的属性值,可以是id、name、type、或其他属性
    attr = d.find_element_by_id('kw').get_attribute('type')
    print('attr:',attr)
    # 返回元素的结果是否可见,返回结果为True或者False
    res = d.find_element_by_id('kw').is_displayed()
    print("res:",res)

    4、获取验证信息

    from selenium import webdriver
    import time
    
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    """
    写自动化测试用例的时候,用来做断言(验证)
    三类验证信息
    url
    title
    text
    """
    # 搜索之前
    title = d.title
    print("title:",title)
    url = d.current_url
    print('url:',url)
    
    d.find_element_by_id('kw').send_keys('selenium')
    d.find_element_by_id('su').click()
    time.sleep(2)
    
    # 搜索之后
    title = d.title
    print("title:",title)
    url = d.current_url
    print('url:',url)
    
    # 断言
    if title == 'selenium_百度搜索':
        print('test case pass')
    else:
        print('test case error')

    5、设置元素等待

     1.显示等待

    import time
    from selenium.webdriver.common.by import By # 元素定位
    from selenium.webdriver.support.ui import WebDriverWait # 等待
    from selenium.webdriver.support import expected_conditions as EC # 条件判断
    from selenium import webdriver
    """
    显式等待:针对某个元素等待
    隐式等待:针对当前页面中的所有元素等待
    """
    # 方式一
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    # 5是5秒钟,0.5是检测的频率
    ele = WebDriverWait(d, 5, 0.5).until(
        EC.presence_of_element_located((By.ID,'kw'))
        )
    ele.send_keys('selenium')
    d.quit()
    from selenium import webdriver
    """
    显式等待:针对某个元素等待
    隐式等待:针对当前页面中的所有元素等待
    """
    # 方式二
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    print(time.ctime())
    
    for i in range(10):
        try:
            global el
            el = d.find_element_by_id('kw')
            if el.is_displayed():
                break
        except:
            pass
        time.sleep(1)
    else:
        print('time out')
    el.send_keys('python')
    # d.close()
    print(time.ctime())

     2.隐式等待

    from selenium.webdriver.support.ui import WebDriverWait # 等待
    from selenium import webdriver
    # 隐式等待
    d = webdriver.Chrome()
    # 默认10秒的等待
    d.implicitly_wait(10)
    d.get('http://www.baidu.com')
    input_ = d.find_element_by_id('kw')
    input_.send_keys('selenium')

    6、定位一组元素

    from selenium import webdriver
    
    d = webdriver.Chrome()
    d.get('http://www.baidu.com')
    """
    定位一组元素:在之前8中定位之前element加s
    d.find_elements_by_class_name()
    d.find_elements_by_name()
    d.find_elements_by_id()
    d.find_elements_by_link_text()
    d.find_elements_by_xpath()
    d.find_elements_by_tag_name()
    d.find_elements_by_css_selector()
    d.find_elements_by_partial_link_text()
    """

     7、多表单切换

     在web 应用中经常会出现frame 嵌套的应用,假设页面上有A、B 两个frame,其中B 在A 内,那么定位B 中的内容则需要先到A,然后再到B。

      switch_to_frame 方法可以把当前定位的主体切换了frame 里。怎么理解这句话呢?我们可以从frame
      的实质去理解。frame 中实际上是嵌入了另一个页面,而webdriver 每次只能在一个页面识别,因此才需要
      用switch_to.frame 方法去获取frame 中嵌入的页面,对那个页面里的元素进行定位。

       switch_to_frame 的参数问题。官方说name 是可以的,但是经过实验发现id 也可以。所以只要frame
       中id 和name,那么处理起来是比较容易的。如果frame 没有这两个属性的话,你可以直接手动添加。

       注:switch_to_frame() 方法在使用的时候被横线划掉,说明不建议使用

       selenium 提供了 switch_to.frame() 方法来切 frame / iframe

       以163邮箱登录为例:

    from selenium import webdriver
    import time
    d = webdriver.Chrome()
    d.get('https://mail.163.com/')
    
    d.implicitly_wait(10)
    ele = d.find_element_by_id("x-URS-iframe") # 先定位到这个iframe页面
    d.switch_to.frame(ele) # 然后切换到这个iframe页面
    d.find_element_by_name('email').clear()
    d.find_element_by_name('email').send_keys('xxxxxx')
    
    d.find_element_by_name('password').clear()
    d.find_element_by_name('password').send_keys('xxxxxxx')
    
    d.find_element_by_id('dologin').click()
    time.sleep(3)
    d.close()

    8、多窗口的切换

    from selenium import webdriver
    d = webdriver.Chrome()
    
    d.implicitly_wait(10)
    d.get('http://www.baidu.com')
    
    # 获得百度搜索窗口句柄
    search_window = d.current_window_handle
    print(search_window)
    
    d.find_element_by_link_text('登录').click()
    d.find_element_by_class_name('tang-pass-footerBar')
    d.find_element_by_link_text('立即注册').click()
    
    # 获得当前所有打开的窗口句柄
    all_handles = d.window_handles
    
    # 进入注册窗口
    for handle in all_handles:
        if handle != search_window:
            d.switch_to.window(handle)
            c_handle = d.current_window_handle # 当前页句柄
            print('now register window!')
    
            d.find_element_by_id('TANGRAM__PSP_3__userName').send_keys('xxxxxx')
            d.find_element_by_id('TANGRAM__PSP_3__phone').send_keys('1233323423')
    View Code

     9、警告窗处理

    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    import time
    """
    text:返回 alert/confirm/prompt中的文字信息
    accept():接受现有警告框 
    dismiss():解散现有警告框
    send_keys(KeysToSend):发送文本至警告框
    KeysToSend:将文本发送至警告框
    """
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    driver.get("http://www.baidu.com")
    # 鼠标悬停到设置
    obj = driver.find_element_by_link_text("设置")
    ActionChains(driver).move_to_element(obj).perform()
    # 点击搜索设置
    driver.find_element_by_link_text("搜索设置").click()
    # 点击保存设置
    driver.find_element_by_class_name("prefpanelgo").click()
    time.sleep(3)
    # 接受警告框
    res = driver.switch_to.alert().text
    print(res)
    View Code

    10、上传文件

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get('http://sahitest.com/demo/php/fileUpload.htm')
    upload = driver.find_element_by_id('file')
    upload.send_keys('d:\baidu.py')  # send_keys
    print(upload.get_attribute('value') ) # check value
    
    driver.quit()
    View Code

    11、控制浏览器滚动条

    from selenium import webdriver
    import time
    #访问百度
    driver=webdriver.Chrome()
    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="var q=document.documentElement.scrollTop=10000"
    driver.execute_script(js)
    time.sleep(3)
    #将滚动条移动到页面的顶部
    js_="var q=document.documentElement.scrollTop=0"
    driver.execute_script(js_)
    time.sleep(3)
    driver.quit()
    View Code

    12、验证码

    对于web 应用来说,大部分的系统在用户登录时都要求用户输入验证码,验证码的类型的很多,有字
    母数字的,有汉字的,甚至还要用户输入一条算术题的答案的,对于系统来说使用验证码可以有效果的防
    止采用机器猜测方法对口令的刺探,在一定程度上增加了安全性。但对于测试人员来说,不管是进行性能
    测试还是自动化测试都是一个棘手的问题

    去掉验证码
    这是最简单的方法,对于开发人员来说,只是把验证码的相关代码注释掉即可,如果是在测试环境,
    这样做可省去了测试人员不少麻烦,如果自动化脚本是要在正式环境跑,这样就给系统带来了一定的风险。

    设置万能码
    去掉验证码的主要是安全问题,为了应对在线系统的安全性威胁,可以在修改程序时不取消验证码,
    而是程序中留一个“后门”---设置一个“万能验证码”,只要用户输入这个“万能验证码”,程序就认为验
    证通过,否则按照原先的验证方式进行验证。

    验证码识别技术

    例如可以通过Python-tesseract 来识别图片验证码,Python-tesseract 是光学字符识别Tesseract OCR 引

    擎的Python 封装类。能够读取任何常规的图片文件(JPG, GIF ,PNG , TIFF 等)。不过,目前市面上的验证码
    形式繁多,目前任何一种验证码识别技术,识别率都不是100% 。

    记录cookie

    通过向浏览器中添加cookie 可以绕过登录的验证码,这是比较有意思的一种解决方案。我们可以在
    用户登录之前,通过add_cookie()方法将用户名密码写入浏览器cookie ,再次访问系统登录链接将自
    动登录

    使用cookie 进行登录最大的难点是如何获得用户名密码的name ,如果找到不到name 的名字,就没
    办法向value 中输用户名、密码信息。

    13、webdriver 原理

    1. WebDriver 启动目标浏览器,并绑定到指定端口。该启动的浏览器实例,做为web driver 的remote
    server。

    2. Client 端通过CommandExcuter 发送HTTPRequest 给remote server 的侦听端口(通信协议: the
    webriver wire protocol)

    3. Remote server 需要依赖原生的浏览器组件(如:IEDriverServer.exe、chromedriver.exe),来转
    化转化浏览器的native 调用。

  • 相关阅读:
    Kali,CentOS 配置静态网络与开启SSH服务【附VMware中配置】
    httpHelper请求辅助类
    请求后的数据处理
    Viewcontroller基类
    上拉下拉基类
    获取cell中的button在整个屏幕上的位置
    Object-C反射读取实体属性和值
    xcode在代码中查找中文
    编写xcode5插件需要增加DVTPlugInCompatibilityUUIDs
    c# 扩展方法
  • 原文地址:https://www.cnblogs.com/crazyforever/p/9186141.html
Copyright © 2020-2023  润新知