WebDriver使用入门

WD.py是一个Python WebDriver客户端,实现了WebDriver协议中的大部分API。 它最初是为Macaca(一个Node.js驱动的WebDriver服务器)而设计的,但也可以应用于WebDriver服务器的其他实现,比如Selenium,Appium等。

自动化测试

查找元素

WebDriver的查找元素命令允许分别查找单个元素和元素集合,定位策略如下:

  • 文本
  • id
  • XPath
  • 链接文本
  • 部分链接文本
  • 标签名
  • 类名
  • CSS选择器

找到元素的基本方法是element(),例如查找id为“login”的元素:

driver.element('id', 'login')

但是在大多数情况下,不需要使用这个基本的方法,为了方便起见,有很多扩展方法。

文本

例如,查找页面上name属性为“Login failed!”的元素:

driver.element_by_name('Login failed!')

id

例如,查找id为“login”的元素:

driver.element_by_id('login')

XPath

XPath是XML Path的简称,由于HTML文档本身就是一个标准的XML页面,所以可以使用XPath的语法来定位页面元素。这个方法是非常强大的元素查找方式,使用这种方法几乎可以定位到页面上的任意元素。

例如,查找页面上id为“finding-elements-to-interact”的元素下的第4个table元素:

driver.element_by_xpath('//*[@id="finding-elements-to-interact"]/table[4]')

链接文本

这个方法比较直接,即通过超文本链接上的文字信息来定位元素,这种方式一般专门用于定位页面上的超文本链接。

例如,查找页面上文字为“macaca”的超文本链接:

driver.element_by_link_text('macaca')

部分链接文本

这个方法是上一个方法的扩展,当不能准确知道超链接上的文本信息或者只想通过一些关键字进行匹配时,可以使用这个方法来通过部分链接文字进行匹配。

例如,查找页面上部分文字为“maca”的超文本链接:

driver.element_by_partial_link_text('maca')

标签名

该方法可以通过元素的标签名称来查找元素,需要注意的是,这个方法搜索到的元素通常不止一个。

例如,查找页面上的“ input”标签:

driver.element_by_tag_name('input')

此外,WebDriver上的所有元素方法都可以在WebElement上使用,也就是从当前Web元素中查找元素:

web_element.element_by_id('ss')

类名

一般程序员或页面设计师会给元素直接赋予一个样式属性或者利用css文件里的伪类来定义元素样式,这个方法可以利用元素的css样式表所引用的伪类名称来进行元素查找。

例如,查找页面上className属性为“btn”的元素:

driver.element_by_class_name('btn')

CSS选择器

这种元素定位方式跟XPath比较类似,但执行速度较快,所以功能也是蛮强大的。

例如,查找页面上样式表为“.btn”的元素:

driver.element_by_css_selector('.btn')

异常处理

当没有找到元素时,会引发WebDriverException异常。为了避免这种情况,可是使用element_if_exists方法,如果元素存在,则返回True,否则返回False,例如:

driver.element_by_id_if_exists('login')

也可以使用element_or_none方法,如果元素存在,则返回元素,否则返回None,例如:

driver.element_by_id_or_none('login')

此外,还有wait_for方法等待元素满足给定条件,默认等待10秒,每个间隔1秒,断言器函数默认为asserters.is_displayed,例如:

driver.wait_for_element_by_id('login')

按键输入

当需要完成一个输入字段的操作时,可以将一系列的按键行为发送给一个元素:

driver.web_element.send_keys('123456')

send_keys方法也接受一个数组,这在发送特殊键(不是文本的按键)时非常有用:

driver.web_element.send_keys([1, 2, 3, 4, 5, 6])

PC按键映射:

映射 按键 键码
\uE002 HELP 259 (0x00000103)
\uE003 BACK_SPACE 67 (0x00000043)
\uE004 TAB 61 (0x0000003d)
\uE005 CLEAR 28 (0x0000001c)
\uE007 ENTER 66 (0x00000042)
\uE008 SHIFT 59 (0x0000003b)
\uE009 CONTROL 113 (0x00000071)
\uE00A ALT 57 (0x00000039)
\uE00B PAUSE 121 (0x00000079)
\uE00C ESCAPE 111 (0x0000006f)
\uE00E PAGE_UP 92 (0x0000005c)
\uE00F PAGE_DOWN 93 (0x0000005d)
\uE010 END 123 (0x0000007b)
\uE011 HOME 122 (0x0000007a)
\uE012 ARROW_LEFT 21 (0x00000015)
\uE013 ARROW_UP 19 (0x00000013)
\uE014 ARROW_RIGHT 22 (0x00000016)
\uE015 ARROW_DOWN 20 (0x00000014)
\uE016 INSERT 124 (0x0000007c)
\uE017 DELETE 112 (0x00000070)
\uE031 F1 131 (0x00000083)
\uE032 F2 132 (0x00000084)
\uE033 F3 133 (0x00000085)
\uE034 F4 134 (0x00000086)
\uE035 F5 135 (0x00000087)
\uE036 F6 136 (0x00000088)
\uE037 F7 137 (0x00000089)
\uE038 F8 138 (0x0000008a)
\uE039 F9 139 (0x0000008b)
\uE03A F10 140 (0x0000008c)
\uE03B F11 141 (0x0000008d)
\uE03C F12 142 (0x0000008e)
\uE03D META 117 (0x00000075)

Android按键映射:

映射 按键 键码
\uE101 POWER 电源键 26 (0x0000001a)
\uE102 VOLUME_UP 音量加 24 (0x00000018)
\uE103 VOLUME_DOWN 音量减 25 (0x00000019)
\uE104 VOLUME_MUTE 禁音 164 (0x000000a4)
\uE105 HOME_SCREEN HOME键 3 (0x00000003)
\uE106 BACK BACK键 4 (0x00000004)
\uE107 MENU MENU键 82 (0x00000052)
\uE108 CAMERA 拍照键 27 (0x0000001b)
\uE109 CALL 电话键 5 (0x00000005)
\uE10A END_CALL 结束电话键 6 (0x00000006)
\uE10B SEARCH 搜索键 84 (0x00000054)
\uE10C DPAD_LEFT 导航左键 21 (0x00000015)
\uE10D DPAD_UP 导航上键 19 (0x00000013)
\uE10E DPAD_RIGHT 导航右键 22 (0x00000016)
\uE10F DPAD_DOWN 导航下键 20 (0x00000014)
\uE110 DPAD_CENTER 导航确定键 23 (0x00000017)

iOS按键映射:

映射 按键
\uE105 HOME_SCREEN HOME键

使用数组发送特殊键非常方便:

driver.web_element.send_keys([1, DELETE, 1, 2, 3, 4, 5, 6])

屏幕快照

截图时可以返回截图的base64编码字符串:

base64_str = driver.take_screenshot()

或者保存截图到给定的路径:

driver.save_screenshot('./screen.png')

save_screenshot方法具有可选的第二个参数来决定是否由于某种原因无法保存到文件系统时忽略IOError。例如,没有读写权限时,忽略异常信息:

driver.save_screenshot('/etc/screen.png', True)

切换环境

对于移动端测试,可能需要在Native(原生)和Webview(H5)之间切换环境,首先获取现有的环境:

ctxs = driver.contexts
print(ctxs) # ['NATIVE', 'WEBVIEW_1', 'WEBVIEW_2']

然后切换到指定的环境:

driver.context = 'WEBVIEW_1'
print(driver.context) # WEBVIEW_1

执行JS片段

在一些复杂的情况下,可能需要在页面中插入一段JavaScript代码,并得到想要的任何东西。可以在脚本中使用arguments来表示脚本之后的索引参数。

script = 'return document.querySelector(".btn").tagName === arguments[0]'
args = ['div']
result = driver.execute_script(script, *args)

上面的脚本等于JavaScript中的IIFE:

function () {
  return document.querySelector(".btn").tagName === "div"
}()

WebElement方法

WebElement的实例方法主要与行为元素有关,比如点击元素、获取标签名或元素的内部文本。WebElement实例是通过查找元素命令返回的,例如通过id检索元素:

web_element = driver.element_by_id('login')
print(type(web_element) == WebElement) # True

例如点击元素:

web_element.click()

例如获取元素的标签名称:

tag_name = web_element.tag_name

例如获取元素的内部文本:

text = web_element.text

编码风格

建议使用官方推荐的两种编码风格,第一种是使用额外的括号:

(
    driver
        .get('https://www.google.com')
        .element_by_id('login')
        .click()
)

第二种是使用反斜杠:

driver                             \
    .get('https://www.google.com') \
    .element_by_id('login')        \
    .click()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容