Selenium作为著名的开源WEB UI自动化工具,在很多公司的很多项目都得了实践。不过关于Ruby下的实现的文章很少。由于我的工作中是使用Ruby来实现Selenium的UI自动化的,所以我就想以一个个实际的例子来给大家介绍下Selenium的使用方法。
第一个系列的主题是如何用Selenium实现京东抢券的脚本。第一步是京东登录的。下面我就按步骤来进行实例分析。
1. 需要使用的gem:
require 'selenium-webdriver'
2. 启动浏览器:
这里主要是使用的是Chrome和Firefox两种主流的浏览器。Firefox是不需要单独的Webdriver的,但是Chrome需要下载专门的Webdriver。
1 $dr = Selenium::WebDriver.for :chrome
2 $dr = Selenium::WebDriver.for :firefox
3. 登录京东:
1 begin
2 $dr.get("http://www.jd.com/")
3
4 login_link = $dr.find_element(:class, "link-login")
5 wait_element_display(login_link)
6 login_link.click
7
8 login_tab_link = $dr.find_element(:xpath, "//a[.='账户登录']")
9 wait_element_display(login_tab_link)
10 login_tab_link.click
11
12 username = $dr.find_element(:xpath, "//input[@id='loginname']")
13 username.send_keys "jdaccount"
14 pw = $dr.find_element(:xpath, "//input[@id='nloginpwd']")
15 pw.send_keys "password"
16
17 login_button = $dr.find_element(:id, "loginsubmit")
18 wait_element_display_then_click(login_button)
19 rescue => exception
20 puts exception
21 ensure
22 $dr.close
23 end
上面的代码中有几个需要注意的点:
- $dr.get("http://www.jd.com/") 这是访问一个URL的方法, get 是 Selenium::WebDriver::Driver 类的方法。
- find_element 是用了定位元素的方法,返回值是一个 Selenium::WebDriver::Element 类的对象。这是操作界面的元素的第一步,也就是拿到想要操作的元素。
- 定位元素的方法有很多,常见的有 id , link_text , xpath , class 。其中适应性最广的是xpath。关于xpath的使用我会在另外的文章中介绍。
- click 是 Selenium::WebDriver::Element 类的方法,模拟的是鼠标的单击操作。
- send_keys 模拟的是键盘输入的操作。
- $dr.close 是关闭浏览器,无论结果如何,都需要在脚本最后关闭浏览器。
注意上面的代码中我定义了两个方法 wait_element_display_then_click 和 wait_element_display 。 这是由于等待一个元素出现和点击元素是非常常见的操作。由于页面的加载时间不确定,所以需要设置等待。在这里我推荐大家使用Selenium中的显示等待。 方法定义如下:
1 def wait_element_display(element)
2 wait = Selenium::WebDriver::Wait.new()
3 wait.until { element.displayed? }
4 end
5
6 def wait_element_display_then_click(element)
7 wait_element_display(element)
8 element.click
9 end
Selenium中有一个重要的class叫做 Selenium::WebDriver::Wait ,用来处理各种等待,在初始化对象的过程中可以设置如下的参数:
:timeout (Numeric) — default: 5 — Seconds to wait before timing out. :interval (Numeric) — default: 0.2 — Seconds to sleep between polls. :message (String) — Exception mesage if timed out. :ignore (Array, Exception) — Exceptions to ignore while polling (default: Error::NoSuchElementError)
在方法中,我设置等待直到元素显示为止。
element.displayed? 是 Selenium::WebDriver::Element 类一个很常用的method, 用了判断元素是否显示在界面上。测试中很多场景都会用到这个判断。
判断显示和点击可以再次封装为一个方法,目的是避免点击操作时元素并未显示导致失败。
最后是登录的完整代码
#encoding=UTF-8
require 'selenium-webdriver'
require "pry"
require "yaml"
def wait_element_display(element)
wait = Selenium::WebDriver::Wait.new()
wait.until { element.displayed? }
end
def wait_element_display_then_click(element)
wait_element_display(element)
element.click
end
$dr = Selenium::WebDriver.for :chrome
begin
$dr.get("http://www.jd.com/")
login_link = $dr.find_element(:class, "link-login")
wait_element_display(login_link)
login_link.click
login_tab_link = $dr.find_element(:xpath, "//a[.='账户登录']")
wait_element_display(login_tab_link)
login_tab_link.click
username = $dr.find_element(:xpath, "//input[@id='loginname']")
username.send_keys "jdaccount"
pw = $dr.find_element(:xpath, "//input[@id='nloginpwd']")
pw.send_keys "password"
login_button = $dr.find_element(:id, "loginsubmit")
wait_element_display_then_click(login_button)
rescue => exception
puts exception
ensure
$dr.close
end