这篇文章讨论selenium对于网页控件的操作。网页控件不像driver或是浏览器那样设置好直接用就可以了,操作一个网页控件我们首先要知道它在网页上的位置,找到它,然后再操作。所以我想先介绍一个必要的知识点– 控件的定位。
那怎么找到网页上的元素呢?除非是极简风格或是本身网站就简单,现在大多数网站源代码都很多很长。就即便是看起来很简单的网站,比如韩寒的“一个”(www.wufazhuce.com),打开源代码一看也是很长的。假设我现在想找下方某一篇文章的元素位置:
要是一行一行看源代码找,那肯定要花很长时间,不划算。不过没关系,现在咱们使用的三种浏览器都有自己内嵌的工具可以帮助我们找到想要的元素,不管网页多长多复杂,定位速度都很快。FireFox的内嵌工具叫Firebug,作为该浏览器其中一个插件存在。打开FireFox,选择”add-on”并搜索FireBug,可以找到该工具:
我们最好也把下面的FirePath也安装上,以后会用到。装好后我们会在浏览器右上角看到一个小虫子的图标,不过暂时还是灰色的,因为没激活。FireBug嘛,bug,小虫子。点击激活它,然后打开咱们的测试网站webelements.html就可以开始使用了。比如我想找页面上的链接“点击这里跳转”,只要把鼠标移到该链接上方->右键-> Inspect Element with Firebug(用Firebug查看元素),就可以看到这个链接元素的位置和代码,高亮显示:
我们的演示网站比较简单,大家可以在更复杂的网站上实验。
以上是FireFox。相比之下Chrome比较简单,不需要安装任何插件,因为它本身自带一个开发者工具。直接在元素上右键->Inspect(查看)就会弹出开发者工具:
IE也不需要插件,右键->Inspect Element(查看元素)即可。网页源代码不会因为浏览器的改变而发生变化,所以其实不管使用哪种浏览器,只要我们能定位到我们想要的元素就可以了。
定位到了我们想要的元素然后呢?我们可以在浏览器上鼠标右键点点点找到该元素,但和我们写的程序有什么关系呢?怎么能通过程序知道它的位置呢?所以我们要做的,就是把鼠标点出来的元素代码通过某种媒介告诉我们写的程序,而这个媒介就是定位器(Locators):
我们在eclipse里新建一个java项目叫SeleniumId,然后建包com.test -> Test.java,把该引的selenium jar包引进来,把driver设置创建好。我们还是用测试网页webelements.html做例子。直接上代码:
网页元素有8种定位器,任何一个网页元素都可以通过这8种之一找到:
1. Id;
2. Name;
3. ClassName;
4. TagName;
5. LinkText;
6. PartialLinkText;
7. CSS Locator;
8. Xpath。
还不少,后来我自己学习的时候在他人基础上编了个口诀记的:“一个id,两个link(Link, PartialLink),三个name(Name, ClassName, TagName)外加两个大bug(CSS Locator, Xpath)。”我管最后两个叫大bug因为一个网页元素可以没有id、name、link,但一定会有xpath。而且现在基本看不到不用css的网站了,所以css locator大部分情况也能通用。这二者秒杀一切网页元素,所有的都能找到,很bug。以后做例子的时候大家就能体会到了。
还记得前面咱们之前说driver还有一个方法叫findElement()吗?咱们还写了这么一句driver.findElement(),findElement的意思是找到元素。这句代码就是用来接收定位器的,让定位器作为参数传入findElement方法。
现在开始介绍第一种定位器id。id是一个网页元素的属性,它的语法格式是:
举个例子,用firefox打开咱们的webelements的网站,比如我们想定位第三个网页元素链接,用firebug查看结果如下:
我们可以看到链接这个网页元素有个id=hyperlink的属性。所以,我们的程序可以这么继续写:
By.id(“hyperlink”)作为参数传入findElement()方法,里面有一个关键字叫By,英文里是“依靠”的意思,所以这句话的意思就是“依靠一个id值为hyperlink的属性找到某控件”。记起来也就不难了。By这个关键字很重要,只要一设计网页控件定位就需要它。findElement()方法返回的是一个网页元素的对象,类型是WebElement,咱们这个例子里指的就是这个链接,我用link表示。因为现在还没有系统介绍网页控件的操作和断言,所以我们只能在终端打印出来链接信息来证明已经找到了该链接。不过大家可以看一下一个网页控件可以有多少操作:
getText()方法可以打印出一个链接上的文本内容,所以我们用这个方法在终端打印出来:
结果如下:
没问题吧?如果没找到肯定打印不出来这句话对不对?其实不光打不出来,找不到还会抛异常,selenium就是这么个玩意儿。
你看,我们随便写了个id,其实压根不存在。错误妥妥地爆出来。你可以用try…catch…捕获错误信息,但我们总不希望测试的时候老有异常抛出来吧?以后讲控件操作时会告诉大家怎么处理。控件的操作我们会在讲完定位器后挨个扫荡一遍,暂时咱们用到哪个就先提一句。以上就是一个使用id查找链接的小例子,大家可以用别的网站再做做实验。
有人说,那如果在同一个网页上有两个元素拥有同一个id怎么办呢?比如它们都等于hyperlink,程序怎么知道该选哪个呢?完全没必要顾虑,因为在同一个网页上不可能有两个元素拥有同一个id,有些功能因为id冲突会在某些情况下失效!这是web应用前端开发时的规定,你可以去任何正规大型网站上看看,同一个网页上绝不会出现同一个id。所以,如果一个元素有id,那我们最好先用id来定位,因为它可以唯一标识当前网页上的某一个元素。当然,如果是同一个网站中的不同网页,id可以重复。
看来放到不同网页就不会引起冲突,我们可不可以这么想:网页之间是彼此独立的,定位控件时都是根据当前网页来执行的?为了证明这个观点,请看下面这个例子,我们先打印出来链接文本,然后导到百度,然后再尝试打印链接文本:
执行一下肯定会报错,因为跳转到百度后原先网页上的链接对象就不存在了!同样的System.out.println(link.getText())操作,只不过中间隔了一个跳转百度并等3秒钟就报错了。所以我们可以得出这个结论了:所有的控件定位都是针对当前网页来说的,当从一个网页跳转到另一个网页的时候,所有之前存在的都会失效。这不光适用于id,还适合于其它定位器。这也间接证明了不同网页元素可以用同一个id,因为同一时间selenium只能处理一个网页。至于网页之间为什么是彼此独立的,这个涉及http协议以及web应用程序相关知识,有兴趣的可以上网查查资料。咱们是做测试的,其实更需要知识的广度。如果以后有时间我也会写相关的文章的。
如果id不存在还能用id来定位这个链接吗?当然不能,不存在怎么能使用id呢?那就得从另外七种定位器中选择了。
这篇文章的源代码是SeleniumId这个项目,下篇介绍和Name相关的三种定位器使用方法。
本篇知识点及注意事项:
1.所有的控件定位都是针对当前网页来说的,当从一个网页跳转到另一个网页的时候,所有之前存在的都会失效。