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