Loading

web自动化-Selenium(一)

Selenium简介

Webdriver概述

Webdriver(Selenium2)是一种用于Web 应用程序的自动化测试工具,它提供了一套友好的API,与Selenium1(Selenium-RC)相比,Webdriver 的API更容易理解和使用,其可读性和可维护性也大大提高。Webdriver 完全就是一套类库,不依赖于任何测试框架,除了必要的浏览器驱动,不需要启动其他进程或安装其他程序,也不必像Selenium1 那样需要先启动服务。

支持浏览器

Firefox、IE、Microsoft Edge、Chrome、safari

支持语言

Java、C#、PHP、Python、Perl、Ruby

前世

Selenium RC

早期的Selenium使用的是JavaScript注入技术与浏览器打交道,需要Selenium RC启动一个Server,将操作Web元素的API调用转化为一段段Javascript,在Selenium内核启动浏览器之后注入这段Javascript。开发过Web应用的人都知道,Javascript可以获取并调用页面的任何元素,自如的进行操作。由此才实现了Selenium的目的:自动化Web操作。这种Javascript注入技术的缺点是速度不理想,而且稳定性大大依赖于Selenium内核对API翻译成的Javascript质量高低。

今生

WebDriver

当Selenium2.x 提出了WebDriver的概念之后,它提供了完全另外的一种方式与浏览器交互是。利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏览器本身(截屏,窗口大小,启动,关闭,安装插件,配置证书之类)。由于使用的是浏览器原生的API,速度大大提高,而且调用的稳定性交给了浏览器厂商本身,显然是更加科学。然而带来的一些副作用就是,不同的浏览器厂商,对Web元素的操作和呈现多少会有一些差异,这就直接导致了Selenium WebDriver要分浏览器厂商不同,而提供不同的实现。例如Firefox就有专门的FirefoxDriver,Chrome就有专门的ChromeDriver等等。(甚至包括了AndroidDriver和iOS WebDriver)

Selenium3.0发布后,最大更新点就是干掉了对selenium rc的支持,这标志着webdriver协议最终一统江湖,rc毕竟是继子,webdriver才是亲儿子,假儿子给真儿子让路,豪门继承权尘埃落定。

selenium3.0的意味着什么

webdriver 协议现在已经成为业内公认的浏览器UI测试的标准实现。简而言之,做浏览器ui测试,请认准selenium webdriver商标。各种官方支持意味着以后的浏览器UI测试的速度和稳定性会有较大的提升。selenium 2.0时代只有chrome driver是官方出品,其它实现均是第三方。从稳定性上说,2.0时代最稳定的测试浏览器是chrome和firefox,其它浏览器支持均或多或少有些问题。浏览器UI自动化测试已经成为了行业标配。这也是为什么几乎所有浏览器厂商都推出自己官方driver的原因。

RemoteWebDriver(selenium的WebDriver的基类)

启动目标浏览器,并绑定到指定端口。该启动的浏览器实例,做为web driver的remote server,Remote server 需要依赖原生的浏览器组件(如:IEDriver.dll,chromedriver.exe),来转化浏览器的api调用,一些定位元素的api都在该类中。

WebDriver

webdriver是按照server – client的经典设计模式设计的。

webdriver的作用就是创建一个新的浏览器实例,也就是启动一个Server端。

(Starts the service and then creates new instance of chrome driver)

server端就是我们的Remote server,也就是我们通过各个不同浏览器所启动的浏览器实例,在我们脚本启动浏览器后,这个浏览器就可以称之为我们的Remote server,它的职责就是等待client发送请求并做出相应处理。

client 就是我们的测试代码,我们测试代码中的所有操作,比如打开浏览器,寻找元素,点击都是以http请求的方式发送给被测试浏览器,也就是我们的Remote server,remote server接受请求,并执行相应操作,并在response中返回执行状态、返回值等信息(这里调用的接口是浏览器的源生API,而每一个浏览器都有自己的一套接口信息,这也就是为什么我们要安装不同的驱动的原因)

WebDriver工作流程

  1. 通过WebDriver创建一个浏览器服务,remote server。

  2. 脚本启动时会在新的线程中启动一个浏览器,并绑定特定的端口,没个浏览器有不同的端口段。

  3. client 创建1个session,在该session中通过http请求向remote server发送restful的请求,remote server解析请求,完成相应操作并返回response。

  4. 分析response,继续执行脚本还是结束执行

command.py

Command类中定义了WebDriver的一些常用的常量。

remote\webdrvier.py

所有浏览器webdrvier的基类,其中包含了所有webdriver的api接口

remote\remote_connection.py

包含启动Remote WebDrvier server,执行client请求,self._commands是selenium的核心请求参数,根据对应的Command常量,发送不同的http请求。

Page Object Model(POM)的优势

  1. POM提供了一种在UI层操作、业务流程与验证分离的模式,这使得测试代码变得更加清晰和高可读性
  2. 对象库与用例分离,使得我们更好的复用对象,甚至能与不同的工具进行深度结合应用
  3. 可复用的页面方法代码会变得更加优化
  4. 更加有效的命名方式使得我们更加清晰的知道方法所操作的UI元素。例如我们要回到首页,方法名命名为: gotoHomePage(),通过方法名即可清晰的知道具体的功能实现。

元素定位方法

xpath使用方法

什么是Xpath

xpath是XML路径语言,是一种查询语言,使用路径表达式浏览XML文档中的元素和属性。XPath标准语法如下:

xpath=//tagname[@attribute='value']
  • // : 选择当前节点
  • Tagname: 节点标签名
  • @: 选择属性
  • Attribute: 节点属性名
  • Value: 属性值

xpath有绝对定位和相对定位两种,绝对定位使用绝对路径,缺点是路径太长,只要一个节点变动就无法定位。

xpath支持id、class、name定位元素

# 通过ID定位
//*[@id='kw']

# 通过Class定位
//*[@class='class_name']

#通过Name定位
//*[@name='name']

xpath支持属性定位功能

# @ 代表以属性定位,后面可以接标签中任意属性
//*[@other='attribute']

当标签的属性重复时,xpath提供了通过标签来进行过滤

# 将 * 换位任意标签名,则可根据标签进行筛选
//input[@placeholder='用户名']

当标签重复时,xpath提供了层级过滤
例如:找不到儿子,那么就先找爸爸,实在不行可以先找爷爷

# 支持通过 / 进行层级递进,找到符合层级关系的标签
//form/div/input[@placeholder="用户名"]

# 当层级都重复时,可以通过单个层级的属性进行定位
//form/div[@class='login-user']/input

xpath提供了索引过滤

一个元素它的兄弟元素跟它的标签一样,这时候无法通过层级定位到。因为都是一个父亲生的,多胞胎兄弟。xpath提供了索引过滤

# 通过索引,在List中定位属性,与python的索引有些差别,Xpath从1开始 
//select[@name='city'][1]/option[1] 

# 通过多个层级的属性来定位 
//div[@class='driver'][1]/div[@class='inner'][1]

逻辑运算定位

上面如果都用上还重复的话,我们就可以使用xpath提供的终极神器,逻辑运算定位。and或or

# 通过and来缩小过滤的范围,只有条件都符合时才能定位到
//select[@name='city' and @size='4' and @multiple="multiple"]
 
# or就相反了,只要这些筛选中,其中一个出现那么久匹配到了
//select[@name='city' or @size='4']

Contains()定位

# Contains()方法也许通过部分文本来定位查找元素,CSS Selector不支持这种用法。
Xpath = //*[contains(@type,'partial_text')]
Xpath = //*[contains(@name,'partial_text')]
Xpath = //*[contains(@class,'partial_text')]
Xpath = //*[contains(@id,'partial_text')]
Xpath = //*[contains(text(),'partial_text')]
Xpath = //*[contains(@href,'partial_text')]

Starts-with()方法

# 通过开始位置包含文本的定位方式
Xpath = //*[starts-with(@type,'start_text')]
Xpath = //*[starts-with(@name,'start_text')]
Xpath = //*[starts-with(@class,'start_text')]
Xpath = //*[starts-with(@id,'start_text')]
Xpath = //*[starts-with(text(),'start_text')]
Xpath = //*[starts-with(@href,'start_text')]

用text() 定位

# 模糊定位 包含【原始】str的元素
//li[contains(text(),'原始')]

# 定位text文本为【原始数据】的元素
//li[text()="原始数据"]

用parent通过儿子定位父亲

//td[text()='轴的含义说明']/parent::tr

用ancestor通过儿子定位祖先(包括爸爸)

//td[text()='轴的含义说明']/ancestor::table

CSS和xpath区别

CSS Selector和Xpath几乎可以定位到所有Web元素(HTML和XML文档元素,Android应用的层级结构使用xml编写),它们的主要差异包括:

  1. XPath通过遍历的方式从XML文档中选择节点,CSS Selector是一种匹配模式定位,因此CSS Selector比 XPath 执行效率更高。
  2. Xpath可以通过文本来定位,而CSS Selector不能;
  3. Xpath可以通过子节点来定位父节点,CSS Selector是前向的,不能利用子节点定位父节点。
  4. CSS Selector语法相比Xpath更加简洁

CSS Selector使用方法

什么是CSS selector

CSS selector定位,实际就是HTML的CSS选择器的标签定位

CSS selector支持id、class的定位

CSS selector支持id、class的定位与HTML中CSS定位相同

# 号表id 定位有id的标签方式更加简洁
#i1

# . 代表Class 定位有id的标签方式更加简洁
.c1

# Class定位还提供了多个Class定位 通过连续 . 来缩小范围
.c1.c2.c3

CSS selector支持标签定位没什么卵用

# 与Css相同 支持标签选择器,但并没有什么用,一个页面重复的标签太多
 
# 定位方式 :直接输入标签名称

CSS selector支持任意属性定位

# 属性定位方式与css相同,直接中括号,加上属性就可以了
[name='n1']

CSS selector子字符串匹配进行定位

[id^='id_prefix_'] # id前缀为‘id_prefix_’的元素
[id$='_id_sufix'] # id后缀为‘_id_sufix’的元素
[id*='id_pattern'] # id包含‘id_pattern’的元素

单单属性定位还不够,CSS selector还提供了标签属性组合定位

# 与css 定位相同 等同于我们标签属性选择器
input[name='n1']

# 当与ID、Class 组合使用时书写方式更为简单
Class
input.c1
ID
input#i1

CSS selector提供了多属性组合过滤

# Css Selector 的多属性组合选择过滤 没有and 只需要多个[] 连接 就可以
select[name='city'][size='4'][multiple="multiple"]

CSS selector也支持层级关系定位

# 与Xpath的不同 Css Selector通过 > 来区分层级的界定
select>option[value='3']

CSS selector 可以用索引来定位

# css也可以通过索引nth-child(1)来定位子元素,直接翻译过来就是第几个小孩
# 总结:选择标签后,找第几个小孩即可
# Select控件第三个Opel
select>select>option:nth-child(3)
# CheckBox第一个Volvo
checkbox>input:nth-child(1)

# CheckBox第二个Saab
checkbox>input:nth-child(4)
# RadioBox第二个Saab
radio>input:nth-child(4)

CSS selector 模糊匹配

# ^= 匹配元素属性以什么开头
input[value^="登"]

# $= 匹配属性以什么结尾
input[value$="录"]

# *= 匹配属性包含什么值 input
[value*="录"]

常用API

浏览器滚动条操作

上下滚动

使用JavaScript操作浏览器的滚动条。

# 拖动滚动条至底部
js1="document.documentElement.scrollTop=10000"
driver.execute_script(js1)
# 拖动滚动条至顶部
js2="document.documentElement.scrollTop=0"
driver.execute_script(js2)

左右拖动

# 左右方向的滚动条可以使用window.scrollTo(左边距,上边距)方法
# example
js="window.scrollTo(200,1000)"
driver.execute_script(js)

窗口最大化

driver.maximize_window() # 窗口最大化

后退、前进、刷新

driver.back() # 向后退
driver.forward() # 向前进
driver.refresh()  # 刷新页面

截屏

driver.get_screenshot_as_file(filename)

# 封装方法
def insert_img(driver, filename):
    func_path = os.path.dirname(__file__)
    # print(func_path)

    base_dir = os.path.dirname(func_path)
    # print(base_dir)

    base_dir = str(base_dir)
    base_dir = base_dir.replace('\\', '/')  # 转换成反斜杠

    # print(base_dir)  # 字符串已经转换了
    base = base_dir.split('/Website')[0]  # 列表读取第一个元素
    # print(base)

    filepath = base + '/Website/test_report/screenshot/' + filename
    driver.get_screenshot_as_file(filepath)

获取元素里属性值

search = self.find_element(*self.search_loc).get_attribute('placeholder')

获取标签内部文案,要用innerText

针对复选框,判断是否勾选上

driver.find_element_by_id('TANGRAM__PSP_10__memberPass').is_selected() # 通常返回布尔值,即True或Failse,来判断

检查元素是否显示(是否可见)

driver.find_element_by_id('TANGRAM__PSP_10__memberPass').is_display()  # 用来判断元素是否出现,通常返回布尔值,即True或Failse,来判断

检查元素是否能编辑

driver.find_element_by_id('TANGRAM__PSP_10__memberPass').is_enable()  # 用来判断元素(input\select标签等)是否可编辑,通常返回布尔值,即True或Failse,来判断

清空输入框内文本

driver.find_element_by_id('TANGRAM__PSP_10__memberPass').clear()  # 用于清除input标签内文本

切换tab窗口

# 1、如果我要当前显示最后一个窗口,封装方法如下:
    def switch_window(self):
        all_handles = self.driver.window_handles
        self.driver.switch_to.window(all_handles[-1])

# 2、如果我要当前显示倒数第二个窗口,封装方法如下:
    def switch_window(self):
        all_handles = self.driver.window_handles
        self.driver.switch_to.window(all_handles[-2])

# 2、如果我要当前显示第一个窗口,封装方法如下:
    def switch_window(self):
        all_handles = self.driver.window_handles
        self.driver.switch_to.window(all_handles[0])

关闭和退出

# 关闭当前窗口
    def close_window(self):
        self.driver.close()

# 关闭浏览器,退出
    self.driver.quit()

切换到框架frame操作

# 1、先切换到‘top-frame’框架
driver.switch_to_frame('top-frame')

# 2、在这个框架下定位input元素进行操作
driver.find_element_by_css_selector('#newtag').send_keys(123)

# 3、紧接着从‘top-frame’框架切换到‘baidu-frame’框架
driver.switch_to_frame('baidu-frame')

# 4、在这个框架下定位input元素进行操作
driver.find_element_by_css_selector('#kw').send_keys(123123)

frame操作,如果里面有嵌套多层frame,那需要一层一层进去,进去后一层一层出来

# 1、从当前框架回到上一层框架
driver.switch_to.parent_frame()

# 2、直接回到默认层框架
driver.switch_to.default_content()

获取当前URL

current_url = self.driver.current_url
print(current_url) # 打印当前url

鼠标悬浮

# 1、先导入模块
from selenium.webdriver import ActionChains

# 2、定位元素
hover_element = driver.find_element_by_css_selector('div.list-top-mld p')
# 对该元素执行悬停操作
ActionChains(driver).move_to_element(hover_element).perform()
# 等待几秒看看效果
time.sleep(3)

from selenium.webdriver.common.action_chains import ActionChains

# 先定位元素
element = driver.find_element_by_css_selector('#a')

element2 = driver.find_element_by_css_selector('#dis1')

action = ActionChains(driver)

# 鼠标悬浮在element元素上,点击element2元素
action.move_to_element(element).click(element2).perform()

time.sleep(2)

独立键盘操作

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import os
import sys
import win32api
import win32con


curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
PathProject = os.path.split(rootPath)[0]
sys.path.append(rootPath)
sys.path.append(PathProject)

import win32api
import win32con

class KeyboardKeys(object):
    #模拟键盘按键类
    VK_CODE = {'backspace': 0x08,
               'tab': 0x09,
               'clear': 0x0C,
               'enter': 0x0D,
               'shift': 0x10,
               'ctrl': 0x11,
               'alt': 0x12,
               'pause': 0x13,
               'caps_lock': 0x14,
               'esc': 0x1B,
               'spacebar': 0x20,
               'page_up': 0x21,
               'page_down': 0x22,
               'end': 0x23,
               'home': 0x24,
               'left_arrow': 0x25,
               'up_arrow': 0x26,
               'right_arrow': 0x27,
               'down_arrow': 0x28,
               'select': 0x29,
               'print': 0x2A,
               'execute': 0x2B,
               'print_screen': 0x2C,
               'ins': 0x2D,
               'del': 0x2E,
               'help': 0x2F,
               '0': 0x30,
               '1': 0x31,
               '2': 0x32,
               '3': 0x33,
               '4': 0x34,
               '5': 0x35,
               '6': 0x36,
               '7': 0x37,
               '8': 0x38,
               '9': 0x39,
               'a': 0x41,
               'b': 0x42,
               'c': 0x43,
               'd': 0x44,
               'e': 0x45,
               'f': 0x46,
               'g': 0x47,
               'h': 0x48,
               'i': 0x49,
               'j': 0x4A,
               'k': 0x4B,
               'l': 0x4C,
               'm': 0x4D,
               'n': 0x4E,
               'o': 0x4F,
               'p': 0x50,
               'q': 0x51,
               'r': 0x52,
               's': 0x53,
               't': 0x54,
               'u': 0x55,
               'v': 0x56,
               'w': 0x57,
               'x': 0x58,
               'y': 0x59,
               'z': 0x5A,
               'numpad_0': 0x60,
               'numpad_1': 0x61,
               'numpad_2': 0x62,
               'numpad_3': 0x63,
               'numpad_4': 0x64,
               'numpad_5': 0x65,
               'numpad_6': 0x66,
               'numpad_7': 0x67,
               'numpad_8': 0x68,
               'numpad_9': 0x69,
               'multiply_key': 0x6A,
               'add_key': 0x6B,
               'separator_key': 0x6C,
               'subtract_key': 0x6D,
               'decimal_key': 0x6E,
               'divide_key': 0x6F,
               'F1': 0x70,
               'F2': 0x71,
               'F3': 0x72,
               'F4': 0x73,
               'F5': 0x74,
               'F6': 0x75,
               'F7': 0x76,
               'F8': 0x77,
               'F9': 0x78,
               'F10': 0x79,
               'F11': 0x7A,
               'F12': 0x7B,
               'F13': 0x7C,
               'F14': 0x7D,
               'F15': 0x7E,
               'F16': 0x7F,
               'F17': 0x80,
               'F18': 0x81,
               'F19': 0x82,
               'F20': 0x83,
               'F21': 0x84,
               'F22': 0x85,
               'F23': 0x86,
               'F24': 0x87,
               'num_lock': 0x90,
               'scroll_lock': 0x91,
               'left_shift': 0xA0,
               'right_shift ': 0xA1,
               'left_control': 0xA2,
               'right_control': 0xA3,
               'left_menu': 0xA4,
               'right_menu': 0xA5,
               'browser_back': 0xA6,
               'browser_forward': 0xA7,
               'browser_refresh': 0xA8,
               'browser_stop': 0xA9,
               'browser_search': 0xAA,
               'browser_favorites': 0xAB,
               'browser_start_and_home': 0xAC,
               'volume_mute': 0xAD,
               'volume_Down': 0xAE,
               'volume_up': 0xAF,
               'next_track': 0xB0,
               'previous_track': 0xB1,
               'stop_media': 0xB2,
               'play/pause_media': 0xB3,
               'start_mail': 0xB4,
               'select_media': 0xB5,
               'start_application_1': 0xB6,
               'start_application_2': 0xB7,
               'attn_key': 0xF6,
               'crsel_key': 0xF7,
               'exsel_key': 0xF8,
               'play_key': 0xFA,
               'zoom_key': 0xFB,
               'clear_key': 0xFE,
               '+': 0xBB,
               ',': 0xBC,
               '-': 0xBD,
               '.': 0xBE,
               '/': 0xBF,
               '`': 0xC0,
               ';': 0xBA,
               '[': 0xDB,
               '\\': 0xDC,
               ']': 0xDD,
               "'": 0xDE,
               '`': 0xC0}

    @staticmethod
    def keyDown(keyName):
        #按下按键
        win32api.keybd_event(KeyboardKeys.VK_CODE[keyName],0,0,0)


    @staticmethod
    def keyUp(keyName):
        #释放按键
        win32api.keybd_event(KeyboardKeys.VK_CODE[keyName],0,win32con.KEYEVENTF_KEYUP,0)


    @staticmethod
    def oneKey(key):
        #模拟单个按键
        KeyboardKeys.keyDown(key)
        KeyboardKeys.keyUp(key)

    @staticmethod
    def twoKeys(key1,key2):
        #模拟两个组合键
        KeyboardKeys.keyDown(key1)
        KeyboardKeys.keyDown(key2)
        KeyboardKeys.keyUp(key2)
        KeyboardKeys.keyUp(key1)
def type_keyboard(self):
    kb = win32key_board.KeyboardKeys()
    kb.oneKey("m")
    kb.oneKey("h")
    kb.oneKey("p")
    kb.oneKey("enter")

【鼠标键盘操作】

https://blog.csdn.net/huilan_same/article/details/52305176

等待

UI自动化什么最关键

稳定性

隐式等待

【固定等待】、【隐式等待】

time.sleep()   # 只适用于代码调试的时候用

# 1、需要导入模块
from selenium.common.exceptions import NoSuchElementException

# 2、调用implicity_wait()方法
driver.implicitly_wait(2)  # 隐式等待
# 隐式等待,设置对多等2s

显示等待

显示等待是针对某一个元素进行相关等待判断

在页面元素定位时,等待元素出现立马执行,提高了代码执行效率

首先导入模块

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

实例化

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

e = EC.presence_of_element_located((By.CSS_SELECTOR,'i1'))

element = WebDriverWait(driver,10,0.5).until(e)

element.send_keys(12312)

详解

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

base_url = "http://www.baidu.com"
driver = webdriver.Firefox()
driver.implicitly_wait(5)
'''隐式等待和显示等待都存在时,超时时间取二者中较大的'''
locator = (By.ID,'kw')
driver.get(base_url)

WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
'''判断title,返回布尔值'''

WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))
'''判断title,返回布尔值'''

WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
'''判断某个元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement'''

WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su')))
'''判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0'''

WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))
'''判断元素是否可见,如果可见就返回这个元素'''

WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有1个元素存在于dom树中,如果定位到就返回列表'''

WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有一个元素在页面中可见,如果定位到就返回列表'''

WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'设置'))
'''判断指定的元素中是否包含了预期的字符串,返回布尔值'''

WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下'))
'''判断指定元素的属性值中是否包含了预期的字符串,返回布尔值'''

#WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))
'''判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False'''
#注意这里并没有一个frame可以切换进去

WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap')))
'''判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素'''
#注意#swfEveryCookieWrap在此页面中是一个隐藏的元素

WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click()
'''判断某个元素中是否可见并且是enable的,代表可点击'''
driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click()
#WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click()

#WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su')))
'''等待某个元素从dom树中移除'''
#这里没有找到合适的例子

WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))
'''判断某个元素是否被选中了,一般用在下拉列表'''

WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''

WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''
driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()

instance = WebDriverWait(driver,10).until(EC.alert_is_present())
'''判断页面上是否存在alert,如果有就切换到alert并返回alert的内容'''
print instance.text
instance.accept()

driver.close()
posted @ 2020-03-13 23:40  Binzichen  阅读(376)  评论(0编辑  收藏  举报