zoukankan      html  css  js  c++  java
  • selenium源码分析以及api讲解

    第三方模块库(pip安装的)放在External Libraries下面的site-packages里,要把谷歌、火狐和IE浏览器的驱动放在python.exe的同级目录下,我的是放在C:Miniconda3Scripts(Scripts文件夹和python.exe文件是在同一个目录下),谷歌浏览器是51版本的,直接用那个驱动就行

    什么是page object设计模式?
    Page Object模式是使用Selenium的广大同行最为公认的一种设计模式,在设计测试时,把元素和方法按照页面抽象出来,分离成一定的对象,然后再进行组织
    Page Object模式,创建一个对象来对应页面的一个应用,故我们可以为每个页面定义一个类,并为每个页面的属性和操作构建模型,体现在对界面交互细节的封装,测试在更上层使用页面对象,在底层的属性或者操作的更改不会中断测试,减少代码重复,提高测试代码的可读性和可维护性

    将一个页面抽象成一个类,将这个页面上能够抽象成一个个方法

    1、把每个页面当成一个页面对象,对页面的可操作功能进行封装
    2、测试case通过调用页面对象的方式来完成case的编写
    3、可以做到UI操作与case编写进行分离

     

    UI自动化面试题的网址:http://www.imdsx.cn/index.php/2017/08/04/mianshi/

    selenium流程:

    selenium是经典的server-client设计模式,webdriver在启动的时候启动了server(浏览器),client(代码),创建了一个浏览器,通过session去指定我们要连接的浏览器,底层http请求调用浏览器源生api,处理我们的请求,点击、拖拽,执行完成之后返回结果,client端去处理,判断状态码是否为200,是否成功了,进而进行下一步操作

    现在用的selenium是3.x版本的,完全用webdriver,之前的2.x版本采用selenium RC的方式,解析我们的客户端代码,转换成js代码执行操作,弊端是完全依赖于转换精准度

    from selenium import webdriver
    driver = webdriver.Chrome() # 启动谷歌浏览器
    # driver = webdriver.Firefox() 启动浏览器,也可以使用火狐浏览器
    # driver = webdriver.Ie() 启动浏览器,也可以使用IE浏览器
    driver.get('http://ui.imdsx.cn/uitester/') # 请求目标网址,打开这个网址
    driver.maximize_window() #全屏浏览器
    from selenium import webdriver
    option = webdriver.ChromeOptions() # Chrome的配置
    option.add_argument('--start-maximized') # 启动就放大浏览器
    driver = webdriver.Chrome(chrome_options=option) # 启动浏览器
    driver.get('http://ui.imdsx.cn/uitester/') # 请求目标网址,打开这个网址

    定位方式,也叫选择器(selenium提供了大概18种方式)

    1、单数模式 8种(重点)

    尽量用css_selector定位,css_selector定位不了使用xpath辅助定位

    2、复数模式 8种,基本不用

    3、底层实现 2种,基本不用

    driver.find_element()
    driver.find_elements()

    常用api:

    # 执行JavaScript语句,window.scrollTo(0,0)是操作滚动条,x轴是0,y轴>0就往下拉滚动条,重点
    driver.execute_script('window.scrollTo(0,0)')

     

    # 最大化当前窗口,不需要传参,重点
    driver.maximize_window()

     

    # 窗口操作:获取窗口的height和width
    size = driver.get_window_size()
    print(size)  # 打印出{'width': 1936, 'height': 1056}

    # 设置窗口的height和width
    driver.set_window_size(2000, 1000)

    # 浏览器的按钮操作
    driver.find_element_by_link_text('跳转大师兄博客地址').click()
    time.sleep(2)
    driver.back()  # 后退
    time.sleep(2)
    driver.forward()  # 前进
    time.sleep(2)
    driver.refresh()  # 刷新


    截图当前页面:as_png的上层封装,只需要传入图片名称,在当前目录下自动生成图片,以.png结尾,如果以别的图片格式会报警告,重点
    driver.get_screenshot_as_file('fileName.png')

     

    # 返回当前url
    print(driver.current_url)
    # 返回浏览器名称
    print(driver.name)
    # 返回页面源码
    print(driver.page_source)
    # 返回标题
    print(driver.title)

    ElementApi接口:
    # element.get_attribute,根据标签属性名称,获取属性value
    element = driver.find_element_by_link_text('跳转大师兄博客地址')
    data = element.get_attribute('innerText')
    result = element.get_attribute('href')
    print(data)  # 打印出a标签之间的文案:跳转大师兄博客地址
    print(result)  # 打印出超链接路径:http://www.imdsx.cn/


    # 向文本框发送字符串
    element.send_keys('哈哈哈')


    # is_selected(),判断是否勾选,返回一个布尔值
    flag1 = driver.find_element_by_css_selector('#on').is_selected()
    print(flag1)  # 打印True
    flag2 = driver.find_element_by_css_selector('#off').is_selected()
    print(flag2)  # 打印False


    # is_displayed(),判断在页面是否展示,返回一个布尔值
    flag = driver.find_element_by_css_selector('#dis1').is_displayed()
    print(flag)  # 源码里有display:none,打印False


    # 清除文本框里的内容
    element.clear()


    # 鼠标左键点击操作
    element.click()

    # 获取浏览器全部的handles,和@property一起使用,后面不用加括号,重点
    print(driver.window_handles)
    # 获取当前浏览器handle,可以理解为窗口的名字,和@property一起使用,后面不用加括号,重点
    print(driver.current_window_handle)
    driver.find_element_by_link_text('新建标签页面').click()
    # 获取浏览器全部的handles
    print(driver.window_handles)  # 打印的是一个list
    # 获取当前浏览器handle
    print(driver.current_window_handle)  # 从打印结果可以看到,跳转到新的页面,默认还是显示之前的handle

     

    import time
    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get('http://ui.imdsx.cn/uitester/')
    time.sleep(1)
    driver.execute_script('window.scrollTo(0,0)')  # 执行js脚本,操作滚动条,x轴是0,y轴>0就往下拉
    time.sleep(1)
    driver.maximize_window()
    # 获取浏览器全部的handles
    print(driver.window_handles)
    # 获取当前浏览器handle
    print(driver.current_window_handle)
    driver.find_element_by_link_text('新建标签页面').click()
    # 获取浏览器全部的handles
    print(driver.window_handles)
    # 获取当前浏览器handle
    print(driver.current_window_handle)  # 从打印结果可以看到,跳转到新的页面,默认还是显示之前的handle
    driver.switch_to.window(driver.window_handles[-1])  # switch_to.window切换到另一个页面,-1代表新打开的窗口
    print('切换完成后:', driver.current_window_handle)
    driver.find_element_by_css_selector('#newtag').send_keys('切换成功了')  # 在新页面输入内容
    driver.close()
    time.sleep(2)
    driver.switch_to.window(driver.window_handles[-1])  # 关闭新页面后切换到最初的页面,取0和-1都可以
    time.sleep(2)
    driver.find_element_by_css_selector('#i1').send_keys(111111)
    driver.quit()

    # 关闭与退出:
    # 全部退出webdriver的浏览器,重点
    driver.quit()
    # 只退出当前的tag页面
    driver.close()

    # alert三种操作方式,了解就行
    driver.switch_to.alert.dismiss()  # 取消
    driver.switch_to.alert.accept()  # 确认
    print(driver.switch_to.alert.text)  # 获取文案,和@property一起使用,后面不用加括号

    import time
    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get('http://ui.imdsx.cn/uitester/')
    driver.execute_script('window.scrollTo(0,0);')
    driver.find_element_by_css_selector('#alert').click()  # 点击alert按钮,弹出提示框
    driver.switch_to.alert.accept()  # 关闭提示框,确定

    driver.find_element_by_css_selector('#confirm').click()
    driver.switch_to.alert.dismiss()  # 关闭提示框,取消

    driver.find_element_by_css_selector('#confirm').click()
    print(driver.switch_to.alert.text)  # 获取文案,在pycharm里打印文案,打印出CONFIRM弹框!!

    可以switch_to windowalert也可以switch_to frame
    标签iframe的重点:iframe是一层一层的跳转
    1、driver.switch_to.frame('attribute')  # 向下跳一层,直接传id或name的属性值
    2、driver.switch_to.parent_frame()  # 向上跳一层
    3、driver.switch_to.default_content()  # 跳到最外层
    selenium学习页面->新建标签页面->百度页面,然后再从百度页面跳到新建标签页面的代码如下:

    从selenium学习页面跳到新建标签页面,再跳到百度页面,在百度输入框里输入内容,然后跳到最外层,在id为i1的文本框里输入内容的代码如下:

    # 如果没有idname属性,切换iframe通过对象的方式也是ok的
    element = driver.find_element_by_css_selector('[src="/new-index/"]')
    driver.switch_to.frame(element)
    driver.find_element_by_css_selector('#newtag').send_keys(111)

    # select模块,HTML中通过select标签生成的下拉框,就可以通过Select模块进行处理

    # 鼠标悬浮操作
    点击鼠标悬浮下的双击按钮,第一种方式是用move_to_element,鼠标悬浮到目标元素上再click,代码如下:

    import time
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains  # 连贯操作,把多个函数名追加到一个数组里,然后.preform就能实现连贯操作
    driver = webdriver.Chrome()
    driver.get('http://ui.imdsx.cn/uitester/')
    time.sleep(1)
    driver.execute_script('window.scrollTo(0,0)')
    time.sleep(1)
    driver.maximize_window()

    action = ActionChains(driver)
    element = driver.find_element_by_css_selector('#a')
    element2 = driver.find_element_by_css_selector('#dis1')
    action.move_to_element(element).click(element2).perform()  # 看源码把两个函数名放到一个list里,perform是使函数运行
    time.sleep(3)
    driver.quit()

    第二种方式是用操作js,通过id找到鼠标悬浮清空下方input框value参数这个div,通过js将display为none改为,然后可以看到双击按钮,点击即可

    import time
    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get('http://ui.imdsx.cn/uitester/')
    time.sleep(1)
    driver.execute_script('window.scrollTo(0,0)')
    time.sleep(1)
    driver.maximize_window()
    js = "document.getElementById('dis1').style.display=''"  # 将style属性的display属性干掉,把none改为空
    driver.execute_script(js)
    time.sleep(2)
    driver.find_element_by_css_selector('#dis1').click()
    time.sleep(3)
    driver.quit()

    拼图drag_and_drop(element,target),element是源,target是拖拽到的位置,代码如下:

    import time
    from selenium.webdriver.common.action_chains import ActionChains  # 连贯操作
    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get('http://ui.imdsx.cn/move/')
    time.sleep(1)
    driver.execute_script('window.scrollTo(0,0)')
    time.sleep(1)
    driver.maximize_window()
    s0 = driver.find_element_by_css_selector('#dragger')
    s1 = driver.find_element_by_css_selector('#dragger1')
    s2 = driver.find_element_by_css_selector('#dragger2')
    s3 = driver.find_element_by_css_selector('#dragger3')

    t0 = driver.find_element_by_css_selector('#i1')
    t1 = driver.find_element_by_css_selector('#i2')
    t2 = driver.find_element_by_css_selector('#i3')
    t3 = driver.find_element_by_css_selector('#i4')
    time.sleep(2)
    ActionChains(driver).drag_and_drop(s0, t0).drag_and_drop(s1, t1).drag_and_drop(s2, t2).drag_and_drop(s3, t3).perform()
    time.sleep(3)
    driver.quit()

    # deselect_by_value,通过value属性,来取消对应option,取消选中,只用于多选,[@name='city'][2]是多选框
    # element = driver.find_element_by_xpath("//select[@name='city'][2]")
    # Select(element).deselect_by_value('4')

    对于处理上传图片的定位,如果是input类型的可以通过send keys来搞定,图片写绝对路径,如下图:

  • 相关阅读:
    nth-child与nth-of-type
    改变事件绑定的this的问题
    瀑布流的一些CSS实现方式
    事件捕获与冒泡的再探
    为学
    ECharts导出word 图表模糊失真
    垂直对齐:vertical-align:super属性
    Vuex- Action的 { commit } {commit}是什么写法
    修改对象中的属性名
    echarts 角度渐变环形图心得
  • 原文地址:https://www.cnblogs.com/laosun0204/p/9013829.html
Copyright © 2011-2022 走看看