【Web自动化测试】(六)Selenium中表单、多窗口、多frame、多浏览器等场景处理方法

相关文章链接:
【Web自动化测试】(一)Selenium介绍及安装部署说明
【Web自动化测试】(二)使用selenium编写测试用例
【Web自动化测试】(三)Selenium中控件定位方法
【Web自动化测试】(四)Selenium中WEB控件交互的方法
【Web自动化测试】(五)Selenium中的三种等待方式
【Web自动化测试】(七)selenium中执行JavaScript脚本
【web自动化测试】(八)cookie复用



前言:
本文为在霍格沃兹测试开发学社中学习到的一些技术,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步。


在前面的文章中,我们讲述了WEB控件定位和WEB控件交互的方法,下面就为大家介绍几种我们在进行WEB自动化过程中常见的场景的处理方法。


1.表单操作

  1. 什么是表单
    表单是一个包含表单元素的区域;
    表单元素是允许用户在表单中(比如:文本域、下来列表、单元框、复选框等等)输入信息的元素;
    表单使用表单标签(<form>)定义。例如:<form><input /></form>
    在这里插入图片描述

  2. 操作表单元素的步骤
    首先要定位到表单元素;
    然后去操作元素(清空、输入或者点击等)。

  3. 示例
    测试用例步骤:
    1.打开百度;
    2.点击“登录”;
    3.在弹出的表单中输入用户名和密码;
    4.点击表单中的“登录”,提交表单。

from time import sleep
from selenium import webdriver

class TestDemo:
    def setup(self):
        self.driver=webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    def test_form(self):
        self.driver.get("https://www.baidu.com")

        #点击登录
        self.driver.find_element_by_id("s-top-loginbtn").click()

        #输入账号
        self.driver.find_element_by_id("TANGRAM__PSP_11__userName").send_keys("CSDN_demo")
        #输入密码
        self.driver.find_element_by_id("TANGRAM__PSP_11__password").send_keys("111111")
        #点击表单中的登录
        self.driver.find_element_by_id("TANGRAM__PSP_11__submit").click()

        #停止3秒为了看结果
        sleep(3)

2.多窗口处理

  1. 说明
    点击某些链接,会重新开发一个窗口,对于这种情况,向在新页面上操作,就得先切换窗口了。
    窗口的唯一标识用句柄标识,因此只需要切换句柄,就可以在多个页面灵活操作了。
  2. 处理流程
    第一步:先获取当前的窗口句柄(driver.current_window_handle);
    第二步:再获取到所有的窗口句柄(driver.window_handles);
    第三步:判断是想要操作的窗口,如果是,可以对窗口进行操作;如果不是,跳转到另外一个窗口,对另外一个窗口进行操作(driver.switch_to_window)。
  3. 示例
from time import sleep
from selenium import webdriver
from selenium.webdriver import ActionChains


class TestDemo:
    def setup(self):
        self.driver=webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    def test_windows(self):
        self.driver.get("https://www.baidu.com/")
        #shiyong ActionChains进行操作
        action=ActionChains(self.driver)

        #点击百度首页右上角的登录
        element_login =self.driver.find_element_by_link_text("登录")
        action.click(element_login).perform() #点击百度“登录”

        #点击表单中的立即注册
        # 注意:当操作后有新窗口或者浮层出现的话,不能吧所有操作做完之后一起preform  这样会导致窗口无法正常弹出,影响下一个步骤的元素查找
        element_register = self.driver.find_element_by_link_text("立即注册")
        action.click(element_register).perform()
        #会有新窗口呈现 因此立即perform

        #获取当前所有窗口句柄
        windowsall=self.driver.window_handles #获取所有窗口句柄
        #打印获取句柄内容,主要是为了让大家看返回的窗口句柄是啥类型的,可以去掉
        print(windowsall)
        # 切换到注册窗口,即最后一个窗口句柄
        self.driver.switch_to.window(windowsall[-1])

        #输入注册名
        element_username = self.driver.find_element_by_id('TANGRAM__PSP_4__userName')
        element_username.send_keys("CSDN_demo")
        #暂停三秒,主要是为了观察当前页面是个啥情况,可以去掉
        sleep(3)

        #切换到登录窗口,即第一个窗口句柄
        self.driver.switch_to.window(windowsall[0])

        #下面开始进行正常的登录操作
        #输入用户名
        element_userloginname = self.driver.find_element_by_id('TANGRAM__PSP_11__userName')
        element_userloginname.send_keys("CSDN_demo")
        #输入密码
        element_userloginpassword = self.driver.find_element_by_id('TANGRAM__PSP_11__password')
        element_userloginpassword.send_keys("111111")
        #点击登录,提交表单
        element_loginbutton = self.driver.find_element_by_id('TANGRAM__PSP_11__submit')
        action.click(element_loginbutton).perform()
        # 暂停三秒,主要是为了观察当前页面是个啥情况,可以去掉
        sleep(3)
   

3.多frame处理

  1. 说明
    在web自动化中,如果一个元素定位不到那么很大可能是在iframe中。
    1. 什么是frame?
      frame是和html中的框架,在html中,所谓的框架就是可以在同一个浏览器中显示不止一个页面。
      基于html的框架,有分为垂直框架和水平框架。
    2. frame分类
      fram标签包含frameset、frame、iframe三种;
      frameset和普通标签一样,不会影响正常的定位,可以使用index、id、name、webelement任意种方式定位frame;
      而frame与iframe对selenium定位而言是一样的,selenium有一组方法对frame进行操作。
  2. 多frame切换
    1. frame存在两种
      一种是嵌套的,一种是未嵌套的
    2. 切换frame
      dirver.switch_to.frame():根据元素id或者index切换frame
      dirver.switch_to.default_content ():切换到默认frame
      dirver.switch_to.parent_frame() :切换到父级frame
    3. 处理嵌套的iframe
      处理嵌套的iframe可以先进入到ifame的父frame,再进到子frame,然后可以对子节点里面的对应对象进行处理和操作
  3. 示例
from time import sleep
from selenium import webdriver
from selenium.webdriver import ActionChains


class TestDemo:
    def setup(self):
        self.driver=webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    def test_frame_drag(self):

        self.driver.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
        #切换到iframe中
        self.driver.switch_to.frame('iframeResult')
        #定位元素
        el_draggable = self.driver.find_element_by_id('draggable')
        el_droppable = self.driver.find_element_by_id('droppable')

        action = ActionChains(self.driver)
        #使用ActionChains进行拖拽操作
        action.click_and_hold(el_draggable).move_to_element(el_droppable).perform()  # 不要忘记调用perform()
        sleep(3)
        #在将frame切换到默认的frame
        self.driver.switch_to.default_content()
        #点击确定
        el_submit = self.driver.find_element_by_id('submitBTN')
        print(el_submit.text)

4.多浏览器处理

  1. 说明
    在WEB自动化测试中,我们常使用不对的浏览器记性兼容性测试。在代码中传入不同的浏览器参数,即可实现多种类浏览器处理。
  2. 示例
import os
from time import sleep
from selenium import webdriver

class TestDemo:
    def setup(self):
        option = webdriver.ChromeOptions()
        option.add_experimental_option('w3c', False)

        #通过在终端给browser参数赋值,来判断使用使用浏览器运行测试用例
        browser=os.getenv("browser")
        print("browser",browser)
        #值为firefox则使用Firefox运行
        if browser=="firefox":
            self.driver=webdriver.Firefox()
        #值为headless,则使用PhantomJS运行
        elif browser =='headless':
            self.driver=webdriver.PhantomJS()
        #其他情况使用chrome,及默认的话也为chrome
        else:
            self.driver = webdriver.Chrome(options=option)
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()

    def teardown(self):
        self.driver.quit()

    def test_form(self):
        self.driver.get("https://www.baidu.com")

        #点击登录
        self.driver.find_element_by_id("s-top-loginbtn").click()

        #输入账号
        self.driver.find_element_by_id("TANGRAM__PSP_11__userName").send_keys("CSDN_demo")
        #输入密码
        self.driver.find_element_by_id("TANGRAM__PSP_11__password").send_keys("111111")
        #点击表单中的登录
        self.driver.find_element_by_id("TANGRAM__PSP_11__submit").click()

        #停止3秒为了看窗口情况,可以删除
        sleep(3)

在终端中运行结果:
Windows上:

#先set browser
set browser=firefox
#再执行测试用例
pytest test_broswers.py

在这里插入图片描述
Linux/MacOS:

browser=firefox pytest test_browsers.py

在这里插入图片描述

由于无Linux/MacOS环境,因此无法演示,找个图片给大家看一下。大家根据自己的操作系统来进行使用即可。

5.文件上传

  1. 说明
    WEB自动化过程中,我们也会遇到上传文件和上传图片这种情况,如果是input标签的话,我们可以直接使用send_keys(“文件路径”)来进行上传文件操作
  2. 示例
from time import sleep
from selenium import webdriver

class TestDemo:
    def setup(self):
        self.driver=webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()
     def test_upload(self):
        self.driver.get("https://image.baidu.com/")
        #点击百度图片搜索框中的照相机图标
        self.driver.find_element_by_xpath('//*[@id="sttb"]/img[1]').click()
        #上传图片,使用相对路径
        self.driver.find_element_by_id('stfile').send_keys('../pic/test.jpg')
        #用于查看结果,可删除
        sleep(3)

6.弹框处理

  1. 说明

    • 在页面操作中有时会遇到JavaScript所生成的alert、confirm以及prompt,使用switch_to.alert()方法定位到。然后使用text/accept/dismiss/send_keys等方法就你行操作用。
    • 常用的alert方法:
      switch_to.alert():获取当前页面上的告警
      text:返回alert、confirm、prompt中的文字信息
      accept():接收现有的告警窗口
      dismiss():解散也有的告警窗口
      send_keys(keyToSend):发送文本至告警框。
  2. 示例

from time import sleep
from selenium import webdriver

class TestDemo:
    def setup(self):
        self.driver=webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()
        
    def test_alert(self):
        #打开网址
        self.driver.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')

        #切换frame
        self.driver.switch_to.frame('iframeResult')

        #定位元素
        el_drag=self.driver.find_element_by_id('draggable')
        el_drop=self.driver.find_element_by_id('droppable')

        #定义actionchains动作
        action=ActionChains(self.driver)
        #进行拖拽操作
        action.drag_and_drop(el_drag,el_drop).perform()
        sleep(5)

        #切换到alert页面,并同意alert内容
        self.driver.switch_to.alert.accept()
        #alert的其他功能
        #self.driver.switch_to.alert.send_keys()  # - keysToSend: The text to be sent to Alert.
        #self.driver.switch_to.alert.dismiss()   #Dismisses the alert available.

        #切换至默认rframe
        self.driver.switch_to.default_content()
        self.driver.find_element_by_id('submitBTN').click()
        sleep(5)

7.浏览器复用

  1. 为什么要复用浏览器?
    1. 在已有浏览器中打开操作,不用重新打开浏览器,节省时间,由于调试的时候,使用很方便;
    2. 可以记录之前操作状态与记录,否则每次打开使用的都是最新的“无痕”浏览器。
  2. 复用浏览器的操作步骤
    第一步:先在终端中启用复用浏览器的端口
    chrome --remote-debugging-port=9222
    第二步:在自动化代码中加入以下代码
    option = webdriver.ChromeOptions()
    option.debugger_address = "127.0.0.1:9222"
    self.driver = webdriver.Chrome(options=option)

TIPS:

  1. 本地浏览器启用的端口和python代码中的端口要一致,否则无法正常复用
  2. 端口号可以更改,不一定是9222
  3. 复用时,需要想要操作的窗口放在最前面,这样复用的时候才能使用
  4. 复用浏览器主要在调试测试代码的时候使用的比较多
  5. 当chrome --remote-debugging-port=9222执行失败,需要配置环境变量
  6. 使用浏览器复用时,需要将当前开启所有浏览器都关闭掉
  1. 示例
    第一步:终端先启动复用端口
    在这里插入图片描述
    终端执行命令前,先将所有开启的chrome浏览器都关闭,然后执行此命令,会发现会自动启动一个chrome。

第二步:执行测试用例:
以下是演示代码。
虽然在代码中我们定义了teardown函数,并且要求在测试用例运行结束后关闭浏览器。但是由于复用的关系,当我们的用例运行结束后,浏览器是不会被自动关闭的。

from time import sleep
from selenium import webdriver

class TestDemo:
    def setup(self):
        option = webdriver.ChromeOptions()
        #复用地址以及端口
        option.debugger_address = "127.0.0.1:9222"
        self.driver = webdriver.Chrome(options=option)
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    def test_form(self):
        self.driver.get("https://www.baidu.com")
        #点击登录
        self.driver.find_element_by_id("s-top-loginbtn").click()
        #输入账号
        self.driver.find_element_by_id("TANGRAM__PSP_11__userName").send_keys("CSDN_demo")
        #输入密码
        self.driver.find_element_by_id("TANGRAM__PSP_11__password").send_keys("111111")
        #点击表单中的登录
        self.driver.find_element_by_id("TANGRAM__PSP_11__submit").click()
        #停止3秒为了看结果
        sleep(3)

文末说明
推荐博文: 只需Docker,环境问题再也不是测开路上的『坑』_霍格沃兹测试开发学社的博客-CSDN博客

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值