├── 10 ├── level_locate.rb ├── level_locate.py ├── level_locate.watir.rb ├── LevelLocate.java └── level_locate.html ├── 11 ├── operate_element.watir.rb ├── operate_element.rb ├── operate_element.py ├── OperateElement.java └── operate_element.html ├── 12 ├── send_keys.rb ├── send_keys.py ├── send_keys.html ├── SendKeys.java ├── send_keys.md ├── send_keys.py.md └── send_keys.java.md ├── 13 ├── ButtonGroup.java ├── button_group.rb ├── button_group.py ├── button_group.html ├── button_group.md ├── button_group.py.md └── button_group.java.md ├── 14 ├── ButtonDropdown.java ├── button_dropdown.rb ├── button_dropdown.py ├── button_dropdown.html ├── button_dropdown.md └── button_dropdown.py.md ├── 15 ├── Navs.java ├── navs.rb ├── navs.py ├── navs.html ├── navs.md ├── navs.py.md └── navs.java.md ├── 16 ├── breadcrumb.rb ├── breadcrumb.py ├── breadcrumb.html ├── Breadcrumb.java ├── breadcrumb.md ├── breadcrumb.py.md └── breadcrumb.java.md ├── 17 ├── pagination.rb ├── pagination.py ├── Pagination.java ├── pagination.html ├── pagination.md └── pagination.py.md ├── 18 ├── Modal.java ├── modal.rb ├── modal.py └── modal.html ├── 19 ├── .DS_Store ├── attribute.watir.rb ├── attribute.rb ├── input.rb ├── attribute.py ├── input.py ├── input.html ├── attribute.html ├── Attribute.java ├── attribute.md ├── attribute.py.md └── attribute.java.md ├── 20 ├── css.rb ├── css.py ├── Css.java ├── css.html ├── css.md ├── css.py.md └── css.java.md ├── 21 ├── status.watir.rb ├── status.rb ├── status.py ├── status.html ├── Status.java ├── status.md └── status.py.md ├── 22 ├── Form.java ├── form.watir.rb ├── form.rb ├── form.py ├── form.html └── form.md ├── 23 ├── Js.java ├── .DS_Store ├── js.rb ├── js.py ├── js.html ├── js.md ├── js.py.md └── js.java.md ├── 24 ├── AlertExample.java ├── alert.rb ├── alert.watir.rb ├── alert.py ├── alert.html ├── alert.md ├── alert.py.md └── alert.java.md ├── 25 ├── WaitExample.java ├── wait.watir.rb ├── wait.rb ├── wait.py ├── wait.html ├── wait.md └── wait.py.md ├── 26 ├── Frame.java ├── frame.watir.rb ├── inner.html ├── frame.rb ├── frame.py └── frame.html ├── 27 ├── action.md ├── action.java.md └── action.py.md ├── 28 ├── upload_file.watir.rb ├── upload_file.rb ├── upload_file.py ├── upload_file.html ├── Upload.java ├── upload_file.md ├── upload_file.py.md └── upload_file.java.md ├── 29 ├── download.py.md ├── download.md └── download.java.md ├── 30 ├── timeout.py.md ├── timeout.java.md └── timeout.md ├── 32 ├── cookie.watir.rb ├── cookie.rb ├── cookie.py ├── CookieExample.java ├── cookie.py.md ├── cookie.md └── cookie.java.md ├── 33 ├── sub_window.html ├── switch_window.html ├── switch_window.py └── switch_window.py.md ├── 34 └── expected_conditions.py ├── 35 ├── select.py ├── select.html └── select.py.md ├── 00 ├── init.md ├── init.java.md └── init.py.md ├── .DS_Store ├── README.md.bak ├── 01 ├── start_browser.rb ├── start_browser.watir.rb ├── start_browser.py ├── StartBrowser.java ├── start_browser.py.md ├── start_browser.md └── start_browser.java.md ├── to_pdf ├── about.ppt ├── 乙醇webdriver实用指南python版本.pdf └── to_pdf.rb ├── 02 ├── close_browser.watir.rb ├── close_browser.rb ├── close_browser.py ├── CloseBrowser.java ├── close_browser.md ├── close_browser.py.md └── close_browser.java.md ├── 04 ├── resize_browser.watir.rb ├── resize_browser.rb ├── resize_browser.py ├── CloseBrowser.java ├── resize_browser.md ├── resize_browser.py.md └── resize_browser.java.md ├── 05 ├── get.rb ├── get.watir.rb ├── get.py ├── get.py.md ├── get.md ├── Get.java └── get.java.md ├── 03 ├── maximize_browser.watir.rb ├── maximize_browser.rb ├── maximize_browser.py ├── maximize_browser.md ├── Maximize.java ├── maximize_browser.py.md └── maximize_browser.java.md ├── 06 ├── title_and_url.watir.rb ├── title_and_url.rb ├── title_and_url.py ├── TitleAndUrl.java ├── title_and_url.md ├── title_and_url.py.md └── title_and_url.java.md ├── 07 ├── forword_and_back.watir.rb ├── forword_and_back.rb ├── forword_and_back.py ├── forword_and_back.md ├── forword_and_back.py.md ├── ForwardAndBack.java └── forword_and_back.java.md ├── .gitignore ├── 09 ├── find_elements.rb ├── find_elements.watir.rb ├── find_elements.py ├── checkbox.html └── SimpleLocate.java └── 08 ├── simple_locate.watir.rb ├── simple_locate.rb ├── simple_locate.py ├── form.html └── SimpleLocate.java /00/init.md: -------------------------------------------------------------------------------- 1 | # 安装ruby及webdriver的开发环境 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /00/init.java.md: -------------------------------------------------------------------------------- 1 | # 安装java及webdriver的开发环境 2 | 3 | TODO 4 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/.DS_Store -------------------------------------------------------------------------------- /23/Js.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/23/Js.java -------------------------------------------------------------------------------- /15/Navs.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/15/Navs.java -------------------------------------------------------------------------------- /19/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/19/.DS_Store -------------------------------------------------------------------------------- /22/Form.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/22/Form.java -------------------------------------------------------------------------------- /23/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/23/.DS_Store -------------------------------------------------------------------------------- /18/Modal.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/18/Modal.java -------------------------------------------------------------------------------- /26/Frame.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/26/Frame.java -------------------------------------------------------------------------------- /README.md.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/README.md.bak -------------------------------------------------------------------------------- /01/start_browser.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | -------------------------------------------------------------------------------- /01/start_browser.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new(:chrome) 4 | -------------------------------------------------------------------------------- /to_pdf/about.ppt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/to_pdf/about.ppt -------------------------------------------------------------------------------- /13/ButtonGroup.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/13/ButtonGroup.java -------------------------------------------------------------------------------- /24/AlertExample.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/24/AlertExample.java -------------------------------------------------------------------------------- /25/WaitExample.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/25/WaitExample.java -------------------------------------------------------------------------------- /14/ButtonDropdown.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/14/ButtonDropdown.java -------------------------------------------------------------------------------- /01/start_browser.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | 3 | #dr = webdriver.Chrome() 4 | dr = webdriver.Firefox() 5 | -------------------------------------------------------------------------------- /to_pdf/乙醇webdriver实用指南python版本.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/easonhan007/webdriver_guide/HEAD/to_pdf/乙醇webdriver实用指南python版本.pdf -------------------------------------------------------------------------------- /33/sub_window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sub Window 4 | 5 | 6 | 7 |

This is sub window

8 | 9 | -------------------------------------------------------------------------------- /02/close_browser.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new :chrome 4 | sleep 2 5 | puts 'browser will be closed' 6 | b.close 7 | puts 'browser is closed' 8 | -------------------------------------------------------------------------------- /04/resize_browser.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new :chrome 4 | 5 | b.window.resize_to(320, 480) 6 | b.goto '3g.qq.com' 7 | 8 | sleep 3 9 | b.close 10 | -------------------------------------------------------------------------------- /02/close_browser.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | sleep 2 5 | puts 'browser will be closed' 6 | dr.quit() # or dr.close() 7 | puts 'browser is closed' 8 | -------------------------------------------------------------------------------- /05/get.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | url = 'http://www.baidu.com' 5 | puts "now access #{url}" 6 | dr.get url 7 | sleep 5 8 | 9 | dr.quit 10 | -------------------------------------------------------------------------------- /05/get.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new :chrome 4 | url = 'http://www.baidu.com' 5 | puts "now access #{url}" 6 | b.goto url 7 | 8 | sleep 5 9 | 10 | b.close 11 | -------------------------------------------------------------------------------- /02/close_browser.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | import time 3 | 4 | dr = webdriver.Chrome() 5 | time.sleep(2) 6 | print 'browser will be closed' 7 | dr.quit() # or dr.close() 8 | print 'browser is closed' 9 | -------------------------------------------------------------------------------- /04/resize_browser.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | 5 | dr.manage.window.resize_to(320,480) 6 | dr.get 'http://www.3g.qq.com' 7 | 8 | sleep 5 9 | dr.quit 10 | 11 | -------------------------------------------------------------------------------- /03/maximize_browser.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new :chrome 4 | sleep 2 5 | puts 'maximize browser' 6 | b.window.maximize 7 | sleep 2 8 | puts 'close browser' 9 | b.close 10 | 11 | -------------------------------------------------------------------------------- /04/resize_browser.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | import time 3 | 4 | dr = webdriver.Chrome() 5 | 6 | dr.set_window_size(240, 320) 7 | dr.get('http://www.3g.qq.com') 8 | 9 | time.sleep(5) 10 | dr.quit() 11 | -------------------------------------------------------------------------------- /05/get.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | import time 3 | 4 | dr = webdriver.Chrome() 5 | 6 | url = 'http://www.baidu.com' 7 | print "now access %s" %(url) 8 | dr.get(url) 9 | time.sleep(3) 10 | 11 | dr.quit() 12 | -------------------------------------------------------------------------------- /03/maximize_browser.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | sleep 2 5 | puts 'maximize browser' 6 | dr.manage.window.maximize() 7 | sleep 2 8 | puts 'close browser' 9 | dr.quit 10 | 11 | -------------------------------------------------------------------------------- /03/maximize_browser.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | import time 3 | 4 | dr = webdriver.Chrome() 5 | time.sleep(2) 6 | print 'maximize browser' 7 | 8 | dr.maximize_window() 9 | 10 | time.sleep(2) 11 | print 'close browser' 12 | 13 | dr.quit() 14 | 15 | -------------------------------------------------------------------------------- /33/switch_window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Switch Window 4 | 5 | 6 | 7 |

This is main window

8 | Click to open sub window 9 | 10 | -------------------------------------------------------------------------------- /01/StartBrowser.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.WebDriver; 2 | import org.openqa.selenium.chrome.ChromeDriver; 3 | 4 | 5 | public class StartBrowser { 6 | 7 | public static void main(String[] args) { 8 | WebDriver dr = new ChromeDriver(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /01/start_browser.py.md: -------------------------------------------------------------------------------- 1 | 启动浏览器 2 | ========== 3 | 4 | 场景 5 | ---- 6 | 在使用webdriver进行测试时启动浏览器无疑是必须的前置工作。 7 | 8 | 代码 9 | ---- 10 | ```python 11 | from selenium import webdriver 12 | 13 | dr = webdriver.Chrome() 14 | 15 | ``` 16 | 17 | 讨论 18 | ---- 19 | 自己试着弄清楚如何启动IE和Firefox 20 | 21 | 22 | -------------------------------------------------------------------------------- /06/title_and_url.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new :chrome 4 | url = 'http://www.baidu.com' 5 | puts "now access #{url}" 6 | b.goto url 7 | 8 | puts "title of current page is #{b.title}" 9 | puts "url of current page is #{b.url}" 10 | sleep 1 11 | 12 | b.close 13 | -------------------------------------------------------------------------------- /28/upload_file.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'upload_file.html')) 6 | 7 | b.goto file_path 8 | 9 | b.file_field.set('./upload_file.md') 10 | 11 | sleep(2) 12 | b.quit() 13 | 14 | -------------------------------------------------------------------------------- /06/title_and_url.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | url = 'http://www.baidu.com' 5 | puts "now access #{url}" 6 | dr.get url 7 | 8 | puts "title of current page is #{dr.title}" 9 | puts "url of current page is #{dr.current_url}" 10 | sleep 1 11 | 12 | dr.quit 13 | -------------------------------------------------------------------------------- /28/upload_file.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'upload_file.html')) 6 | dr.get file_path 7 | 8 | dr.find_element(name: 'file').send_keys('./upload_file.md') 9 | 10 | sleep(2) 11 | dr.quit() 12 | 13 | -------------------------------------------------------------------------------- /32/cookie.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | url = 'www.baidu.com' 6 | b.goto url 7 | 8 | puts b.cookies.to_hash 9 | dr.cookies.clear 10 | dr.cookies.add('BAIDUID', 'xxxxxx') 11 | dr.cookies.add('BDUSS', 'xxxxxx') 12 | 13 | b.goto url 14 | 15 | sleep(3) 16 | b.close() 17 | 18 | -------------------------------------------------------------------------------- /01/start_browser.md: -------------------------------------------------------------------------------- 1 | 启动浏览器 2 | ========== 3 | 4 | 场景 5 | ---- 6 | 在使用webdriver进行测试时启动浏览器无疑是必须的前置工作。 7 | 8 | 代码 9 | ---- 10 | ```ruby 11 | require 'selenium-webdriver' 12 | # chrome 13 | dr = Selenium::WebDriver.for :chrome 14 | # firefox 15 | dr = Selenium::WebDriver.for :ff 16 | # ie 17 | dr = Selenium::WebDriver.for :ie 18 | ``` 19 | 20 | 21 | -------------------------------------------------------------------------------- /25/wait.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'wait.html')) 6 | 7 | b.goto file_path 8 | 9 | # 点击按钮 10 | b.button(:id, 'btn').when_present.click() 11 | 12 | b.span(:class,'label').wait_until_present 13 | 14 | sleep(2) 15 | b.close() 16 | 17 | -------------------------------------------------------------------------------- /20/css.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'css.html')) 6 | dr.get file_path 7 | 8 | link = dr.find_element(id: 'tooltip') 9 | puts link.css_value(:color) 10 | 11 | puts dr.find_element(:tag_name, 'h3').css_value('font') 12 | 13 | dr.quit() 14 | 15 | -------------------------------------------------------------------------------- /24/alert.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'alert.html')) 6 | dr.get file_path 7 | 8 | # 点击链接弹出alert 9 | dr.find_element(:id, 'tooltip').click() 10 | 11 | alert = dr.switch_to.alert 12 | alert.accept() 13 | 14 | sleep(1) 15 | dr.quit() 16 | 17 | -------------------------------------------------------------------------------- /24/alert.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'alert.html')) 6 | 7 | b.goto file_path 8 | 9 | # 点击链接弹出alert 10 | b.link(:id, 'tooltip').click() 11 | 12 | alert = b.alert 13 | alert.ok() # or use b.close() to cancel alert 14 | 15 | sleep(1) 16 | b.quit() 17 | 18 | -------------------------------------------------------------------------------- /04/CloseBrowser.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.WebDriver; 2 | import org.openqa.selenium.chrome.ChromeDriver; 3 | 4 | 5 | public class ResizeBrowser { 6 | 7 | public static void main(String[] args) { 8 | WebDriver dr = new ChromeDriver(); 9 | dr.manage().window().setSize(new Dimension(240, 320)); 10 | dr.get("http://www.3g.qq.com/"); 11 | dr.quit(); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /02/CloseBrowser.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.WebDriver; 2 | import org.openqa.selenium.chrome.ChromeDriver; 3 | 4 | 5 | public class CloseBrowser { 6 | 7 | public static void main(String[] args) { 8 | WebDriver dr = new ChromeDriver(); 9 | System.out.println("browser will be closed"); 10 | 11 | dr.quit(); 12 | System.out.println("browser is closed"); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /30/timeout.py.md: -------------------------------------------------------------------------------- 1 | 超时设置 2 | ========= 3 | 4 | 场景 5 | ---- 6 | webdriver中可以设置很多的超时时间 7 | 8 | * implicit_wait。识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出异常 9 | 10 | 代码 11 | ---- 12 | 13 | ``` 14 | ff = webdriver.Firefox() 15 | ff.implicitly_wait(10) # seconds 16 | ff.get("http://somedomain/url_that_delays_loading") 17 | myDynamicElement = ff.find_element_by_id("myDynamicElement") 18 | 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /19/attribute.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'attribute.html')) 6 | 7 | b.goto file_path 8 | 9 | link = b.link(id: 'tooltip') 10 | 11 | # 获得tooltip的内容 12 | puts link.attribute_value('data-original-title') 13 | 14 | # 获取该链接的text 15 | puts link.text() 16 | 17 | b.close 18 | -------------------------------------------------------------------------------- /32/cookie.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | url = 'http://www.baidu.com' 6 | dr.get url 7 | 8 | p dr.manage.all_cookies 9 | dr.manage.delete_all_cookies 10 | dr.manage.add_cookie(name: 'BAIDUID', value: 'xxxxxx') 11 | dr.manage.add_cookie(name: 'BDUSS', value: 'xxxxxx') 12 | 13 | dr.get url 14 | 15 | sleep(3) 16 | dr.quit() 17 | 18 | -------------------------------------------------------------------------------- /19/attribute.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'attribute.html')) 6 | dr.get file_path 7 | 8 | link = dr.find_element(id: 'tooltip') 9 | 10 | # 获得tooltip的内容 11 | puts link.attribute('data-original-title') 12 | 13 | # 获取该链接的text 14 | puts link.text() 15 | 16 | dr.quit() 17 | 18 | -------------------------------------------------------------------------------- /25/wait.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'wait.html')) 6 | dr.get file_path 7 | 8 | # 点击按钮 9 | dr.find_element(:id, 'btn').click() 10 | 11 | wait = Selenium::WebDriver::Wait.new() 12 | wait.until { dr.find_element(class: 'label').displayed? } 13 | 14 | sleep(2) 15 | dr.quit() 16 | 17 | -------------------------------------------------------------------------------- /01/start_browser.java.md: -------------------------------------------------------------------------------- 1 | 启动浏览器 2 | ========== 3 | 4 | 场景 5 | ---- 6 | 在使用webdriver进行测试时启动浏览器无疑是必须的前置工作。 7 | 8 | 代码 9 | ---- 10 | ``` 11 | import org.openqa.selenium.WebDriver; 12 | import org.openqa.selenium.chrome.ChromeDriver; 13 | 14 | 15 | public class StartBrowser { 16 | 17 | public static void main(String[] args) { 18 | WebDriver dr = new ChromeDriver(); 19 | } 20 | 21 | } 22 | ``` 23 | 24 | 25 | -------------------------------------------------------------------------------- /05/get.py.md: -------------------------------------------------------------------------------- 1 | 访问链接 2 | ======== 3 | 4 | 情景 5 | ---- 6 | web UI测试里最简单也是最基本的事情就是访问1个链接了。 7 | 8 | 在python的webdrive中,访问url时应该使用get方法。 9 | 10 | 代码 11 | ---- 12 | 13 | ```python 14 | from selenium import webdriver 15 | import time 16 | 17 | dr = webdriver.Chrome() 18 | 19 | url = 'http://www.baidu.com' 20 | print "now access %s" %(url) 21 | dr.get(url) 22 | time.sleep(3) 23 | 24 | dr.quit() 25 | ``` 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /06/title_and_url.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | url = 'http://www.baidu.com' 9 | dr.get(url) 10 | 11 | print "title of current page is %s" %(dr.title) 12 | print "url of current page is %s" %(dr.current_url) 13 | 14 | sleep(1) 15 | 16 | dr.quit() 17 | -------------------------------------------------------------------------------- /15/navs.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'navs.html')) 6 | dr.get file_path 7 | 8 | # 方法1:层级定位,先定位ul再定位li 9 | dr.find_element(:class, 'nav').find_element(:link_text, 'About').click() 10 | sleep(1) 11 | 12 | # 方法2: 直接定位link 13 | dr.find_element(:link_text, 'Home').click() 14 | 15 | dr.quit() 16 | 17 | -------------------------------------------------------------------------------- /13/button_group.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'button_group.html')) 6 | dr.get file_path 7 | 8 | # 定位text是second的按钮 9 | second_btn = dr.find_element(:class, 'btn-group').find_elements(:class, 'btn').detect {|btn| btn.text == 'second'} 10 | second_btn.click() 11 | sleep(2) 12 | 13 | dr.quit() 14 | 15 | -------------------------------------------------------------------------------- /26/frame.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'frame.html')) 6 | 7 | b.goto file_path 8 | 9 | 10 | # 往f2中的百度关键字文本框中输入内容 11 | b.frame(:id, 'f1').frame(:id, 'f2').text_field(id: 'kw').set 'watir-webdriver' 12 | 13 | # 再到f1 14 | b.frame(:id, 'f1').link(text: 'click').click 15 | 16 | sleep(2) 17 | b.quit() 18 | 19 | -------------------------------------------------------------------------------- /23/js.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'js.html')) 6 | dr.get file_path 7 | 8 | # 在页面上直接执行js 9 | dr.execute_script('$("#tooltip").fadeOut();') 10 | sleep(1) 11 | 12 | # 在已经定位的元素上执行js 13 | button = dr.find_element(class: 'btn') 14 | dr.execute_script('$(arguments[0]).fadeOut()', button) 15 | sleep(1) 16 | 17 | dr.quit() 18 | 19 | -------------------------------------------------------------------------------- /07/forword_and_back.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new :chrome 4 | first_url = 'http://www.baidu.com' 5 | puts "now access #{first_url}" 6 | b.goto(first_url) 7 | sleep 1 8 | second_url = 'http://www.news.baidu.com' 9 | puts "now access #{second_url}" 10 | b.goto(second_url) 11 | sleep 1 12 | 13 | puts "back to #{first_url}" 14 | b.back() 15 | sleep 1 16 | puts "forward to #{second_url}" 17 | b.forward() 18 | sleep 1 19 | b.close 20 | -------------------------------------------------------------------------------- /28/upload_file.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from time import sleep 5 | import os 6 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 7 | 8 | dr = webdriver.Chrome() 9 | file_path = 'file:///' + os.path.abspath('upload_file.html') 10 | 11 | dr.get(file_path) 12 | 13 | dr.find_element_by_name('file').send_keys('./upload_file.md') 14 | 15 | sleep(2) 16 | dr.quit() 17 | 18 | -------------------------------------------------------------------------------- /19/input.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'input.html')) 6 | dr.get file_path 7 | 8 | text_field = dr.find_element(class: 'well').find_element(:css, 'input[type=text]') 9 | puts text_field.attribute('id') 10 | puts text_field.attribute('name') 11 | puts text_field.attribute('class') 12 | puts text_field.attribute('value') 13 | 14 | dr.quit() 15 | 16 | -------------------------------------------------------------------------------- /07/forword_and_back.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | first_url = 'http://www.baidu.com' 5 | puts "now access #{first_url}" 6 | dr.get(first_url) 7 | sleep 1 8 | second_url = 'http://www.news.baidu.com' 9 | puts "now access #{second_url}" 10 | dr.get(second_url) 11 | sleep 1 12 | 13 | puts "back to #{first_url}" 14 | dr.navigate.back() 15 | sleep 1 16 | puts "forward to #{second_url}" 17 | dr.navigate.forward() 18 | sleep 1 19 | dr.quit() 20 | -------------------------------------------------------------------------------- /11/operate_element.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'operate_element.html')) 6 | 7 | b.goto file_path 8 | #click 9 | b.link(:text, 'Link1').click 10 | sleep(1) 11 | b.link(:text, 'Link1').click 12 | 13 | #set 14 | element = b.text_field(:name, 'q') 15 | element.set 'waitr-webdriver' 16 | sleep(1) 17 | 18 | #clear 19 | element.clear 20 | 21 | sleep(2) 22 | b.close 23 | 24 | -------------------------------------------------------------------------------- /20/css.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('css.html') 9 | 10 | dr.get(file_path) 11 | 12 | link = dr.find_element_by_id('tooltip') 13 | print link.value_of_css_property('color') 14 | 15 | print dr.find_element_by_tag_name('h3').value_of_css_property('font') 16 | 17 | dr.quit() 18 | 19 | -------------------------------------------------------------------------------- /03/maximize_browser.md: -------------------------------------------------------------------------------- 1 | 浏览器最大化 2 | ============ 3 | 4 | 场景 5 | ---- 6 | 当我们在测试中使用一些基于图像和坐标的辅助测试工具时,我们就会需要使浏览器在每次测试时保存最大化,以便在同一分辨率下进行图像比对和坐标点选。 7 | 8 | 举例来说,如果在webdriver测试中使用了sikuli来对flash插件进行操作的话,把浏览器最大化无疑是一个比较简单的保证分辨率统一的解决方案。 9 | 10 | 代码 11 | ---- 12 | ``` 13 | require 'selenium-webdriver' 14 | 15 | dr = Selenium::WebDriver.for :chrome 16 | sleep 2 17 | puts 'maximize browser' 18 | dr.manage.window.maximize() 19 | sleep 2 20 | puts 'close browser' 21 | dr.quit 22 | ``` 23 | 24 | 25 | -------------------------------------------------------------------------------- /03/Maximize.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.WebDriver; 2 | import org.openqa.selenium.chrome.ChromeDriver; 3 | 4 | 5 | public class Maximize { 6 | 7 | public static void main(String[] args) throws InterruptedException { 8 | WebDriver dr = new ChromeDriver(); 9 | Thread.sleep(2000); 10 | 11 | System.out.println("maximize browser"); 12 | dr.manage().window().maximize(); 13 | Thread.sleep(2000); 14 | 15 | System.out.println("browser will be close"); 16 | dr.quit(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /26/inner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | inner 5 | 6 | 7 | 8 |
9 |
10 |

inner

11 | 12 | click 13 |
14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /05/get.md: -------------------------------------------------------------------------------- 1 | 访问链接 2 | ======== 3 | 4 | 情景 5 | ---- 6 | web UI测试里最简单也是最基本的事情就是访问1个链接了。 7 | 8 | webdriver的api里有2种访问url的方式,分别是get和navigate.to方法。一般情况下建议使用get,因为其字母比较少,不太容易出错。 9 | 10 | 代码 11 | ---- 12 | 13 | ``` 14 | require 'selenium-webdriver' 15 | 16 | dr = Selenium::WebDriver.for :chrome 17 | url = 'http://www.baidu.com' 18 | puts "now access #{url}" 19 | dr.get url 20 | sleep 5 21 | 22 | dr.quit 23 | ``` 24 | 25 | 讨论 26 | ---- 27 | navigate方法实际上会产生1个Navigator对象,其封装了与导航相关的一些方法,比如前进后退等。 28 | 29 | 30 | -------------------------------------------------------------------------------- /19/attribute.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('attribute.html') 9 | 10 | dr.get(file_path) 11 | 12 | link = dr.find_element_by_id('tooltip') 13 | 14 | sleep(1) 15 | # 获得tooltip的内容 16 | print link.get_attribute('data-original-title') 17 | 18 | # 获取该链接的text 19 | print link.text 20 | 21 | dr.quit() 22 | 23 | -------------------------------------------------------------------------------- /24/alert.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('alert.html') 9 | dr.get(file_path) 10 | 11 | # 点击链接弹出alert 12 | dr.find_element_by_id('tooltip').click() 13 | 14 | try: 15 | alert = dr.switch_to_alert() 16 | alert.accept() 17 | except: 18 | print 'no alerts display' 19 | 20 | sleep(1) 21 | dr.quit() 22 | 23 | -------------------------------------------------------------------------------- /05/Get.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.WebDriver; 2 | import org.openqa.selenium.chrome.ChromeDriver; 3 | 4 | 5 | public class Get { 6 | 7 | public static void main(String[] args) throws InterruptedException { 8 | WebDriver dr = new ChromeDriver(); 9 | Thread.sleep(2000); 10 | 11 | String url = "http://www.baidu.com"; 12 | System.out.printf("now accesss %s \n", url); 13 | dr.get(url); 14 | Thread.sleep(2000); 15 | 16 | System.out.println("browser will be close"); 17 | dr.quit(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /03/maximize_browser.py.md: -------------------------------------------------------------------------------- 1 | 浏览器最大化 2 | ============ 3 | 4 | 场景 5 | ---- 6 | 当我们在测试中使用一些基于图像和坐标的辅助测试工具时,我们就会需要使浏览器在每次测试时保存最大化,以便在同一分辨率下进行图像比对和坐标点选。 7 | 8 | 举例来说,如果在webdriver测试中使用了sikuli来对flash插件进行操作的话,把浏览器最大化无疑是一个比较简单的保证分辨率统一的解决方案。 9 | 10 | 代码 11 | ---- 12 | ```python 13 | from selenium import webdriver 14 | import time 15 | 16 | dr = webdriver.Chrome() 17 | time.sleep(2) 18 | print 'maximize browser' 19 | 20 | dr.maximize_window() 21 | 22 | time.sleep(2) 23 | print 'close browser' 24 | 25 | dr.quit() 26 | 27 | ``` 28 | 29 | 30 | -------------------------------------------------------------------------------- /11/operate_element.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'operate_element.html')) 6 | 7 | dr.get file_path 8 | #click 9 | dr.find_element(:link_text, 'Link1').click 10 | sleep(1) 11 | dr.find_element(:link_text, 'Link1').click 12 | 13 | #send_keys 14 | element = dr.find_element(:name, 'q') 15 | element.send_keys('something') 16 | sleep(1) 17 | 18 | #clear 19 | element.clear() 20 | 21 | sleep(2) 22 | dr.quit 23 | 24 | -------------------------------------------------------------------------------- /02/close_browser.md: -------------------------------------------------------------------------------- 1 | 关闭浏览器 2 | ========== 3 | 4 | 场景 5 | ---- 6 | 在脚本运行完毕或者测试代码结束的时候关闭浏览器是非常自然的事情,就像在吃完饭后就把餐桌收拾干净一样。 7 | 8 | 关闭浏览器有两种方式: 9 | 10 | * close方法 11 | 12 | * quit方法 13 | 14 | close方法关闭当前的浏览器窗口,quit方法不仅关闭窗口,还会彻底的退出webdriver,释放与driver server之间的连接。所以简单来说quit是更加彻底的close,quit会更好的释放资源,适合强迫症和完美主义者。 15 | 16 | 代码 17 | ---- 18 | ``` 19 | require 'selenium-webdriver' 20 | 21 | dr = Selenium::WebDriver.for :chrome 22 | sleep 2 23 | puts 'browser will be closed' 24 | dr.quit() # or dr.close() 25 | puts 'browser is closed' 26 | ``` 27 | -------------------------------------------------------------------------------- /16/breadcrumb.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'breadcrumb.html')) 6 | dr.get file_path 7 | 8 | # 获得其父层级 9 | anstors = dr.find_element(:class, 'breadcrumb').find_elements(:tag_name, 'a').map { |link| link.text } 10 | p anstors 11 | sleep(1) 12 | 13 | # 获取当前层级 14 | # 由于页面上可能有很多class为active的元素 15 | # 所以使用层级定位最为保险 16 | puts dr.find_element(:class, 'breadcrumb').find_element(:class, 'active').text 17 | 18 | dr.quit() 19 | 20 | -------------------------------------------------------------------------------- /23/js.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('js.html') 9 | dr.get(file_path) 10 | 11 | # 在页面上直接执行js 12 | dr.execute_script('$("#tooltip").fadeOut();') 13 | sleep(1) 14 | 15 | # 在已经定位的元素上执行js 16 | button = dr.find_element_by_class_name('btn') 17 | dr.execute_script('$(arguments[0]).fadeOut()', button) 18 | sleep(1) 19 | 20 | dr.quit() 21 | 22 | -------------------------------------------------------------------------------- /16/breadcrumb.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | import time 4 | import os 5 | 6 | dr = webdriver.Chrome() 7 | file_path = 'file:///' + os.path.abspath('breadcrumb.html') 8 | dr.get(file_path) 9 | 10 | # 获得其父层级 11 | for link in dr.find_element_by_class_name('breadcrumb').find_elements_by_tag_name('a'): 12 | print link.text 13 | 14 | # 获取当前层级 15 | # 由于页面上可能有很多class为active的元素 16 | # 所以使用层级定位最为保险 17 | print dr.find_element_by_class_name('breadcrumb').find_element_by_class_name('active').text 18 | 19 | dr.quit() 20 | 21 | -------------------------------------------------------------------------------- /02/close_browser.py.md: -------------------------------------------------------------------------------- 1 | 关闭浏览器 2 | ========== 3 | 4 | 场景 5 | ---- 6 | 在脚本运行完毕或者测试代码结束的时候关闭浏览器是非常自然的事情,就像在吃完饭后就把餐桌收拾干净一样。 7 | 8 | 关闭浏览器有两种方式: 9 | 10 | * close方法 11 | 12 | * quit方法 13 | 14 | close方法关闭当前的浏览器窗口,quit方法不仅关闭窗口,还会彻底的退出webdriver,释放与driver server之间的连接。所以简单来说quit是更加彻底的close,quit会更好的释放资源,适合强迫症和完美主义者。 15 | 16 | 代码 17 | ---- 18 | ```python 19 | from selenium import webdriver 20 | import time 21 | 22 | dr = webdriver.Chrome() 23 | time.sleep(2) 24 | print 'browser will be closed' 25 | dr.quit() # or dr.close() 26 | print 'browser is closed' 27 | ``` 28 | -------------------------------------------------------------------------------- /26/frame.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'frame.html')) 6 | dr.get file_path 7 | 8 | # 先到f1再到f2 9 | dr.switch_to.frame('f1') 10 | dr.switch_to.frame('f2') 11 | # 往f2中的百度关键字文本框中输入内容 12 | dr.find_element(id: 'kw').send_keys 'watir-webdriver' 13 | 14 | # 直接跳出所有frame 15 | dr.switch_to.default_content 16 | 17 | # 再到f1 18 | dr.switch_to.frame('f1') 19 | dr.find_element(link_text: 'click').click 20 | 21 | sleep(2) 22 | dr.quit() 23 | 24 | -------------------------------------------------------------------------------- /32/cookie.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from time import sleep 5 | import os 6 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 7 | 8 | dr = webdriver.Chrome() 9 | 10 | url = 'http://www.baidu.com' 11 | dr.get(url) 12 | 13 | print dr.get_cookies() 14 | dr.delete_all_cookies() 15 | dr.add_cookie({'name': 'BAIDUID', 'value': 'xxxxxx'}) 16 | dr.add_cookie({'name': 'BDUSS', 'value': 'xxxxxx'}) 17 | 18 | dr.get(url) 19 | 20 | sleep(3) 21 | dr.quit() 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile ~/.gitignore_global 6 | 7 | # Ignore bundler config 8 | /.bundle 9 | 10 | # Ignore the default SQLite database. 11 | /db/*.sqlite3 12 | 13 | # Ignore all logfiles and tempfiles. 14 | *.log 15 | /tmp 16 | 17 | # Ignore vim swp files. 18 | *.swp 19 | 20 | /_book 21 | 22 | -------------------------------------------------------------------------------- /10/level_locate.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'level_locate.html')) 6 | 7 | dr.get file_path 8 | 9 | dr.find_element(:link_text, 'Link1').click 10 | wait = Selenium::WebDriver::Wait.new({:timeout => 30}) 11 | wait.until { dr.find_element(:id, 'dropdown1').displayed? } 12 | menu = dr.find_element(:id, 'dropdown1').find_element(:link_text, 'Another action') 13 | 14 | dr.action.move_to(menu).perform() 15 | 16 | sleep 2 17 | dr.quit 18 | 19 | -------------------------------------------------------------------------------- /11/operate_element.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | import time 4 | import os 5 | 6 | dr = webdriver.Chrome() 7 | file_path = 'file:///' + os.path.abspath('operate_element.html') 8 | dr.get(file_path) 9 | 10 | # click 11 | dr.find_element_by_link_text('Link1').click() 12 | time.sleep(1) 13 | dr.find_element_by_link_text('Link1').click() 14 | 15 | # send_keys 16 | element = dr.find_element_by_name('q') 17 | element.send_keys('something') 18 | time.sleep(1) 19 | 20 | # clear 21 | element.clear() 22 | time.sleep(1) 23 | 24 | dr.quit() 25 | 26 | -------------------------------------------------------------------------------- /17/pagination.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'pagination.html')) 6 | dr.get file_path 7 | 8 | # 获得所有分页的数量 9 | # -2是因为要去掉上一个和下一个 10 | total_pages = dr.find_element(:class, 'pagination').find_elements(:tag_name, 'li').size - 2 11 | puts "total page is #{total_pages}" 12 | 13 | # 获取当前页面的url以及当前页面是第几页 14 | current_page = dr.find_element(:class, 'pagination').find_element(:class, 'active') 15 | puts "current page is #{current_page.text}" 16 | dr.quit() 17 | 18 | -------------------------------------------------------------------------------- /07/forword_and_back.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from time import sleep 3 | import os 4 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 5 | 6 | dr = webdriver.Chrome() 7 | 8 | first_url = 'http://www.baidu.com' 9 | print "now access %s" %(first_url) 10 | 11 | dr.get(first_url) 12 | sleep(1) 13 | second_url = 'http://www.news.baidu.com' 14 | print "now access %s" %(second_url) 15 | dr.get(second_url) 16 | sleep(1) 17 | 18 | print "back to %s" %(first_url) 19 | dr.back() 20 | sleep(1) 21 | print "forward to %s" %(second_url) 22 | dr.forward() 23 | sleep(1) 24 | dr.quit() 25 | -------------------------------------------------------------------------------- /14/button_dropdown.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'button_dropdown.html')) 6 | dr.get file_path 7 | 8 | # 定位text是watir-webdriver的下拉菜单 9 | # 首先显示下拉菜单 10 | dr.find_element(:link_text, 'Info').click() 11 | wait = Selenium::WebDriver::Wait.new(timeout: 10) 12 | wait.until { dr.find_element(:class, 'dropdown-menu').displayed? } 13 | 14 | # 通过ul再层级定位 15 | dr.find_element(:class, 'dropdown-menu').find_element(:link_text, 'watir-webdriver').click() 16 | sleep(1) 17 | 18 | dr.quit() 19 | 20 | -------------------------------------------------------------------------------- /15/navs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from time import sleep 5 | import os 6 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 7 | 8 | dr = webdriver.Chrome() 9 | file_path = 'file:///' + os.path.abspath('navs.html') 10 | 11 | dr.get(file_path) 12 | 13 | sleep(1) 14 | 15 | # 方法1:层级定位,先定位ul再定位li 16 | dr.find_element_by_class_name('nav').find_element_by_link_text('About').click() 17 | sleep(1) 18 | 19 | # 方法2: 直接定位link 20 | dr.find_element_by_link_text('Home').click() 21 | sleep(1) 22 | 23 | dr.quit() 24 | 25 | -------------------------------------------------------------------------------- /25/wait.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from time import sleep 5 | import os 6 | import selenium.webdriver.support.ui as ui 7 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 8 | 9 | dr = webdriver.Chrome() 10 | file_path = 'file:///' + os.path.abspath('wait.html') 11 | 12 | dr.get(file_path) 13 | 14 | # 点击按钮 15 | dr.find_element_by_id('btn').click() 16 | 17 | wait = ui.WebDriverWait(dr, 10) 18 | wait.until(lambda dr: dr.find_element_by_class_name('label').is_displayed()) 19 | 20 | sleep(2) 21 | dr.quit() 22 | 23 | -------------------------------------------------------------------------------- /13/button_group.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from time import sleep 5 | import os 6 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 7 | 8 | dr = webdriver.Chrome() 9 | file_path = 'file:///' + os.path.abspath('button_group.html') 10 | 11 | dr.get(file_path) 12 | 13 | sleep(1) 14 | 15 | # 定位text是second的按钮 16 | buttons = dr.find_element_by_class_name('btn-group').find_elements_by_class_name('btn') 17 | for btn in buttons: 18 | if btn.text == 'second': print 'find second button' 19 | 20 | sleep(1) 21 | dr.quit() 22 | 23 | -------------------------------------------------------------------------------- /12/send_keys.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'send_keys.html')) 6 | dr.get file_path 7 | 8 | # copy content of A 9 | dr.find_element(:id, 'A').send_keys([:control, 'a']) 10 | dr.find_element(:id, 'A').send_keys([:control, 'x']) 11 | sleep(1) 12 | 13 | # paste to B 14 | dr.find_element(:id, 'B').send_keys([:control, 'v']) 15 | sleep(1) 16 | 17 | # send keys to A 18 | dr.find_element(:id, 'A').send_keys('watir', '-', 'webdriver', :space, 'is', :space, 'better') 19 | sleep(2) 20 | 21 | dr.quit() 22 | 23 | -------------------------------------------------------------------------------- /19/input.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | import selenium.webdriver.support.ui as ui 6 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 7 | 8 | dr = webdriver.Chrome() 9 | file_path = 'file:///' + os.path.abspath('input.html') 10 | 11 | dr.get(file_path) 12 | 13 | text_field = dr.find_element_by_class_name('well').find_element_by_css_selector('input[type=text]') 14 | 15 | print text_field.get_attribute('id') 16 | print text_field.get_attribute('name') 17 | print text_field.get_attribute('class') 18 | print text_field.get_attribute('value') 19 | 20 | dr.quit() 21 | 22 | -------------------------------------------------------------------------------- /10/level_locate.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.support.ui import WebDriverWait 4 | import time 5 | import os 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('level_locate.html') 9 | dr.get(file_path) 10 | 11 | dr.find_element_by_link_text('Link1').click() 12 | 13 | WebDriverWait(dr, 10).until(lambda the_driver: the_driver.find_element_by_id('dropdown1').is_displayed()) 14 | menu = dr.find_element_by_id('dropdown1').find_element_by_link_text('Another action') 15 | 16 | webdriver.ActionChains(dr).move_to_element(menu).perform() 17 | 18 | time.sleep(2) 19 | 20 | dr.quit() 21 | 22 | -------------------------------------------------------------------------------- /07/forword_and_back.md: -------------------------------------------------------------------------------- 1 | 前进和后退 2 | =========== 3 | 4 | 场景 5 | ---- 6 | 说实话,这两个功能一般不太常用。所能想到的场景大概也就是在几个页面间来回跳转,省去每次都get url。 7 | 8 | 代码 9 | ---- 10 | 11 | ``` 12 | require 'selenium-webdriver' 13 | 14 | dr = Selenium::WebDriver.for :chrome 15 | first_url = 'http://www.baidu.com' 16 | puts "now access #{first_url}" 17 | dr.get(first_url) 18 | sleep 1 19 | second_url = 'http://www.news.baidu.com' 20 | puts "now access #{second_url}" 21 | dr.get(second_url) 22 | sleep 1 23 | 24 | puts "back to #{first_url}" 25 | dr.navigate.back() 26 | sleep 1 27 | puts "forward to #{second_url}" 28 | dr.navigate.forward() 29 | sleep 1 30 | dr.quit() 31 | ``` 32 | -------------------------------------------------------------------------------- /22/form.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'form.html')) 6 | 7 | b.goto file_path 8 | 9 | # watir中跟form元素相关的方法有 10 | # checkbox 11 | # radio 12 | # text_field 13 | # text_area 14 | # button(input submit or button) 15 | # form 16 | # select 17 | 18 | # 选中checkbox 19 | b.checkbox.set true 20 | sleep(1) 21 | 22 | # 选中radio 23 | b.radio.set 24 | sleep(1) 25 | 26 | # 选择下拉菜单中的最后一项 27 | b.select.options.last.click 28 | sleep(1) 29 | 30 | # 点击提交按钮 31 | b.button.click 32 | sleep(1) 33 | 34 | alert = b.alert 35 | puts alert.text 36 | alert.ok() 37 | 38 | b.close() 39 | 40 | -------------------------------------------------------------------------------- /30/timeout.java.md: -------------------------------------------------------------------------------- 1 | 超时设置 2 | ========= 3 | 4 | 场景 5 | ---- 6 | webdriver中可以设置很多的超时时间 7 | 8 | * implicitlyWait。识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出NoSuchElement异常 9 | * setScriptTimeout。异步脚本的超时时间。webdriver可以异步执行脚本,这个是设置异步执行脚本脚本返回结果的超时时间 10 | * pageLoadTimeout。页面加载时的超时时间。因为webdriver会等页面加载完毕在进行后面的操作,所以如果页面在这个超时时间内没有加载完成,那么webdriver就会抛出异常 11 | 12 | 代码 13 | ---- 14 | 15 | ``` 16 | # 定位对象时给3s的时间 17 | # 如果3s内还定位不到则抛出异常 18 | driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS); 19 | 20 | # 页面加载超时时间设置为5s 21 | dr.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS); 22 | 23 | # 异步脚本的超时时间设置成3s 24 | dr.manage().timeouts().setScriptTimeout(3, TimeUnit.SECONDS); 25 | 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /06/TitleAndUrl.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.WebDriver; 2 | import org.openqa.selenium.chrome.ChromeDriver; 3 | 4 | 5 | public class TitleAndUrl { 6 | 7 | public static void main(String[] args) throws InterruptedException { 8 | WebDriver dr = new ChromeDriver(); 9 | Thread.sleep(2000); 10 | 11 | String url = "http://www.baidu.com"; 12 | System.out.printf("now accesss %s \n", url); 13 | 14 | dr.get(url); 15 | Thread.sleep(2000); 16 | 17 | System.out.printf("title of current page is %s\n", dr.getTitle()); 18 | System.out.printf("url of current page is %s\n", dr.getCurrentUrl()); 19 | 20 | System.out.println("browser will be close"); 21 | dr.quit(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /22/form.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'form.html')) 6 | dr.get file_path 7 | 8 | # 选中checkbox 9 | dr.find_element(:css, 'input[type=checkbox]').click() 10 | sleep(1) 11 | 12 | # 选中radio 13 | dr.find_element(:css, 'input[type=radio]').click() 14 | sleep(1) 15 | 16 | # 选择下拉菜单中的最后一项 17 | dr.find_element(:tag_name, 'select').find_elements(:tag_name, 'option').last.click() 18 | sleep(1) 19 | 20 | # 点击提交按钮 21 | dr.find_element(:css, 'input[type=submit]').click() 22 | sleep(1) 23 | 24 | alert = dr.switch_to.alert 25 | puts alert.text 26 | alert.accept() 27 | 28 | dr.quit() 29 | 30 | -------------------------------------------------------------------------------- /17/pagination.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('pagination.html') 9 | 10 | dr.get(file_path) 11 | 12 | # 获得所有分页的数量 13 | # -2是因为要去掉上一个和下一个 14 | total_pages = len(dr.find_element_by_class_name('pagination').find_elements_by_tag_name('li')) - 2 15 | print "total page is %s" %(total_pages) 16 | 17 | # 获取当前页面的url以及当前页面是第几页 18 | current_page = dr.find_element_by_class_name('pagination').find_element_by_class_name('active') 19 | print "current page is %s" %(current_page.text) 20 | 21 | dr.quit() 22 | 23 | -------------------------------------------------------------------------------- /04/resize_browser.md: -------------------------------------------------------------------------------- 1 | 设置浏览器大小 2 | ============== 3 | 4 | 场景 5 | ---- 6 | 设置浏览器窗口的大小有下面两个比较常见的用途: 7 | 8 | * 在统一的浏览器大小下运行用例,可以比较容易的跟一些基于图像比对的工具进行结合,提升测试的灵活性及普遍适用性。比如可以跟sikuli结合,使用sikuli操作flash; 9 | 10 | * 在不同的浏览器大小下访问测试站点,对测试页面截图并保存,然后观察或使用图像比对工具对被测页面的前端样式进行评测。比如可以将浏览器设置成移动端大小(320x480),然后访问移动站点,对其样式进行评估; 11 | 12 | 代码 13 | ---- 14 | 将浏览器调整成移动端大小,然后访问移动站点,对移动站点的样式进行评估。 15 | 16 | ``` 17 | require 'selenium-webdriver' 18 | 19 | dr = Selenium::WebDriver.for :chrome 20 | 21 | dr.manage.window.resize_to(320,480) 22 | dr.get 'http://www.3g.qq.com' 23 | 24 | sleep 5 25 | dr.quit 26 | ``` 27 | 28 | 讨论 29 | ---- 30 | 31 | webdriver提供了很多调整浏览器窗口的接口,比如move_to(移动窗口),position(设置或获取浏览器的位置)。在一般情况下这些功能并不常用。 32 | 33 | -------------------------------------------------------------------------------- /04/resize_browser.py.md: -------------------------------------------------------------------------------- 1 | 设置浏览器大小 2 | ============== 3 | 4 | 场景 5 | ---- 6 | 设置浏览器窗口的大小有下面两个比较常见的用途: 7 | 8 | * 在统一的浏览器大小下运行用例,可以比较容易的跟一些基于图像比对的工具进行结合,提升测试的灵活性及普遍适用性。比如可以跟sikuli结合,使用sikuli操作flash; 9 | 10 | * 在不同的浏览器大小下访问测试站点,对测试页面截图并保存,然后观察或使用图像比对工具对被测页面的前端样式进行评测。比如可以将浏览器设置成移动端大小(320x480),然后访问移动站点,对其样式进行评估; 11 | 12 | 代码 13 | ---- 14 | 将浏览器调整成移动端大小,然后访问移动站点,对移动站点的样式进行评估。 15 | 16 | ```python 17 | from selenium import webdriver 18 | import time 19 | 20 | dr = webdriver.Chrome() 21 | 22 | dr.set_window_size(240, 320) 23 | dr.get('http://www.3g.qq.com') 24 | 25 | time.sleep(5) 26 | dr.quit() 27 | 28 | ``` 29 | 30 | 讨论 31 | ---- 32 | 33 | webdriver提供了很多调整浏览器窗口的接口,比如set_window_position(设置或获取浏览器的位置)。在一般情况下这些功能并不常用。 34 | 35 | -------------------------------------------------------------------------------- /27/action.md: -------------------------------------------------------------------------------- 1 | action 2 | ======= 3 | 4 | 场景 5 | ---- 6 | 由于webdriver是要模拟真实的用户操作,因此webdriver的Action类中提供了很多与操作有关的方法。 7 | 8 | 下面列举一下Action类的一些主要方法 9 | 10 | * key_down。模拟按键按下 11 | * key_up。模拟按键弹起 12 | * click 13 | * send_keys 14 | * double_click。鼠标左键双击 15 | * click_and_hold。鼠标左键点击住不放 16 | * release。鼠标左键弹起,可以与click_and_hold配合使用 17 | * move_to。把鼠标移动到元素的中心点 18 | * content_click。鼠标右键点击 19 | * drag_and_drop。拖拽 20 | 21 | 代码 22 | ---- 23 | ``` 24 | driver.action.key_down(:shift). 25 | click(element). 26 | click(second_element). 27 | key_up(:shift). 28 | drag_and_drop(element, third_element). 29 | perform 30 | ``` 31 | 32 | 讨论 33 | ---- 34 | 具体使用方法可以参考api文档。action的api文档算是比较全面了。 35 | -------------------------------------------------------------------------------- /02/close_browser.java.md: -------------------------------------------------------------------------------- 1 | 关闭浏览器 2 | ========== 3 | 4 | 场景 5 | ---- 6 | 在脚本运行完毕或者测试代码结束的时候关闭浏览器是非常自然的事情,就像在吃完饭后就把餐桌收拾干净一样。 7 | 8 | 关闭浏览器有两种方式: 9 | 10 | * close方法 11 | 12 | * quit方法 13 | 14 | close方法关闭当前的浏览器窗口,quit方法不仅关闭窗口,还会彻底的退出webdriver,释放与driver server之间的连接。所以简单来说quit是更加彻底的close,quit会更好的释放资源,适合强迫症和完美主义者。 15 | 16 | 代码 17 | ---- 18 | ``` 19 | import org.openqa.selenium.WebDriver; 20 | import org.openqa.selenium.chrome.ChromeDriver; 21 | 22 | 23 | public class CloseBrowser { 24 | 25 | public static void main(String[] args) { 26 | WebDriver dr = new ChromeDriver(); 27 | System.out.println("browser will be closed"); 28 | 29 | dr.quit(); 30 | System.out.println("browser is closed"); 31 | } 32 | 33 | } 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /07/forword_and_back.py.md: -------------------------------------------------------------------------------- 1 | 前进和后退 2 | =========== 3 | 4 | 场景 5 | ---- 6 | 说实话,这两个功能一般不太常用。所能想到的场景大概也就是在几个页面间来回跳转,省去每次都get url。 7 | 8 | 代码 9 | ---- 10 | 11 | ```python 12 | from selenium import webdriver 13 | from time import sleep 14 | import os 15 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 16 | 17 | dr = webdriver.Chrome() 18 | 19 | first_url = 'http://www.baidu.com' 20 | print "now access %s" %(first_url) 21 | 22 | dr.get(first_url) 23 | sleep(1) 24 | second_url = 'http://www.news.baidu.com' 25 | print "now access %s" %(second_url) 26 | dr.get(second_url) 27 | sleep(1) 28 | 29 | print "back to %s" %(first_url) 30 | dr.back() 31 | sleep(1) 32 | print "forward to %s" %(second_url) 33 | dr.forward() 34 | sleep(1) 35 | dr.quit() 36 | ``` 37 | -------------------------------------------------------------------------------- /12/send_keys.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.common.keys import Keys 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('send_keys.html') 9 | 10 | dr.get(file_path) 11 | 12 | # copy content of A 13 | dr.find_element_by_id('A').send_keys((Keys.CONTROL, 'a')) 14 | dr.find_element_by_id('A').send_keys((Keys.CONTROL, 'x')) 15 | sleep(1) 16 | 17 | # paste to B 18 | dr.find_element_by_id('B').send_keys((Keys.CONTROL, 'v')) 19 | sleep(1) 20 | 21 | # # send keys to A 22 | dr.find_element_by_id('A').send_keys('watir', '-', 'webdriver', Keys.SPACE, 'is', Keys.SPACE, 'better') 23 | sleep(2) 24 | 25 | dr.quit() 26 | -------------------------------------------------------------------------------- /26/frame.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from time import sleep 5 | import os 6 | import selenium.webdriver.support.ui as ui 7 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 8 | 9 | dr = webdriver.Chrome() 10 | file_path = 'file:///' + os.path.abspath('frame.html') 11 | 12 | dr.get(file_path) 13 | 14 | # 先到f1再到f2 15 | dr.switch_to_frame('f1') 16 | dr.switch_to_frame('f2') 17 | 18 | # 往f2中的百度关键字文本框中输入内容 19 | dr.find_element_by_id('kw').send_keys('watir-webdriver') 20 | 21 | # 直接跳出所有frame 22 | dr.switch_to_default_content() 23 | 24 | # 再到f1 25 | dr.switch_to_frame('f1') 26 | dr.find_element_by_link_text('click').click() 27 | 28 | sleep(2) 29 | dr.quit() 30 | 31 | -------------------------------------------------------------------------------- /29/download.py.md: -------------------------------------------------------------------------------- 1 | 下载 2 | ===== 3 | 4 | 场景 5 | ---- 6 | webdriver允许我们设置默认的文件下载路径。也就是说文件会自动下载并且存在设置的那个目录中。 7 | 8 | 下面会给出chrome和firefox浏览器的具体设置方法。 9 | 10 | 代码 11 | ----- 12 | 13 | ``` 14 | import os 15 | 16 | from selenium import webdriver 17 | 18 | fp = webdriver.FirefoxProfile() 19 | 20 | fp.set_preference("browser.download.folderList",2) 21 | fp.set_preference("browser.download.manager.showWhenStarting",False) 22 | fp.set_preference("browser.download.dir", os.getcwd()) 23 | fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream") 24 | 25 | browser = webdriver.Firefox(firefox_profile=fp) 26 | browser.get("http://pypi.python.org/pypi/selenium") 27 | browser.find_element_by_partial_link_text("selenium-2").click() 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /09/find_elements.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'checkbox.html')) 6 | 7 | dr.get file_path 8 | 9 | # 选择所有的checkbox并全部勾上 10 | dr.find_elements(:css, 'input[type=checkbox]').each {|c| c.click} 11 | dr.navigate.refresh() 12 | sleep 1 13 | 14 | # 打印当前页面上有多少个checkbox 15 | puts dr.find_elements(:css, 'input[type=checkbox]').size 16 | 17 | # 选择页面上所有的input,然后从中过滤出所有的checkbox并勾选之 18 | dr.find_elements(:tag_name, 'input').each do |input| 19 | input.click if input.attribute(:type) == 'checkbox' 20 | end 21 | sleep 1 22 | 23 | # 把页面上最后1个checkbox的勾给去掉 24 | dr.find_elements(:css, 'input[type=checkbox]').last.click 25 | 26 | sleep 2 27 | dr.quit 28 | 29 | -------------------------------------------------------------------------------- /28/upload_file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | upload_file 5 | 6 | 7 | 9 | 10 | 11 | 12 |
13 |
14 |

upload_file

15 | 16 |
17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /27/action.java.md: -------------------------------------------------------------------------------- 1 | action 2 | ======= 3 | 4 | 场景 5 | ---- 6 | 由于webdriver是要模拟真实的用户操作,因此webdriver的Action类中提供了很多与操作有关的方法。 7 | 8 | 下面列举一下Action类的一些主要方法 9 | 10 | * keyDown。模拟按键按下 11 | * keyUp。模拟按键弹起 12 | * click 13 | * sendKeys 14 | * doubleClick。鼠标左键双击 15 | * clickAndHold。鼠标左键点击住不放 16 | * release。鼠标左键弹起,可以与click_and_hold配合使用 17 | * moveToElement。把鼠标移动到元素的中心点 18 | * contextClick。鼠标右键点击 19 | * dragAndDrop。拖拽 20 | 21 | 代码 22 | ---- 23 | ``` 24 | Actions action = new Actions(driver) 25 | action.keyDown(Keys.SHIFT). 26 | click(element). 27 | click(second_element). 28 | keyUp(Keys.SHIFT). 29 | dragAndDrop(element, third_element). 30 | build(). 31 | perform() 32 | ``` 33 | 34 | 讨论 35 | ---- 36 | 具体使用方法可以参考api文档。action的api文档算是比较全面了。 37 | -------------------------------------------------------------------------------- /03/maximize_browser.java.md: -------------------------------------------------------------------------------- 1 | 浏览器最大化 2 | ============ 3 | 4 | 场景 5 | ---- 6 | 当我们在测试中使用一些基于图像和坐标的辅助测试工具时,我们就会需要使浏览器在每次测试时保存最大化,以便在同一分辨率下进行图像比对和坐标点选。 7 | 8 | 举例来说,如果在webdriver测试中使用了sikuli来对flash插件进行操作的话,把浏览器最大化无疑是一个比较简单的保证分辨率统一的解决方案。 9 | 10 | 代码 11 | ---- 12 | ``` 13 | import org.openqa.selenium.WebDriver; 14 | import org.openqa.selenium.chrome.ChromeDriver; 15 | 16 | 17 | public class Maximize { 18 | 19 | public static void main(String[] args) throws InterruptedException { 20 | WebDriver dr = new ChromeDriver(); 21 | Thread.sleep(2000); 22 | 23 | System.out.println("maximize browser"); 24 | dr.manage().window().maximize(); 25 | Thread.sleep(2000); 26 | 27 | System.out.println("browser will be close"); 28 | dr.quit(); 29 | } 30 | 31 | } 32 | 33 | ``` 34 | 35 | 36 | -------------------------------------------------------------------------------- /18/modal.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'modal.html')) 6 | dr.get file_path 7 | 8 | # 打开对话框 9 | dr.find_element(:id, 'show_modal').click 10 | 11 | wait = Selenium::WebDriver::Wait.new(timeout: 10) 12 | wait.until { dr.find_element(id: 'myModal').displayed? } 13 | 14 | # 点击对话框中的链接 15 | # 由于对话框中的元素被蒙板所遮挡,直接点击会报 Element is not clickable的错误 16 | # 所以使用js来模拟click 17 | # 在watir-webdriver中只需要fire_event(:click)就可以了 18 | link = dr.find_element(id: 'myModal').find_element(id: 'click') 19 | dr.execute_script('$(arguments[0]).click()', link) 20 | sleep(2) 21 | 22 | # 关闭对话框 23 | dr.find_element(:class, 'modal-footer').find_elements(:tag_name, 'button').first.click 24 | 25 | dr.quit() 26 | 27 | -------------------------------------------------------------------------------- /27/action.py.md: -------------------------------------------------------------------------------- 1 | action 2 | ======= 3 | 4 | 场景 5 | ---- 6 | 由于webdriver是要模拟真实的用户操作,因此webdriver的Action类中提供了很多与操作有关的方法。 7 | 8 | 下面列举一下Action类的一些主要方法 9 | 10 | * key_down。模拟按键按下 11 | * key_up。模拟按键弹起 12 | * click 13 | * send_keys 14 | * double_click。鼠标左键双击 15 | * click_and_hold。鼠标左键点击住不放 16 | * release。鼠标左键弹起,可以与click_and_hold配合使用 17 | * move_to_element。把鼠标移动到元素的中心点 18 | * context_click。鼠标右键点击 19 | * drag_and_drop。拖拽 20 | 21 | 22 | 代码 23 | ---- 24 | ``` 25 | from selenium.webdriver.common.action_chains import ActionChains 26 | 27 | element = wd.find_element_by_link_text('xxxxx') 28 | hov = ActionChains(wd).move_to_element(element) 29 | hov.perform() 30 | ``` 31 | 32 | 讨论 33 | ---- 34 | 具体的api文档参考[这里](http://selenium-python.readthedocs.org/en/latest/api.html#module-selenium.webdriver.common.action_chains) 35 | -------------------------------------------------------------------------------- /35/select.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.support.select import Select 4 | from time import sleep 5 | import os 6 | 7 | dr = webdriver.Firefox() 8 | file_path = 'file:///' + os.path.abspath('select.html') 9 | dr.get(file_path) 10 | 11 | phone_selector = Select(dr.find_element_by_tag_name('select')) 12 | 13 | # 返回所有的options 14 | print(phone_selector.options) 15 | sleep(1) 16 | 17 | # 返回所有选中的options 18 | print(phone_selector.all_selected_options) 19 | sleep(1) 20 | 21 | # 通过option的value值来选择iphone 7 22 | phone_selector.select_by_value('ip7') 23 | sleep(2) 24 | 25 | # 通过index来选择,比如选择第2项 26 | phone_selector.select_by_index(1) 27 | sleep(1) 28 | 29 | # 通过option的text来选择 30 | phone_selector.select_by_visible_text('iPhone 6s') 31 | 32 | 33 | dr.quit() 34 | -------------------------------------------------------------------------------- /14/button_dropdown.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from selenium.webdriver.common.keys import Keys 4 | from time import sleep 5 | import os 6 | import selenium.webdriver.support.ui as ui 7 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 8 | 9 | dr = webdriver.Chrome() 10 | file_path = 'file:///' + os.path.abspath('button_dropdown.html') 11 | 12 | dr.get(file_path) 13 | 14 | # 定位text是watir-webdriver的下拉菜单 15 | # 首先显示下拉菜单 16 | dr.find_element_by_link_text('Info').click() 17 | 18 | wait = ui.WebDriverWait(dr, 10) 19 | wait.until(lambda dr: dr.find_element_by_class_name('dropdown-menu').is_displayed()) 20 | 21 | # 通过ul再层级定位 22 | dr.find_element_by_class_name('dropdown-menu').find_element_by_link_text('watir-webdriver').click() 23 | sleep(1) 24 | 25 | dr.quit() 26 | 27 | -------------------------------------------------------------------------------- /22/form.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('form.html') 9 | dr.get(file_path) 10 | 11 | # 选中checkbox 12 | dr.find_element_by_css_selector('input[type=checkbox]').click() 13 | sleep(1) 14 | 15 | # 选中radio 16 | dr.find_element_by_css_selector('input[type=radio]').click() 17 | sleep(1) 18 | 19 | # 选择下拉菜单中的最后一项 20 | dr.find_element_by_tag_name('select').find_elements_by_tag_name('option')[-1].click() 21 | sleep(1) 22 | 23 | # 点击提交按钮 24 | dr.find_element_by_css_selector('input[type=submit]').click() 25 | sleep(10) 26 | 27 | alert = dr.switch_to_alert() 28 | print alert.text 29 | alert.accept() 30 | 31 | dr.quit() 32 | 33 | -------------------------------------------------------------------------------- /26/frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | frame 5 | 6 | 7 | 11 | 12 | 13 | 14 |
15 |
16 |

frame

17 | 18 |
19 |
20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /05/get.java.md: -------------------------------------------------------------------------------- 1 | 访问链接 2 | ======== 3 | 4 | 情景 5 | ---- 6 | web UI测试里最简单也是最基本的事情就是访问1个链接了。 7 | 8 | webdriver的api里有2种访问url的方式,分别是get和navigate.to方法。一般情况下建议使用get,因为其字母比较少,不太容易出错。 9 | 10 | 代码 11 | ---- 12 | 13 | ``` 14 | import org.openqa.selenium.WebDriver; 15 | import org.openqa.selenium.chrome.ChromeDriver; 16 | 17 | 18 | public class Get { 19 | 20 | public static void main(String[] args) throws InterruptedException { 21 | WebDriver dr = new ChromeDriver(); 22 | Thread.sleep(2000); 23 | 24 | String url = "http://www.baidu.com"; 25 | System.out.printf("now accesss %s \n", url); 26 | dr.get(url); 27 | Thread.sleep(2000); 28 | 29 | System.out.println("browser will be close"); 30 | dr.quit(); 31 | } 32 | 33 | } 34 | 35 | ``` 36 | 37 | 讨论 38 | ---- 39 | navigate方法实际上会产生1个Navigator对象,其封装了与导航相关的一些方法,比如前进后退等。 40 | 41 | 42 | -------------------------------------------------------------------------------- /32/CookieExample.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.Cookie; 2 | import org.openqa.selenium.WebDriver; 3 | import org.openqa.selenium.chrome.ChromeDriver; 4 | 5 | 6 | public class CookieExample { 7 | 8 | public static void main(String[] args) throws InterruptedException { 9 | WebDriver dr = new ChromeDriver(); 10 | 11 | String url = "http://www.baidu.com"; 12 | System.out.printf("now accesss %s \n", url); 13 | 14 | dr.get(url); 15 | Thread.sleep(2000); 16 | 17 | System.out.println(dr.manage().getCookies()); 18 | 19 | dr.manage().deleteAllCookies(); 20 | 21 | Cookie c1 = new Cookie("BAIDUID", "xxxxxxxxxx"); 22 | Cookie c2 = new Cookie("BDUSS", "xxxxxxxxxx"); 23 | dr.manage().addCookie(c1); 24 | dr.manage().addCookie(c2); 25 | 26 | System.out.println("browser will be close"); 27 | 28 | dr.quit(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /21/status.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'status.html')) 6 | 7 | b.goto file_path 8 | 9 | # watir没有enabled方法 10 | # 不过可以element的private方法assert_enabled来判断元素的状态 11 | text_field = b.text_field(:name, 'user') 12 | begin 13 | text_field.send(:assert_enabled) 14 | rescue 15 | puts 'element disabled' 16 | end 17 | 18 | # 隐藏掉text_field 19 | # 判断其是否显示 20 | # watir 中使用visible方法 21 | b.execute_script('$(arguments[0]).hide()', text_field) 22 | puts text_field.visible? 23 | 24 | # 使用click方法选择raido 25 | radio = b.radio(name: 'radio') 26 | radio.set() 27 | puts radio.set? 28 | 29 | # 判断元素是否存在 exists 30 | # 判断元素是否存在且可见 present 31 | puts b.text_field(:name, 'users').exists? 32 | puts b.text_field(:name, 'users').present? 33 | 34 | 35 | b.quit() 36 | 37 | -------------------------------------------------------------------------------- /29/download.md: -------------------------------------------------------------------------------- 1 | 下载 2 | ===== 3 | 4 | 场景 5 | ---- 6 | webdriver允许我们设置默认的文件下载路径。也就是说文件会自动下载并且存在设置的那个目录中。 7 | 8 | 下面会给出chrome和firefox浏览器的具体设置方法。 9 | 10 | 代码 11 | ----- 12 | 13 | ``` 14 | # for chrome 15 | profile = Selenium::WebDriver::Chrome::Profile.new 16 | # 设置自动下载 17 | profile['download.prompt_for_download'] = false 18 | # 设置具体路径 19 | profile['download.default_directory'] = "/path/to/dir" 20 | 21 | driver = Selenium::WebDriver.for :chrome, :profile => profile 22 | 23 | # for firefox 24 | profile = Selenium::WebDriver::Firefox::Profile.new 25 | 26 | profile['browser.download.dir'] = "/tmp/webdriver-downloads" 27 | profile['browser.download.folderList'] = 2 28 | # 设置哪些文件自动下载,这里设置的是pdf文件 29 | profile['browser.helperApps.neverAsk.saveToDisk'] = "application/pdf" 30 | 31 | driver = Selenium::WebDriver.for :firefox, :profile => profile 32 | 33 | ``` 34 | -------------------------------------------------------------------------------- /29/download.java.md: -------------------------------------------------------------------------------- 1 | 下载 2 | ===== 3 | 4 | 场景 5 | ---- 6 | webdriver允许我们设置默认的文件下载路径。也就是说文件会自动下载并且存在设置的那个目录中。 7 | 8 | 下面会给出firefox浏览器的具体设置方法。 9 | 10 | 代码 11 | ----- 12 | 13 | ``` 14 | driver = Selenium::WebDriver.for :chrome, :profile => profile 15 | 16 | # for firefox 17 | FirefoxProfile firefoxProfile = new FirefoxProfile(); 18 | 19 | firefoxProfile.setPreference("browser.download.folderList",2); 20 | firefoxProfile.setPreference("browser.download.manager.showWhenStarting",false); 21 | firefoxProfile.setPreference("browser.download.dir","c:\\downloads"); 22 | firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk","text/csv"); 23 | 24 | WebDriver driver = new FirefoxDriver(firefoxProfile); 25 | //new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability); 26 | 27 | driver.navigate().to("http://www.myfile.com/hey.csv"); 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /06/title_and_url.md: -------------------------------------------------------------------------------- 1 | 打印当前页面的title及url 2 | ======================== 3 | 4 | 情景 5 | ---- 6 | 测试中,访问1个页面然后判断其title是否符合预期是很常见的1个用例,所谓用例不够,title来凑就是这个道理。更具体一点,假设1个页面的title应该是'hello world', 那么可以写这样的一个用例:访问该页面,获取该页面的title,判断获取的值是否等于'hello world'。 7 | 8 | 获取当前页面的url也是非常重要的一个操作。在某些情况下,你访问一个url,这时系统会自动对这个url进行跳转,这就是所谓的'重定向'。一般测试重定向的方法是访问这个url,然后等待页面重定向完毕之后,获取当前页面的url,判断该url是否符合预期。另外的一个常见的测试场景是提交了一个表单,如果表单内容通过了验证,那么则会跳转到一个新页面,如果未通过验证,则会停留在当前页面,此时获取当前页面的url则可以帮助我们判断表单提交的跳转是否符合预期。更具体一点,假如你在测试一个登陆页面,输入正确的登陆信息后,会跳转到系统首页。获取跳转后的url然后判断其是否与系统首页的url相符将是一个很不错的用例。 9 | 10 | 代码 11 | ---- 12 | ``` 13 | require 'selenium-webdriver' 14 | 15 | dr = Selenium::WebDriver.for :chrome 16 | url = 'http://www.baidu.com' 17 | puts "now access #{url}" 18 | dr.get url 19 | 20 | puts "title of current page is #{dr.title}" 21 | puts "url of current page is #{dr.current_url}" 22 | sleep 1 23 | 24 | dr.quit 25 | ``` 26 | -------------------------------------------------------------------------------- /16/breadcrumb.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | breadcrumb 5 | 6 | 7 | 8 | 9 |

breadcrumb

10 |
11 |
12 | 17 |
18 |
19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /09/find_elements.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'checkbox.html')) 6 | 7 | b.goto file_path 8 | 9 | # 选择所有的checkbox并全部勾上 10 | #dr.find_elements(:css, 'input[type=checkbox]').each {|c| c.click} 11 | b.checkboxes.each { |c| c.set(true) } 12 | b.refresh 13 | sleep 1 14 | 15 | # 打印当前页面上有多少个checkbox 16 | #puts dr.find_elements(:css, 'input[type=checkbox]').size 17 | puts b.checkboxes.size 18 | 19 | # 选择页面上所有的input,然后从中过滤出所有的checkbox并勾选之 20 | # 在watir-webdriver中是不需要这样做的 21 | =begin 22 | dr.find_elements(:tag_name, 'input').each do |input| 23 | input.click if input.attribute(:type) == 'checkbox' 24 | end 25 | sleep 1 26 | =end 27 | 28 | # 把页面上最后1个checkbox的勾给去掉 29 | #dr.find_elements(:css, 'input[type=checkbox]').last.click 30 | b.checkboxes.last.click 31 | 32 | sleep 2 33 | b.close 34 | -------------------------------------------------------------------------------- /32/cookie.py.md: -------------------------------------------------------------------------------- 1 | cookie 2 | ====== 3 | 4 | 场景 5 | ----- 6 | webdriver可以读取并添加cookie。有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie的测试是无法通过白盒和集成测试完成的。 7 | 8 | 另外更加常见的一个场景是自动登陆。有很多系统的登陆信息都是保存在cookie里的,因此只要往cookie中添加正确的值就可以实现自动登陆了。什么图片验证码、登陆的用例就都是浮云了。 9 | 10 | 11 | 12 | 代码 13 | ---- 14 | 下面的代码演示了如何自动登陆百度。其中敏感信息我使用了xxxx来代替。 15 | ### cookie.py 16 | ``` 17 | # -*- coding: utf-8 -*- 18 | from selenium import webdriver 19 | from selenium.webdriver.common.keys import Keys 20 | from time import sleep 21 | import os 22 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 23 | 24 | dr = webdriver.Chrome() 25 | 26 | url = 'http://www.baidu.com' 27 | dr.get(url) 28 | 29 | print dr.get_cookies() 30 | dr.delete_all_cookies() 31 | dr.add_cookie({'name': 'BAIDUID', 'value': 'xxxxxx'}) 32 | dr.add_cookie({'name': 'BDUSS', 'value': 'xxxxxx'}) 33 | 34 | dr.get(url) 35 | 36 | sleep(3) 37 | dr.quit() 38 | 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /09/find_elements.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | import time 4 | import os 5 | 6 | dr = webdriver.Chrome() 7 | file_path = 'file:///' + os.path.abspath('checkbox.html') 8 | dr.get(file_path) 9 | 10 | # 选择所有的checkbox并全部勾上 11 | checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]') 12 | for checkbox in checkboxes: 13 | checkbox.click() 14 | time.sleep(1) 15 | dr.refresh() 16 | time.sleep(2) 17 | 18 | # 打印当前页面上有多少个checkbox 19 | print len(dr.find_elements_by_css_selector('input[type=checkbox]')) 20 | 21 | # 选择页面上所有的input,然后从中过滤出所有的checkbox并勾选之 22 | inputs = dr.find_elements_by_tag_name('input') 23 | for input in inputs: 24 | if input.get_attribute('type') == 'checkbox': 25 | input.click() 26 | 27 | time.sleep(1) 28 | 29 | # 把页面上最后1个checkbox的勾给去掉 30 | dr.find_elements_by_css_selector('input[type=checkbox]').pop().click() 31 | 32 | time.sleep(1) 33 | 34 | dr.quit() 35 | 36 | -------------------------------------------------------------------------------- /28/Upload.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.util.List; 3 | 4 | import org.openqa.selenium.Alert; 5 | import org.openqa.selenium.By; 6 | import org.openqa.selenium.Keys; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.WebElement; 9 | import org.openqa.selenium.chrome.ChromeDriver; 10 | 11 | 12 | public class Upload { 13 | 14 | public static void main(String[] args) throws InterruptedException { 15 | WebDriver dr = new ChromeDriver(); 16 | 17 | File file = new File("src/upload_file.html"); 18 | String filePath = "file:///" + file.getAbsolutePath(); 19 | System.out.printf("now accesss %s \n", filePath); 20 | 21 | dr.get(filePath); 22 | Thread.sleep(1000); 23 | 24 | dr.findElement(By.cssSelector("input[type=file]")).sendKeys("src/navs.html"); 25 | 26 | Thread.sleep(1000); 27 | System.out.println("browser will be close"); 28 | dr.quit(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /21/status.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'selenium-webdriver' 3 | 4 | dr = Selenium::WebDriver.for :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'status.html')) 6 | dr.get file_path 7 | 8 | text_field = dr.find_element(:name, 'user') 9 | puts text_field.enabled? 10 | 11 | # 直接用enabled?方法去判断该button的话返回的会是true 12 | # 这是因为button是使用css方法去disabled的,并不是真正的disable 13 | # 这时候需要判断其class里是否有disabled这值来判断其是否处于disable状态 14 | puts dr.find_element(:class, 'btn').enabled? 15 | 16 | # 隐藏掉text_field 17 | # 判断其是否显示 18 | dr.execute_script('$(arguments[0]).hide()', text_field) 19 | puts text_field.displayed? 20 | 21 | # 使用click方法选择raido 22 | radio = dr.find_element(name: 'radio') 23 | radio.click() 24 | puts radio.selected? 25 | 26 | # 判断元素是否存在 27 | begin 28 | dr.find_element(id: 'none') 29 | rescue Selenium::WebDriver::Error::NoSuchElementError 30 | puts 'element does not exist' 31 | end 32 | 33 | dr.quit() 34 | 35 | -------------------------------------------------------------------------------- /19/input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | attribute 5 | 6 | 7 | 11 | 12 | 13 | 14 |

attribute

15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /20/Css.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.util.List; 3 | 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | 9 | 10 | public class Css { 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | WebDriver dr = new ChromeDriver(); 14 | 15 | File file = new File("src/css.html"); 16 | String filePath = "file:///" + file.getAbsolutePath(); 17 | System.out.printf("now accesss %s \n", filePath); 18 | 19 | dr.get(filePath); 20 | Thread.sleep(1000); 21 | 22 | WebElement link = dr.findElement(By.id("tooltip")); 23 | 24 | System.out.println(link.getCssValue("color")); 25 | 26 | System.out.println(dr.findElement(By.tagName("h3")).getCssValue("font")); 27 | 28 | Thread.sleep(1000); 29 | System.out.println("browser will be close"); 30 | dr.quit(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /20/css.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | attribute 5 | 6 | 7 | 12 | 13 | 14 | 15 |

attribute

16 |
17 |
18 | hover to see tooltip 19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /04/resize_browser.java.md: -------------------------------------------------------------------------------- 1 | 设置浏览器大小 2 | ============== 3 | 4 | 场景 5 | ---- 6 | 设置浏览器窗口的大小有下面两个比较常见的用途: 7 | 8 | * 在统一的浏览器大小下运行用例,可以比较容易的跟一些基于图像比对的工具进行结合,提升测试的灵活性及普遍适用性。比如可以跟sikuli结合,使用sikuli操作flash; 9 | 10 | * 在不同的浏览器大小下访问测试站点,对测试页面截图并保存,然后观察或使用图像比对工具对被测页面的前端样式进行评测。比如可以将浏览器设置成移动端大小(320x480),然后访问移动站点,对其样式进行评估; 11 | 12 | 代码 13 | ---- 14 | 将浏览器调整成移动端大小,然后访问移动站点,对移动站点的样式进行评估。 15 | 16 | ``` 17 | import org.openqa.selenium.WebDriver; 18 | import org.openqa.selenium.chrome.ChromeDriver; 19 | 20 | 21 | public class CloseBrowser { 22 | 23 | public static void main(String[] args) { 24 | WebDriver dr = new ChromeDriver(); 25 | System.out.println("browser will be closed"); 26 | dr.manage().window().setSize(new Dimension(320, 240)); 27 | dr.quit(); 28 | System.out.println("browser is closed"); 29 | } 30 | 31 | } 32 | 33 | ``` 34 | 35 | 讨论 36 | ---- 37 | 38 | webdriver提供了很多调整浏览器窗口的接口,比如move_to(移动窗口),position(设置或获取浏览器的位置)。在一般情况下这些功能并不常用。 39 | 40 | -------------------------------------------------------------------------------- /19/attribute.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | attribute 5 | 6 | 7 | 12 | 13 | 14 | 15 |

attribute

16 |
17 |
18 | hover to see tooltip 19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /07/ForwardAndBack.java: -------------------------------------------------------------------------------- 1 | import org.openqa.selenium.WebDriver; 2 | import org.openqa.selenium.chrome.ChromeDriver; 3 | 4 | 5 | public class ForwardAndBack { 6 | 7 | public static void main(String[] args) throws InterruptedException { 8 | WebDriver dr = new ChromeDriver(); 9 | Thread.sleep(2000); 10 | 11 | String firstUrl = "http://www.baidu.com"; 12 | System.out.printf("now accesss %s \n", firstUrl); 13 | dr.get(firstUrl); 14 | Thread.sleep(1000); 15 | 16 | String secondUrl = "http://www.soso.com"; 17 | System.out.printf("now accesss %s \n", secondUrl); 18 | dr.get(secondUrl); 19 | Thread.sleep(1000); 20 | 21 | System.out.printf("now back to %s \n", firstUrl); 22 | dr.navigate().back(); 23 | Thread.sleep(1000); 24 | 25 | System.out.printf("forward to %s \n", secondUrl); 26 | dr.navigate().forward(); 27 | Thread.sleep(1000); 28 | 29 | System.out.println("browser will be close"); 30 | dr.quit(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /33/switch_window.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from selenium import webdriver 4 | from time import sleep 5 | import os 6 | 7 | # I write this code on my MBP and I can not launch chrome using chrome driver 8 | # use firefox instead 9 | dr = webdriver.Firefox() 10 | file_path = 'file:///' + os.path.abspath('switch_window.html') 11 | 12 | dr.get(file_path) 13 | print dr.title 14 | print dr.find_element_by_tag_name('h3').text 15 | 16 | open_new_win_link = dr.find_element_by_id('open-new-window') 17 | open_new_win_link.click() 18 | 19 | # find all window handles 20 | all_handles = dr.window_handles 21 | 22 | # find handle of the other window 23 | the_other_handle = '' 24 | for h in all_handles: 25 | if h != dr.current_window_handle: the_other_handle = h 26 | 27 | #switch window 28 | if the_other_handle: 29 | dr.switch_to_window(the_other_handle) 30 | print dr.title 31 | print dr.find_element_by_tag_name('h3').text 32 | assert dr.title == 'Sub Window' 33 | 34 | dr.quit -------------------------------------------------------------------------------- /08/simple_locate.watir.rb: -------------------------------------------------------------------------------- 1 | require 'watir-webdriver' 2 | 3 | b = Watir::Browser.new :chrome 4 | file_path = 'file:///' + File.expand_path(File.join('.', 'form.html')) 5 | 6 | b.goto file_path 7 | 8 | # by id 9 | b.text_field(:id, 'inputEmail').click 10 | 11 | # by name 12 | b.text_field(:name, 'password').click 13 | 14 | # by tagname 15 | puts b.form().attribute_value(:class) 16 | 17 | # by class_name 18 | e = b.div(:class, 'controls') 19 | b.execute_script('$(arguments[0]).fadeOut().fadeIn()', e) 20 | sleep 1 21 | 22 | # by link text 23 | link = b.link(:text, 'register') 24 | b.execute_script('$(arguments[0]).fadeOut().fadeIn()', link) 25 | sleep 1 26 | 27 | # by partial link text 28 | link = b.link(:text, /reg/) 29 | b.execute_script('$(arguments[0]).fadeOut().fadeIn()', link) 30 | sleep 1 31 | 32 | # by css selector 33 | div = b.element(:css, '.controls') 34 | b.execute_script('$(arguments[0]).fadeOut().fadeIn()', div) 35 | sleep 1 36 | 37 | sleep 2 38 | b.close 39 | -------------------------------------------------------------------------------- /10/level_locate.watir.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | require 'watir-webdriver' 3 | 4 | b = Watir::Browser.new :chrome 5 | file_path = 'file:///' + File.expand_path(File.join('.', 'level_locate.html')) 6 | 7 | b.goto file_path 8 | 9 | b.link(:text, 'Link1').click 10 | 11 | =begin 12 | wait = Selenium::WebDriver::Wait.new({:timeout => 30}) 13 | wait.until { dr.find_element(:id, 'dropdown1').displayed? } 14 | menu = dr.find_element(:id, 'dropdown1').find_element(:link_text, 'Another action') 15 | dr.action.move_to(menu).perform() 16 | =end 17 | 18 | 19 | menu = b.ul(:id, 'dropdown1').when_present.link(:text, 'Another action') 20 | # b.ul(:id, 'dropdown1').wait_until_present 21 | # Watir::Wait.until { b.ul(:id, 'dropdown1').present? } 22 | # b.ul(:id, 'dropdown1').link(:text, 'Another action').flash 23 | menu.focus 24 | 25 | # close menu 26 | b.link(:text, 'Link1').click 27 | b.ul(:id, 'dropdown1').link(:text, 'Another action').wait_while_present 28 | 29 | sleep 2 30 | b.close 31 | -------------------------------------------------------------------------------- /18/modal.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | import selenium.webdriver.support.ui as ui 6 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 7 | 8 | dr = webdriver.Chrome() 9 | file_path = 'file:///' + os.path.abspath('modal.html') 10 | 11 | dr.get(file_path) 12 | 13 | # 打开对话框 14 | dr.find_element_by_id('show_modal').click() 15 | 16 | wait = ui.WebDriverWait(dr, 10) 17 | wait.until(lambda dr: dr.find_element_by_id('myModal').is_displayed()) 18 | 19 | # 点击对话框中的链接 20 | # 由于对话框中的元素被蒙板所遮挡,直接点击会报 Element is not clickable的错误 21 | # 所以使用js来模拟click 22 | # 在watir-webdriver中只需要fire_event(:click)就可以了 23 | link = dr.find_element_by_id('myModal').find_element_by_id('click') 24 | dr.execute_script('$(arguments[0]).click()', link) 25 | sleep(2) 26 | 27 | # 关闭对话框 28 | buttons = dr.find_element_by_class_name('modal-footer').find_elements_by_tag_name('button') 29 | buttons[0].click() 30 | 31 | dr.quit() 32 | 33 | -------------------------------------------------------------------------------- /23/js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | js 5 | 6 | 7 | 12 | 13 | 14 | 15 |

js

16 |
17 |
18 | hover to see tooltip 19 | Button 20 |
21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /19/Attribute.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.util.List; 3 | 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | 9 | 10 | public class Attribute { 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | WebDriver dr = new ChromeDriver(); 14 | 15 | File file = new File("src/attribute.html"); 16 | String filePath = "file:///" + file.getAbsolutePath(); 17 | System.out.printf("now accesss %s \n", filePath); 18 | 19 | dr.get(filePath); 20 | Thread.sleep(1000); 21 | 22 | WebElement link = dr.findElement(By.id("tooltip")); 23 | 24 | // 获得tooltip的内容 25 | System.out.println(link.getAttribute("data-original-title")); 26 | 27 | // 获取该链接的text 28 | System.out.println(link.getText()); 29 | 30 | Thread.sleep(1000); 31 | System.out.println("browser will be close"); 32 | dr.quit(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /21/status.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from selenium import webdriver 3 | from time import sleep 4 | import os 5 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 6 | 7 | dr = webdriver.Chrome() 8 | file_path = 'file:///' + os.path.abspath('status.html') 9 | dr.get(file_path) 10 | 11 | text_field = dr.find_element_by_name('user') 12 | print text_field.is_enabled() 13 | 14 | # 直接用enabled?方法去判断该button的话返回的会是true 15 | # 这是因为button是使用css方法去disabled的,并不是真正的disable 16 | # 这时候需要判断其class里是否有disabled这值来判断其是否处于disable状态 17 | print dr.find_element_by_class_name('btn').is_enabled() 18 | 19 | # 隐藏掉text_field 20 | # 判断其是否显示 21 | dr.execute_script('$(arguments[0]).hide()', text_field) 22 | print text_field.is_displayed() 23 | 24 | # 使用click方法选择raido 25 | radio = dr.find_element_by_name('radio') 26 | radio.click() 27 | print radio.is_selected() 28 | 29 | # 判断元素是否存在 30 | try: 31 | dr.find_element_by_id('none') 32 | except: 33 | print 'element does not exist' 34 | 35 | dr.quit() 36 | 37 | -------------------------------------------------------------------------------- /30/timeout.md: -------------------------------------------------------------------------------- 1 | 超时设置 2 | ========= 3 | 4 | 场景 5 | ---- 6 | webdriver中可以设置很多的超时时间 7 | 8 | * implicit_wait。识别对象时的超时时间。过了这个时间如果对象还没找到的话就会抛出NoSuchElement异常 9 | * script_timeout。异步脚本的超时时间。webdriver可以异步执行脚本,这个是设置异步执行脚本脚本返回结果的超时时间 10 | * page_load。页面加载时的超时时间。因为webdriver会等页面加载完毕在进行后面的操作,所以如果页面在这个超时时间内没有加载完成,那么webdriver就会抛出异常 11 | 12 | 代码 13 | ---- 14 | 15 | ``` 16 | driver = Selenium::WebDriver.for :chrome 17 | # 定位对象时给3s的时间 18 | # 如果3s内还定位不到则抛出异常 19 | driver.manage.timeouts.implicit_wait = 3 # seconds 20 | 21 | # 页面加载超时时间设置为5s 22 | driver.manage.page_load = 5 #seconds 23 | 24 | # 异步脚本的超时时间设置成3s 25 | driver.manage.script_timeout = 3 #seconds 26 | 27 | ``` 28 | 29 | 讨论 30 | ---- 31 | 由于webdriver是通过给driver发送http请求来进行每步操作的,因此就可以设置http请求的超时时间。默认ruby binding的http client超时时间是60s,你可以通过下面的代码来改变这一设置。 32 | 33 | ``` 34 | client = Selenium::WebDriver::Remote::Http::Default.new 35 | client.timeout = 120 # seconds 36 | driver = Selenium::WebDriver.for(:chrome, :http_client => client) 37 | ``` 38 | -------------------------------------------------------------------------------- /06/title_and_url.py.md: -------------------------------------------------------------------------------- 1 | 打印当前页面的title及url 2 | ======================== 3 | 4 | 情景 5 | ---- 6 | 测试中,访问1个页面然后判断其title是否符合预期是很常见的1个用例,所谓用例不够,title来凑就是这个道理。更具体一点,假设1个页面的title应该是'hello world', 那么可以写这样的一个用例:访问该页面,获取该页面的title,判断获取的值是否等于'hello world'。 7 | 8 | 获取当前页面的url也是非常重要的一个操作。在某些情况下,你访问一个url,这时系统会自动对这个url进行跳转,这就是所谓的'重定向'。一般测试重定向的方法是访问这个url,然后等待页面重定向完毕之后,获取当前页面的url,判断该url是否符合预期。另外的一个常见的测试场景是提交了一个表单,如果表单内容通过了验证,那么则会跳转到一个新页面,如果未通过验证,则会停留在当前页面,此时获取当前页面的url则可以帮助我们判断表单提交的跳转是否符合预期。更具体一点,假如你在测试一个登陆页面,输入正确的登陆信息后,会跳转到系统首页。获取跳转后的url然后判断其是否与系统首页的url相符将是一个很不错的用例。 9 | 10 | 代码 11 | ---- 12 | ```python 13 | # -*- coding: utf-8 -*- 14 | from selenium import webdriver 15 | from time import sleep 16 | import os 17 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 18 | 19 | dr = webdriver.Chrome() 20 | url = 'http://www.baidu.com' 21 | dr.get(url) 22 | 23 | print "title of current page is %s" %(dr.title) 24 | print "url of current page is %s" %(dr.current_url) 25 | 26 | sleep(1) 27 | 28 | dr.quit() 29 | 30 | ``` 31 | -------------------------------------------------------------------------------- /12/send_keys.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | send keys 5 | 6 | 7 | 8 | 9 |

send keys

10 |
11 |
12 |
13 | 14 | 15 |
16 |
17 |
18 |
19 | 20 | 21 |
22 |
23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /32/cookie.md: -------------------------------------------------------------------------------- 1 | cookie 2 | ====== 3 | 4 | 场景 5 | ----- 6 | webdriver可以读取并添加cookie。有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie的测试是无法通过白盒和集成测试完成的。 7 | 8 | 另外更加常见的一个场景是自动登陆。有很多系统的登陆信息都是保存在cookie里的,因此只要往cookie中添加正确的值就可以实现自动登陆了。什么图片验证码、登陆的用例就都是浮云了。 9 | 10 | webdriver读写cookie的接口有以下一些 11 | 12 | * add_cookie。添加cookie,必须有name, value这2个key 13 | * delete_all_cookies。删除所有cookie 14 | * all_cookies。返回所有的cookie 15 | * delete_cookie(name)。删除name这个cookie 16 | * cookie_named。返回特定name的cookie值 17 | 18 | 19 | 代码 20 | ---- 21 | 下面的代码演示了如何自动登陆百度。其中敏感信息我使用了xxxx来代替。 22 | ### cookie.rb 23 | ``` 24 | #encoding: utf-8 25 | require 'selenium-webdriver' 26 | 27 | dr = Selenium::WebDriver.for :chrome 28 | url = 'http://www.baidu.com' 29 | dr.get url 30 | 31 | p dr.manage.all_cookies 32 | dr.manage.delete_all_cookies 33 | dr.manage.add_cookie(name: 'BAIDUID', value: 'xxxxxx') 34 | dr.manage.add_cookie(name: 'BDUSS', value: 'xxxxxx') 35 | 36 | # 重新访问该页面就可以发现已经登陆了 37 | # 当然也可以刷新该页面 38 | dr.get url 39 | 40 | sleep(3) 41 | dr.quit() 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /35/select.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Select 5 | 6 | 7 | 8 | 9 | 10 |
11 |

Select

12 |
13 |
14 |
15 | 16 | 23 |
24 | 25 |
26 |
27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /21/status.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | status 5 | 6 | 7 | 12 | 13 | 14 | 15 |

status

16 |
17 |
18 | 19 |
20 |
21 | Disabled Button 22 |
23 |
24 | 25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /25/wait.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | wait 5 | 6 | 7 | 15 | 16 | 17 | 18 |
19 |
20 |

wait

21 | 22 |
23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /11/OperateElement.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | 8 | 9 | public class OperateElement { 10 | 11 | public static void main(String[] args) throws InterruptedException { 12 | WebDriver dr = new ChromeDriver(); 13 | 14 | File file = new File("src/operate_element.html"); 15 | String filePath = "file:///" + file.getAbsolutePath(); 16 | System.out.printf("now accesss %s \n", filePath); 17 | 18 | dr.get(filePath); 19 | Thread.sleep(1000); 20 | 21 | // click 22 | dr.findElement(By.linkText("Link1")).click(); 23 | Thread.sleep(1000); 24 | dr.findElement(By.linkText("Link1")).click(); 25 | 26 | // send_keys 27 | WebElement element = dr.findElement(By.name("q")); 28 | element.sendKeys("something"); 29 | Thread.sleep(1000); 30 | 31 | // clear 32 | element.clear(); 33 | 34 | Thread.sleep(1000); 35 | System.out.println("browser will be close"); 36 | dr.quit(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /24/alert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | alert 5 | 6 | 7 | 15 | 16 | 17 | 18 |
19 |
20 |

alert

21 | hover to see tooltip 22 |
23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /13/button_group.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | button group 5 | 6 | 7 | 14 | 15 | 16 |

button group

17 |
18 |
19 |
20 |
21 |
22 |
first
23 |
second
24 |
third
25 |
26 |
27 |
28 |
29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /15/navs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Navs 5 | 6 | 7 | 17 | 18 | 19 |

Navs

20 |
21 |
22 | 29 |
30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /07/forword_and_back.java.md: -------------------------------------------------------------------------------- 1 | 前进和后退 2 | =========== 3 | 4 | 场景 5 | ---- 6 | 说实话,这两个功能一般不太常用。所能想到的场景大概也就是在几个页面间来回跳转,省去每次都get url。 7 | 8 | 代码 9 | ---- 10 | 11 | ``` 12 | import org.openqa.selenium.WebDriver; 13 | import org.openqa.selenium.chrome.ChromeDriver; 14 | 15 | 16 | public class ForwardAndBack { 17 | 18 | public static void main(String[] args) throws InterruptedException { 19 | WebDriver dr = new ChromeDriver(); 20 | Thread.sleep(2000); 21 | 22 | String firstUrl = "http://www.baidu.com"; 23 | System.out.printf("now accesss %s \n", firstUrl); 24 | dr.get(firstUrl); 25 | Thread.sleep(1000); 26 | 27 | String secondUrl = "http://www.soso.com"; 28 | System.out.printf("now accesss %s \n", secondUrl); 29 | dr.get(secondUrl); 30 | Thread.sleep(1000); 31 | 32 | System.out.printf("now back to %s \n", firstUrl); 33 | dr.navigate().back(); 34 | Thread.sleep(1000); 35 | 36 | System.out.printf("forward to %s \n", secondUrl); 37 | dr.navigate().forward(); 38 | Thread.sleep(1000); 39 | 40 | System.out.println("browser will be close"); 41 | dr.quit(); 42 | } 43 | 44 | } 45 | 46 | ``` 47 | -------------------------------------------------------------------------------- /08/simple_locate.rb: -------------------------------------------------------------------------------- 1 | require 'selenium-webdriver' 2 | 3 | dr = Selenium::WebDriver.for :chrome 4 | file_path = 'file:///' + File.expand_path(File.join('.', 'form.html')) 5 | puts file_path 6 | dr.get file_path 7 | 8 | # by id 9 | dr.find_element(:id, 'inputEmail').click 10 | 11 | # by name 12 | dr.find_element(:name, 'password').click 13 | 14 | # by tagname 15 | puts dr.find_element(:tag_name, 'form')[:class] 16 | 17 | # by class_name 18 | e = dr.find_element(:class, 'controls') 19 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', e) 20 | sleep 1 21 | 22 | # by link text 23 | link = dr.find_element(:link_text, 'register') 24 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', link) 25 | sleep 1 26 | 27 | # by partial link text 28 | link = dr.find_element(:partial_link_text, 'reg') 29 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', link) 30 | sleep 1 31 | 32 | # by css selector 33 | div = dr.find_element(:css, '.controls') 34 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', div) 35 | sleep 1 36 | 37 | # by xpath 38 | dr.find_element(:xpath, '/html/body/form/div[3]/div/label/input').click 39 | 40 | sleep 2 41 | dr.quit 42 | 43 | -------------------------------------------------------------------------------- /12/SendKeys.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.Keys; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | 8 | 9 | public class SendKeys { 10 | 11 | public static void main(String[] args) throws InterruptedException { 12 | WebDriver dr = new ChromeDriver(); 13 | 14 | File file = new File("src/send_keys.html"); 15 | String filePath = "file:///" + file.getAbsolutePath(); 16 | System.out.printf("now accesss %s \n", filePath); 17 | 18 | dr.get(filePath); 19 | Thread.sleep(1000); 20 | 21 | // copy content of A 22 | dr.findElement(By.id("A")).sendKeys(Keys.chord(Keys.CONTROL + "a")); 23 | Thread.sleep(1000); 24 | dr.findElement(By.id("A")).sendKeys(Keys.chord(Keys.CONTROL + "x")); 25 | 26 | // paste to B 27 | dr.findElement(By.id("B")).sendKeys(Keys.chord(Keys.CONTROL + "v")); 28 | 29 | // SendKeys to A 30 | dr.findElement(By.id("A")).sendKeys(Keys.chord("watir webdriver is better than selenium webdriver")); 31 | 32 | Thread.sleep(1000); 33 | System.out.println("browser will be close"); 34 | dr.quit(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /00/init.py.md: -------------------------------------------------------------------------------- 1 | 安装python及webdriver的开发环境 2 | ============================== 3 | 4 | 场景 5 | ---- 6 | 工欲善其事必先利其器,搭建开发环境对于初学者来说往往是非常困难和无从下手的。因此这里有必要叙述一下python及webdriver开发环境的搭建方法。 7 | 8 | 安装视频 9 | ------- 10 | 如果你对下面的文字不感兴趣,或者你对所有文字都不感兴趣,那么推荐你观看[这个视频](http://v.youku.com/v_show/id_XNjQ1MDI5Nzc2.html) 11 | 12 | 安装步骤 13 | ------- 14 | 15 | 首先感谢[active-python](http://www.activestate.com/activepython/) 16 | 17 | 只需要2步就可以安装完毕。 18 | 19 | **安装[active-python](http://www.activestate.com/activepython/)** 20 | 21 | 从[这里](http://www.activestate.com/activepython/downloads)下载active python2.7.5的windows安装版本,注意,如果是64位系统,则需要选择(64-bit, x64)版本下载。 22 | 23 | 双击打开下载的文件,直接下一步安装既可,很简单,什么都不需要更改。 24 | 25 | *注意,如果你的机器安装了360等专坑小白伪杀毒工具的话,请关闭360再进行安装。* 26 | 27 | **安装selenium webdriver** 28 | 29 | 打开命令行cmd,输入下面的命令 30 | 31 | pip install selenium 32 | 33 | 回车后,你会看到下面的提示 34 | 35 | Downloading/unpacking selenium 36 | Downloading selenium-2.38.1.tar.gz (2.5MB): 2.5MB downloaded 37 | Running setup.py egg_info for package selenium 38 | 39 | Installing collected packages: selenium 40 | Running setup.py install for selenium 41 | 42 | Successfully installed selenium 43 | Cleaning up... 44 | 45 | 现在大功告成,python的webdriver之旅即将展开。 46 | -------------------------------------------------------------------------------- /17/Pagination.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.util.List; 3 | 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | 9 | 10 | public class Pagination { 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | WebDriver dr = new ChromeDriver(); 14 | 15 | File file = new File("src/pagination.html"); 16 | String filePath = "file:///" + file.getAbsolutePath(); 17 | System.out.printf("now accesss %s \n", filePath); 18 | 19 | dr.get(filePath); 20 | Thread.sleep(1000); 21 | 22 | // 获得所有分页的数量 23 | // -2是因为要去掉上一个和下一个 24 | int total_pages = dr.findElement(By.className("pagination")).findElements(By.tagName("li")).size() - 2; 25 | System.out.printf("Total page is %d\n", total_pages); 26 | 27 | // 取当前页面的url以及当前页面是第几页 28 | WebElement current_page = dr.findElement(By.className("pagination")).findElement(By.className("active")); 29 | System.out.printf("Current page is %s\n", current_page.getText()); 30 | 31 | Thread.sleep(1000); 32 | System.out.println("browser will be close"); 33 | dr.quit(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /16/Breadcrumb.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.util.List; 3 | 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | 9 | 10 | public class Breadcrumb { 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | WebDriver dr = new ChromeDriver(); 14 | 15 | File file = new File("src/breadcrumb.html"); 16 | String filePath = "file:///" + file.getAbsolutePath(); 17 | System.out.printf("now accesss %s \n", filePath); 18 | 19 | dr.get(filePath); 20 | Thread.sleep(1000); 21 | 22 | // 获得其父层级 23 | List ancestors = dr.findElement(By.className("breadcrumb")).findElements(By.tagName("a")); 24 | for(WebElement link : ancestors){ 25 | System.out.println(link.getText()); 26 | } 27 | 28 | // 获取当前层级 29 | // 由于页面上可能有很多class为active的元素 30 | // 所以使用层级定位最为保险 31 | WebElement current = dr.findElement(By.className("breadcrumb")).findElement(By.className("active")); 32 | System.out.println(current.getText()); 33 | 34 | Thread.sleep(1000); 35 | System.out.println("browser will be close"); 36 | dr.quit(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /08/simple_locate.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from time import sleep 3 | import os 4 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 5 | 6 | dr = webdriver.Chrome() 7 | file_path = 'file:///' + os.path.abspath('form.html') 8 | print file_path 9 | 10 | dr.get(file_path) 11 | 12 | # by id 13 | dr.find_element_by_id('inputEmail').click() 14 | 15 | # by name 16 | dr.find_element_by_name('password').click() 17 | 18 | # by tagname 19 | print dr.find_element_by_tag_name('form').get_attribute('class') 20 | 21 | # by class_name 22 | e = dr.find_element_by_class_name('controls') 23 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', e) 24 | sleep(1) 25 | 26 | # by link text 27 | link = dr.find_element_by_link_text('register') 28 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', link) 29 | sleep(1) 30 | 31 | # by partial link text 32 | link = dr.find_element_by_partial_link_text('reg') 33 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', link) 34 | sleep(1) 35 | 36 | # by css selector 37 | div = dr.find_element_by_css_selector('.controls') 38 | dr.execute_script('$(arguments[0]).fadeOut().fadeIn()', div) 39 | sleep(1) 40 | 41 | # by xpath 42 | dr.find_element_by_xpath('/html/body/form/div[3]/div/label/input').click() 43 | 44 | sleep(2) 45 | dr.quit() 46 | 47 | -------------------------------------------------------------------------------- /06/title_and_url.java.md: -------------------------------------------------------------------------------- 1 | 打印当前页面的title及url 2 | ======================== 3 | 4 | 情景 5 | ---- 6 | 测试中,访问1个页面然后判断其title是否符合预期是很常见的1个用例,所谓用例不够,title来凑就是这个道理。更具体一点,假设1个页面的title应该是'hello world', 那么可以写这样的一个用例:访问该页面,获取该页面的title,判断获取的值是否等于'hello world'。 7 | 8 | 获取当前页面的url也是非常重要的一个操作。在某些情况下,你访问一个url,这时系统会自动对这个url进行跳转,这就是所谓的'重定向'。一般测试重定向的方法是访问这个url,然后等待页面重定向完毕之后,获取当前页面的url,判断该url是否符合预期。另外的一个常见的测试场景是提交了一个表单,如果表单内容通过了验证,那么则会跳转到一个新页面,如果未通过验证,则会停留在当前页面,此时获取当前页面的url则可以帮助我们判断表单提交的跳转是否符合预期。更具体一点,假如你在测试一个登陆页面,输入正确的登陆信息后,会跳转到系统首页。获取跳转后的url然后判断其是否与系统首页的url相符将是一个很不错的用例。 9 | 10 | 代码 11 | ---- 12 | ``` 13 | import org.openqa.selenium.WebDriver; 14 | import org.openqa.selenium.chrome.ChromeDriver; 15 | 16 | 17 | public class TitleAndUrl { 18 | 19 | public static void main(String[] args) throws InterruptedException { 20 | WebDriver dr = new ChromeDriver(); 21 | Thread.sleep(2000); 22 | 23 | String url = "http://www.baidu.com"; 24 | System.out.printf("now accesss %s \n", url); 25 | 26 | dr.get(url); 27 | Thread.sleep(2000); 28 | 29 | System.out.printf("title of current page is %s\n", dr.getTitle()); 30 | System.out.printf("url of current page is %s\n", dr.getCurrentUrl()); 31 | 32 | System.out.println("browser will be close"); 33 | dr.quit(); 34 | } 35 | 36 | } 37 | 38 | ``` 39 | -------------------------------------------------------------------------------- /17/pagination.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pagination 5 | 6 | 7 | 15 | 16 | 17 | 18 |

Pagination

19 |
20 |
21 | 32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /10/LevelLocate.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.openqa.selenium.interactions.Actions; 8 | import org.openqa.selenium.support.ui.ExpectedCondition; 9 | import org.openqa.selenium.support.ui.WebDriverWait; 10 | 11 | 12 | public class LevelLocate { 13 | 14 | public static void main(String[] args) throws InterruptedException { 15 | WebDriver dr = new ChromeDriver(); 16 | 17 | File file = new File("src/level_locate.html"); 18 | String filePath = "file:///" + file.getAbsolutePath(); 19 | System.out.printf("now accesss %s \n", filePath); 20 | 21 | dr.get(filePath); 22 | Thread.sleep(1000); 23 | 24 | dr.findElement(By.linkText("Link1")).click(); 25 | 26 | (new WebDriverWait(dr, 10)).until(new ExpectedCondition(){ 27 | public Boolean apply(WebDriver d){ 28 | return d.findElement(By.id("dropdown1")).isDisplayed(); 29 | } 30 | } ); 31 | 32 | WebElement menu = dr.findElement(By.id("dropdown1")).findElement(By.linkText("Another action")); 33 | (new Actions(dr)).moveToElement(menu).perform(); 34 | 35 | Thread.sleep(1000); 36 | System.out.println("browser will be close"); 37 | dr.quit(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /14/button_dropdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | button dropdown 5 | 6 | 7 | 14 | 15 | 16 |

button dropdown

17 |
18 |
19 |
20 | 31 |
32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /08/form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Form 5 | 6 | 7 | 8 | 9 | 10 |

simple login form

11 |
12 |
13 | 14 |
15 | 16 |
17 |
18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 29 | 30 | register 31 |
32 |
33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /to_pdf/to_pdf.rb: -------------------------------------------------------------------------------- 1 | #encoding: utf-8 2 | #require 'pdfkit' 3 | =begin 4 | PDFKit.configure do |config| 5 | # config.wkhtmltopdf = 'D:\wkhtmltopdf\wkhtmltopdf.exe' 6 | config.default_options = { 7 | # :page_size => 'Letter', 8 | :print_media_type => true, 9 | :no_background => true, 10 | :encoding => 'utf-8', 11 | 12 | } 13 | # config.root_url = "http://localhost" # Use only if your external hostname is unavailable on the server. 14 | end 15 | =end 16 | md = File.join('..', '**', '*.md') 17 | #md = File.join('..', '**', '*.java.md') 18 | #md = File.join('..', '**', '*.py.md') 19 | md_files = Dir.glob(md) 20 | 21 | #all_in_one = 'webdriver_java.md' 22 | all_in_one = 'webdriver_ruby.md' 23 | #all_in_one = 'webdriver_python.md' 24 | 25 | md_files.each_with_index do |md, index| 26 | File.open(all_in_one, 'a+') do |handle| 27 | File.open(md, 'r') do |f| 28 | if index != 0 29 | handle.puts '' 30 | handle.write('-' * 20) 31 | handle.puts '' 32 | end #if 33 | handle.write(f.read) 34 | end #File.open 35 | end 36 | end 37 | #all_in_one_html = 'all_in_one.html' 38 | #all_in_one_html = 'all_in_one.java.html' 39 | 40 | #system("mdt #{all_in_one} >> #{all_in_one_html}") 41 | 42 | =begin 43 | html = File.open(all_in_one_html, 'r') { |f| f.read } 44 | kit = PDFKit.new(html) 45 | kit.stylesheets << './style.css' 46 | kit.to_file('book.pdf') 47 | File.delete(all_in_one) 48 | File.delete(all_in_one_html) 49 | =end 50 | -------------------------------------------------------------------------------- /28/upload_file.md: -------------------------------------------------------------------------------- 1 | 上传文件 2 | ======== 3 | 4 | 场景 5 | ---- 6 | 上传文件的方法是找到上传文件的对象,通常是的对象。然后直接往这个对象send_keys,传入需要上传文件的正确路径。绝对路径和相对路径都可以,但是上传的文件必须存在,否则会报错。 7 | 8 | 代码 9 | ---- 10 | 11 | ### upload_file.html 12 | ``` 13 | 14 | 15 | 16 | upload_file 17 | 18 | 19 | 21 | 22 | 23 | 24 |
25 |
26 |

upload_file

27 | 28 |
29 |
30 | 31 | 32 | 33 | ``` 34 | 35 | ### upload_file.rb 36 | ``` 37 | #encoding: utf-8 38 | require 'selenium-webdriver' 39 | 40 | dr = Selenium::WebDriver.for :chrome 41 | file_path = 'file:///' + File.expand_path(File.join('.', 'upload_file.html')) 42 | dr.get file_path 43 | 44 | dr.find_element(name: 'file').send_keys('./upload_file.md') 45 | 46 | sleep(2) 47 | dr.quit() 48 | 49 | ``` 50 | -------------------------------------------------------------------------------- /09/checkbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Checkbox 5 | 6 | 7 | 8 | 9 | 10 |

checkbox

11 |
12 |
13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | 21 |
22 | 23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | 41 | -------------------------------------------------------------------------------- /22/form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | form 5 | 6 | 7 | 14 | 15 | 16 | 17 |

form

18 |
19 |
20 |
21 |
22 | Legend 23 | 26 | 27 | 30 | 31 | 38 | 39 | 40 |
41 |
42 |
43 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /09/SimpleLocate.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.util.List; 3 | 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.WebDriver; 6 | import org.openqa.selenium.WebElement; 7 | import org.openqa.selenium.chrome.ChromeDriver; 8 | import org.openqa.selenium.JavascriptExecutor; 9 | 10 | 11 | public class SimpleLocate { 12 | 13 | public static void main(String[] args) throws InterruptedException { 14 | WebDriver dr = new ChromeDriver(); 15 | 16 | File file = new File("src/checkbox.html"); 17 | String filePath = "file:///" + file.getAbsolutePath(); 18 | System.out.printf("now accesss %s \n", filePath); 19 | 20 | dr.get(filePath); 21 | Thread.sleep(1000); 22 | 23 | // 选择所有的checkbox并全部勾上 24 | List checkboxes = dr.findElements(By.cssSelector("input[type=checkbox]")); 25 | for(WebElement checkbox : checkboxes) { 26 | checkbox.click(); 27 | } 28 | dr.navigate().refresh(); 29 | 30 | // 打印当前页面上有多少个checkbox 31 | System.out.printf("%d\n", checkboxes.size()); 32 | 33 | // 选择页面上所有的input,然后从中过滤出所有的checkbox并勾选之 34 | List inputs = dr.findElements(By.tagName("input")); 35 | for(WebElement input : inputs){ 36 | if(input.getAttribute("type").equals("checkbox")){ 37 | input.click(); 38 | } 39 | } 40 | 41 | // 把页面上最后1个checkbox的勾给去掉 42 | List allCheckboxes = dr.findElements(By.cssSelector("input[type=checkbox]")); 43 | allCheckboxes.get(allCheckboxes.size() - 1).click(); 44 | 45 | Thread.sleep(1000); 46 | System.out.println("browser will be close"); 47 | dr.quit(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /28/upload_file.py.md: -------------------------------------------------------------------------------- 1 | 上传文件 2 | ======== 3 | 4 | 场景 5 | ---- 6 | 上传文件的方法是找到上传文件的对象,通常是的对象。然后直接往这个对象send_keys,传入需要上传文件的正确路径。绝对路径和相对路径都可以,但是上传的文件必须存在,否则会报错。 7 | 8 | 代码 9 | ---- 10 | 11 | ### upload_file.html 12 | ``` 13 | 14 | 15 | 16 | upload_file 17 | 18 | 19 | 21 | 22 | 23 | 24 |
25 |
26 |

upload_file

27 | 28 |
29 |
30 | 31 | 32 | 33 | ``` 34 | 35 | ### upload_file.py 36 | ``` 37 | # -*- coding: utf-8 -*- 38 | from selenium import webdriver 39 | from selenium.webdriver.common.keys import Keys 40 | from time import sleep 41 | import os 42 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 43 | 44 | dr = webdriver.Chrome() 45 | file_path = 'file:///' + os.path.abspath('upload_file.html') 46 | 47 | dr.get(file_path) 48 | 49 | dr.find_element_by_name('file').send_keys('./upload_file.md') 50 | 51 | sleep(2) 52 | dr.quit() 53 | ``` 54 | -------------------------------------------------------------------------------- /32/cookie.java.md: -------------------------------------------------------------------------------- 1 | cookie 2 | ====== 3 | 4 | 场景 5 | ----- 6 | webdriver可以读取并添加cookie。有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie的测试是无法通过白盒和集成测试完成的。 7 | 8 | 另外更加常见的一个场景是自动登陆。有很多系统的登陆信息都是保存在cookie里的,因此只要往cookie中添加正确的值就可以实现自动登陆了。什么图片验证码、登陆的用例就都是浮云了。 9 | 10 | webdriver读写cookie的接口有以下一些 11 | 12 | * addCookie(Cookie cookie)。添加cookie,参数是Cookie对象 13 | * deleteAllCookies。删除所有cookie 14 | * getCookies。返回所有的cookie 15 | * deleteCookieNamed(String name)。删除name这个cookie 16 | * getCookieNamed(String name)。返回特定name的cookie值 17 | 18 | 19 | 代码 20 | ---- 21 | 下面的代码演示了如何自动登陆百度。其中敏感信息我使用了xxxx来代替。 22 | ### cookie.java 23 | 24 | ``` 25 | import org.openqa.selenium.Cookie; 26 | import org.openqa.selenium.WebDriver; 27 | import org.openqa.selenium.chrome.ChromeDriver; 28 | 29 | 30 | public class CookieExample { 31 | 32 | public static void main(String[] args) throws InterruptedException { 33 | WebDriver dr = new ChromeDriver(); 34 | 35 | String url = "http://www.baidu.com"; 36 | System.out.printf("now accesss %s \n", url); 37 | 38 | dr.get(url); 39 | Thread.sleep(2000); 40 | 41 | System.out.println(dr.manage().getCookies()); 42 | 43 | dr.manage().deleteAllCookies(); 44 | 45 | Cookie c1 = new Cookie("BAIDUID", "xxxxxxxxxx"); 46 | Cookie c2 = new Cookie("BDUSS", "xxxxxxxxxx"); 47 | dr.manage().addCookie(c1); 48 | dr.manage().addCookie(c2); 49 | 50 | System.out.println("browser will be close"); 51 | 52 | dr.quit();quit} 53 | 54 | } 55 | 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /21/Status.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.util.List; 3 | 4 | import org.openqa.selenium.By; 5 | import org.openqa.selenium.JavascriptExecutor; 6 | import org.openqa.selenium.NoSuchElementException; 7 | import org.openqa.selenium.WebDriver; 8 | import org.openqa.selenium.WebElement; 9 | import org.openqa.selenium.chrome.ChromeDriver; 10 | 11 | 12 | public class Status { 13 | 14 | public static void main(String[] args) throws InterruptedException { 15 | WebDriver dr = new ChromeDriver(); 16 | 17 | File file = new File("src/status.html"); 18 | String filePath = "file:///" + file.getAbsolutePath(); 19 | System.out.printf("now accesss %s \n", filePath); 20 | 21 | dr.get(filePath); 22 | Thread.sleep(1000); 23 | 24 | WebElement textField = dr.findElement(By.name("user")); 25 | System.out.println(textField.isEnabled()); 26 | 27 | // 直接用isEnabled方法去判断该button的话返回的会是true 28 | // 这是因为button是使用css方法去disabled的,并不是真正的disable 29 | // 这时候需要判断其class里是否有disabled这值来判断其是否处于disable状态 30 | System.out.println(dr.findElement(By.className("btn")).isEnabled()); 31 | 32 | // 隐藏掉textField 33 | // 判断其是否显示 34 | ((JavascriptExecutor)dr).executeScript("$(arguments[0]).hide()", textField); 35 | System.out.println(textField.isDisplayed()); 36 | 37 | // 使用click方法选择raido 38 | WebElement radio = dr.findElement(By.name("radio")); 39 | radio.click(); 40 | System.out.println(radio.isSelected()); 41 | 42 | try{ 43 | dr.findElement(By.id("none")); 44 | } catch(NoSuchElementException e){ 45 | System.out.println("element does not exist"); 46 | } 47 | 48 | Thread.sleep(1000); 49 | System.out.println("browser will be close"); 50 | dr.quit(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /20/css.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的css属性 2 | ===================== 3 | 4 | 场景 5 | ---- 6 | 当你的测试用例纠结细枝末节的时候,你就需要通过判断元素的css属性来验证你的操作是否达到了预期的效果。比如你可以通过判断页面上的标题字号以字体来验证页面的显示是否符合预期。当然,这个是强烈不推荐的。因为页面上最不稳定的就是css了,css变动频繁,而且通过属性也不能直观的判断页面的显示效果,还不如让人为的去看一眼,大问题一望即知。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何获取测试对象的css属性。 11 | 12 | ### css.html 13 | ``` 14 | 15 | 16 | 17 | attribute 18 | 19 | 20 | 25 | 26 | 27 | 28 |

attribute

29 |
30 | 33 |
34 | 35 | 36 | 37 | ``` 38 | 39 | ### css.rb 40 | ``` 41 | #encoding: utf-8 42 | require 'selenium-webdriver' 43 | 44 | dr = Selenium::WebDriver.for :chrome 45 | file_path = 'file:///' + File.expand_path(File.join('.', 'css.html')) 46 | dr.get file_path 47 | 48 | link = dr.find_element(id: 'tooltip') 49 | puts link.css_value(:color) 50 | 51 | puts dr.find_element(:tag_name, 'h3').css_value('font') 52 | 53 | dr.quit() 54 | 55 | ``` 56 | 57 | -------------------------------------------------------------------------------- /18/modal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | modal 5 | 6 | 7 | 14 | 15 | 16 | 17 |

modal

18 |
19 |
20 | 21 | Click 22 | 23 | 24 | 38 |
39 |
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /10/level_locate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Level Locate 5 | 6 | 7 | 8 | 9 |

Level locate

10 |
11 |
12 | 22 |
23 |
24 |
25 |
26 | 36 |
37 |
38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /33/switch_window.py.md: -------------------------------------------------------------------------------- 1 | ## 切换窗口 2 | 3 | ### 场景 4 | 5 | 切换窗口的场景其实很普遍,当你点击了一个链接之后有可能弹出一个新窗口,这时候如果你需要定位新窗口中的元素并进行操作,你就需要进行窗口切换的操作。 6 | 7 | ### 代码 8 | 9 | switch_window.html 10 | 11 | ```html 12 | 13 | 14 | Switch Window 15 | 16 | 17 | 18 |

This is main window

19 | Click to open sub window 20 | 21 | 22 | ``` 23 | 24 | sub_window.html 25 | 26 | ```html 27 | 28 | 29 | Sub Window 30 | 31 | 32 | 33 |

This is sub window

34 | 35 | 36 | ``` 37 | 38 | switch_window.py 39 | 40 | ```python 41 | 42 | # coding: utf-8 43 | 44 | from selenium import webdriver 45 | from time import sleep 46 | import os 47 | 48 | # I write this code on my MBP and I can not launch chrome using chrome driver 49 | # use firefox instead 50 | dr = webdriver.Firefox() 51 | file_path = 'file:///' + os.path.abspath('switch_window.html') 52 | 53 | dr.get(file_path) 54 | print dr.title 55 | print dr.find_element_by_tag_name('h3').text 56 | 57 | open_new_win_link = dr.find_element_by_id('open-new-window') 58 | open_new_win_link.click() 59 | 60 | # find all window handles 61 | all_handles = dr.window_handles 62 | 63 | # find handle of the other window 64 | the_other_handle = '' 65 | for h in all_handles: 66 | if h != dr.current_window_handle: the_other_handle = h 67 | 68 | #switch window 69 | if the_other_handle: 70 | dr.switch_to_window(the_other_handle) 71 | print dr.title 72 | print dr.find_element_by_tag_name('h3').text 73 | assert dr.title == 'Sub Window' 74 | 75 | dr.quit 76 | 77 | ``` 78 | 79 | ### 思考 80 | 81 | 切换到新打开窗口的思路实际上就是遍历所有的窗口句柄,如果不是当前窗口的话就切换到这个句柄所代表的窗口。 82 | 83 | 那么问题就来了,上面的代码其实有点问题,你能找到这个问题吗? 84 | -------------------------------------------------------------------------------- /15/navs.md: -------------------------------------------------------------------------------- 1 | 处理navs 2 | ========= 3 | 4 | 场景 5 | ---- 6 | navs可以看作是简单的类似于tab的导航栏。一般来说导航栏都是ul+li。先定位ul再去层级定位li中的link基本就能解决问题。 7 | 8 | 代码 9 | ---- 10 | ### navs.html 11 | ``` 12 | 13 | 14 | 15 | Navs 16 | 17 | 18 | 28 | 29 | 30 |

Navs

31 |
32 |
33 | 40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### navs.rb 48 | ``` 49 | #encoding: utf-8 50 | require 'selenium-webdriver' 51 | 52 | dr = Selenium::WebDriver.for :chrome 53 | file_path = 'file:///' + File.expand_path(File.join('.', 'navs.html')) 54 | dr.get file_path 55 | 56 | # 方法1:层级定位,先定位ul再定位li 57 | dr.find_element(:class, 'nav').find_element(:link_text, 'About').click() 58 | sleep(1) 59 | 60 | # 方法2: 直接定位link 61 | dr.find_element(:link_text, 'Home').click() 62 | 63 | dr.quit() 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /20/css.py.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的css属性 2 | ===================== 3 | 4 | 场景 5 | ---- 6 | 当你的测试用例纠结细枝末节的时候,你就需要通过判断元素的css属性来验证你的操作是否达到了预期的效果。比如你可以通过判断页面上的标题字号以字体来验证页面的显示是否符合预期。当然,这个是强烈不推荐的。因为页面上最不稳定的就是css了,css变动频繁,而且通过属性也不能直观的判断页面的显示效果,还不如让人为的去看一眼,大问题一望即知。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何获取测试对象的css属性。 11 | 12 | ### css.html 13 | ``` 14 | 15 | 16 | 17 | attribute 18 | 19 | 20 | 25 | 26 | 27 | 28 |

attribute

29 |
30 | 33 |
34 | 35 | 36 | 37 | ``` 38 | 39 | ### css.py 40 | ``` 41 | # -*- coding: utf-8 -*- 42 | from selenium import webdriver 43 | from time import sleep 44 | import os 45 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 46 | 47 | dr = webdriver.Chrome() 48 | file_path = 'file:///' + os.path.abspath('css.html') 49 | 50 | dr.get(file_path) 51 | 52 | link = dr.find_element_by_id('tooltip') 53 | print link.value_of_css_property('color') 54 | 55 | print dr.find_element_by_tag_name('h3').value_of_css_property('font') 56 | 57 | dr.quit() 58 | 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /08/SimpleLocate.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | 3 | import org.openqa.selenium.By; 4 | import org.openqa.selenium.WebDriver; 5 | import org.openqa.selenium.WebElement; 6 | import org.openqa.selenium.chrome.ChromeDriver; 7 | import org.openqa.selenium.JavascriptExecutor; 8 | 9 | 10 | public class SimpleLocate { 11 | 12 | public static void main(String[] args) throws InterruptedException { 13 | WebDriver dr = new ChromeDriver(); 14 | 15 | File file = new File("src/form.html"); 16 | String filePath = "file:///" + file.getAbsolutePath(); 17 | System.out.printf("now accesss %s \n", filePath); 18 | 19 | dr.get(filePath); 20 | Thread.sleep(2000); 21 | 22 | // by id 23 | dr.findElement(By.id("inputEmail")).click(); 24 | Thread.sleep(1000); 25 | 26 | // by name 27 | dr.findElement(By.name("password")); 28 | Thread.sleep(1000); 29 | 30 | // by tagname 31 | String classOfForm = dr.findElement(By.tagName("form")).getAttribute("class"); 32 | System.out.printf("%s\n", classOfForm); 33 | Thread.sleep(1000); 34 | 35 | // by link text 36 | WebElement link = dr.findElement(By.linkText("register")); 37 | ((JavascriptExecutor)dr).executeScript("$(arguments[0]).fadeOut().fadeIn()", link); 38 | Thread.sleep(1000); 39 | 40 | // by partial link test 41 | WebElement sameLink = dr.findElement(By.partialLinkText("reg")); 42 | ((JavascriptExecutor)dr).executeScript("$(arguments[0]).fadeOut().fadeIn()", sameLink); 43 | Thread.sleep(1000); 44 | 45 | // by css selector 46 | WebElement div = dr.findElement(By.cssSelector(".controls")); 47 | ((JavascriptExecutor)dr).executeScript("$(arguments[0]).fadeOut().fadeIn()", div); 48 | Thread.sleep(1000); 49 | 50 | // by xpath 51 | dr.findElement(By.xpath("/html/body/form/div[3]/div/label/input")).click(); 52 | Thread.sleep(1000); 53 | 54 | System.out.println("browser will be close"); 55 | dr.quit(); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /16/breadcrumb.md: -------------------------------------------------------------------------------- 1 | 处理面包屑 2 | =========== 3 | 4 | 场景 5 | ---- 6 | 在实际的测试脚本中,有可能需要处理面包屑。处理面包屑主要是获取其层级关系,以及获得当前的层级。一般来说当前层级都不会是链接,而父层级则基本是以链接,所以处理面包屑的思路就很明显了。找到面包屑所在的div或ul,然后再通过该div或ul找到下面的所有链接,这些链接就是父层级。最后不是链接的部分就应该是当前层级了。 7 | 8 | 代码 9 | ---- 10 | ### breadcrumb.html 11 | ``` 12 | 13 | 14 | 15 | breadcrumb 16 | 17 | 18 | 25 | 26 | 27 |

breadcrumb

28 |
29 |
30 | 35 |
36 |
37 | 38 | 39 | 40 | 41 | ``` 42 | 43 | ### breadcrumb.rb 44 | ``` 45 | #encoding: utf-8 46 | require 'selenium-webdriver' 47 | 48 | dr = Selenium::WebDriver.for :chrome 49 | file_path = 'file:///' + File.expand_path(File.join('.', 'breadcrumb.html')) 50 | dr.get file_path 51 | 52 | # 获得其父层级 53 | anstors = dr.find_element(:class, 'breadcrumb').find_elements(:tag_name, 'a').map { |link| link.text } 54 | p anstors 55 | sleep(1) 56 | 57 | # 获取当前层级 58 | # 由于页面上可能有很多class为active的元素 59 | # 所以使用层级定位最为保险 60 | puts dr.find_element(:class, 'breadcrumb').find_element(:class, 'active').text 61 | 62 | dr.quit() 63 | 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /23/js.md: -------------------------------------------------------------------------------- 1 | 执行js 2 | ======= 3 | 4 | 场景 5 | ---- 6 | 如果你熟悉js的话,那么使用webdriver执行js就是一件很高效的事情了。在webdriver脚本中直接执行js的好处很多,这里就不一一枚举了。 7 | 8 | webdriver提供了execute_script()接口来帮助我们完成这一工作。在实际的测试脚本中,以下两种场景是经常遇到的 9 | 10 | * 在页面直接执行一段js 11 | * 在某个已经定位的元素的上执行js 12 | 13 | 代码 14 | ---- 15 | 下面的代码演示了如何在页面以及在已经定位的元素上执行js 16 | 17 | ### js.html 18 | ``` 19 | 20 | 21 | 22 | js 23 | 24 | 25 | 30 | 31 | 32 | 33 |

js

34 |
35 |
36 | hover to see tooltip 37 | Button 38 |
39 |
40 | 41 | 42 | 43 | 44 | ``` 45 | 46 | ### js.rb 47 | ``` 48 | #encoding: utf-8 49 | require 'selenium-webdriver' 50 | 51 | dr = Selenium::WebDriver.for :chrome 52 | file_path = 'file:///' + File.expand_path(File.join('.', 'js.html')) 53 | dr.get file_path 54 | 55 | # 在页面上直接执行js 56 | dr.execute_script('$("#tooltip").fadeOut();') 57 | sleep(1) 58 | 59 | # 在已经定位的元素上执行js 60 | button = dr.find_element(class: 'btn') 61 | dr.execute_script('$(arguments[0]).fadeOut()', button) 62 | sleep(1) 63 | 64 | dr.quit() 65 | 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /11/operate_element.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | operate element 5 | 6 | 7 | 8 | 9 |

operate element

10 |
11 |
12 |
13 | 23 |
24 |
25 |
26 |
27 | 37 |
38 |
39 |
40 |
41 |
42 | 43 |
44 |
45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /16/breadcrumb.py.md: -------------------------------------------------------------------------------- 1 | 处理面包屑 2 | =========== 3 | 4 | 场景 5 | ---- 6 | 在实际的测试脚本中,有可能需要处理面包屑。处理面包屑主要是获取其层级关系,以及获得当前的层级。一般来说当前层级都不会是链接,而父层级则基本是以链接,所以处理面包屑的思路就很明显了。找到面包屑所在的div或ul,然后再通过该div或ul找到下面的所有链接,这些链接就是父层级。最后不是链接的部分就应该是当前层级了。 7 | 8 | 代码 9 | ---- 10 | ### breadcrumb.html 11 | ``` 12 | 13 | 14 | 15 | breadcrumb 16 | 17 | 18 | 25 | 26 | 27 |

breadcrumb

28 |
29 |
30 | 35 |
36 |
37 | 38 | 39 | 40 | 41 | ``` 42 | 43 | ### breadcrumb.py 44 | ``` 45 | #coding=utf-8 46 | 47 | from selenium import webdriver 48 | from time import sleep 49 | import os 50 | 51 | 52 | dr = webdriver.Chrome() 53 | file_path = 'file:///' + os.path.abspath('breadcrumb.html') 54 | dr.get(file_path) 55 | 56 | #获得其父层级 57 | anstors = dr.find_element_by_class_name('breadcrumb').find_elements_by_tag_name('a') 58 | for ans in anstors: 59 | print(ans.text) 60 | 61 | sleep(1) 62 | 63 | # 获取当前层级 64 | # 由于页面上可能有很多class为active的元素 65 | # 所以使用层级定位最为保险 66 | 67 | print(dr.find_element_by_class_name('breadcrumb').find_element_by_class_name('active').text) 68 | 69 | dr.quit() 70 | 71 | ``` 72 | 73 | -------------------------------------------------------------------------------- /12/send_keys.md: -------------------------------------------------------------------------------- 1 | send keys模拟按键输入 2 | ========= 3 | 4 | 场景 5 | ---- 6 | send_keys方法可以模拟一些组合键操作,比如ctrl+a等。另外有时候我们需要在测试时使用tab键将焦点转移到下一个元素,这时候也需要send_keys。在某些更复杂的情况下,还会出现使用send_keys来模拟上下键来操作下拉列表的情况。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何将A多行文本框中的内容清空并复制到B文本框中。 11 | ### send_keys.html 12 | ``` 13 | 14 | 15 | 16 | send keys 17 | 18 | 19 | 20 | 21 |

send keys

22 |
23 |
24 |
25 | 26 | 27 |
28 |
29 |
30 |
31 | 32 | 33 |
34 |
35 |
36 | 37 | 38 | 39 | ``` 40 | 41 | ### send_keys.rb 42 | ``` 43 | #encoding: utf-8 44 | require 'selenium-webdriver' 45 | 46 | dr = Selenium::WebDriver.for :chrome 47 | file_path = 'file:///' + File.expand_path(File.join('.', 'send_keys.html')) 48 | dr.get file_path 49 | 50 | # copy content of A 51 | dr.find_element(:id, 'A').send_keys([:control, 'a']) 52 | dr.find_element(:id, 'A').send_keys([:control, 'x']) 53 | sleep(1) 54 | 55 | # paste to B 56 | dr.find_element(:id, 'B').send_keys([:control, 'v']) 57 | sleep(1) 58 | 59 | # send keys to A 60 | dr.find_element(:id, 'A').send_keys('watir', '-', 'webdriver', :space, 'is', :space, 'better') 61 | sleep(2) 62 | 63 | dr.quit() 64 | ``` 65 | 66 | 67 | -------------------------------------------------------------------------------- /15/navs.py.md: -------------------------------------------------------------------------------- 1 | 处理navs 2 | ========= 3 | 4 | 场景 5 | ---- 6 | navs可以看作是简单的类似于tab的导航栏。一般来说导航栏都是ul+li。先定位ul再去层级定位li中的link基本就能解决问题。 7 | 8 | 代码 9 | ---- 10 | ### navs.html 11 | ``` 12 | 13 | 14 | 15 | Navs 16 | 17 | 18 | 28 | 29 | 30 |

Navs

31 |
32 |
33 | 40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### navs.py 48 | ``` 49 | # -*- coding: utf-8 -*- 50 | from selenium import webdriver 51 | from selenium.webdriver.common.keys import Keys 52 | from time import sleep 53 | import os 54 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 55 | 56 | dr = webdriver.Chrome() 57 | file_path = 'file:///' + os.path.abspath('navs.html') 58 | 59 | dr.get(file_path) 60 | 61 | sleep(1) 62 | 63 | # 方法1:层级定位,先定位ul再定位li 64 | dr.find_element_by_class_name('nav').find_element_by_link_text('About').click() 65 | sleep(1) 66 | 67 | # 方法2: 直接定位link 68 | dr.find_element_by_link_text('Home').click() 69 | sleep(1) 70 | 71 | dr.quit() 72 | 73 | ``` 74 | 75 | -------------------------------------------------------------------------------- /19/attribute.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的属性及内容 2 | ======================== 3 | 4 | 场景 5 | ---- 6 | 获取测试对象的内容是前端自动化测试里一定会使用到的技术。比如我们要判断页面上是否显示了一个提示,那么我们就需要找到这个提示对象,然后获取其中的文字,再跟我们的预期进行比较。在webdriver中使用element.attribute()方法可以获取dom元素(测试对象)的属性。 7 | 8 | 获取测试对象的属性能够帮我们更好的进行对象的定位。比如页面上有很多class都是'btn'的div,而我们需要定位其中1个有具有title属性的div。由于selenium-webdriver是不支持直接使用title来定位对象的,所以我们只能先把所有class是btn的div都找到,然后遍历这些div,获取这些div的title属性,一旦发现具体title属性的div,那么返回这个div既可。在webdriver中,使用element.text()方法可以返回dom节点的内容(text)。 9 | 10 | 代码 11 | ---- 12 | 下面的代码演示了如何获取测试对象的title属性和该对象的文字内容 13 | 14 | ### attribute.html 15 | ``` 16 | 17 | 18 | 19 | attribute 20 | 21 | 22 | 27 | 28 | 29 | 30 |

attribute

31 |
32 | 35 |
36 | 37 | 38 | 39 | ``` 40 | 41 | ### attribute.rb 42 | ``` 43 | #encoding: utf-8 44 | require 'selenium-webdriver' 45 | 46 | dr = Selenium::WebDriver.for :chrome 47 | file_path = 'file:///' + File.expand_path(File.join('.', 'attribute.html')) 48 | dr.get file_path 49 | 50 | link = dr.find_element(id: 'tooltip') 51 | 52 | # 获得tooltip的内容 53 | puts link.attribute('data-original-title') 54 | 55 | # 获取该链接的text 56 | puts link.text() 57 | 58 | dr.quit() 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /23/js.py.md: -------------------------------------------------------------------------------- 1 | 执行js 2 | ======= 3 | 4 | 场景 5 | ---- 6 | 如果你熟悉js的话,那么使用webdriver执行js就是一件很高效的事情了。在webdriver脚本中直接执行js的好处很多,这里就不一一枚举了。 7 | 8 | webdriver提供了execute_script()接口来帮助我们完成这一工作。在实际的测试脚本中,以下两种场景是经常遇到的 9 | 10 | * 在页面直接执行一段js 11 | * 在某个已经定位的元素的上执行js 12 | 13 | 代码 14 | ---- 15 | 下面的代码演示了如何在页面以及在已经定位的元素上执行js 16 | 17 | ### js.html 18 | ``` 19 | 20 | 21 | 22 | js 23 | 24 | 25 | 30 | 31 | 32 | 33 |

js

34 |
35 |
36 | hover to see tooltip 37 | Button 38 |
39 |
40 | 41 | 42 | 43 | 44 | ``` 45 | 46 | ### js.python 47 | ``` 48 | # -*- coding: utf-8 -*- 49 | from selenium import webdriver 50 | from time import sleep 51 | import os 52 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 53 | 54 | dr = webdriver.Chrome() 55 | file_path = 'file:///' + os.path.abspath('js.html') 56 | dr.get(file_path) 57 | 58 | # 在页面上直接执行js 59 | dr.execute_script('$("#tooltip").fadeOut();') 60 | sleep(1) 61 | 62 | # 在已经定位的元素上执行js 63 | button = dr.find_element_by_class_name('btn') 64 | dr.execute_script('$(arguments[0]).fadeOut()', button) 65 | sleep(1) 66 | 67 | dr.quit() 68 | 69 | ``` 70 | 71 | -------------------------------------------------------------------------------- /13/button_group.md: -------------------------------------------------------------------------------- 1 | 处理button group 2 | ================== 3 | 4 | 场景 5 | ---- 6 | button group就是按钮组,将一组按钮排列在一起。处理这种对象的思路一般是先找到button group的包裹(wrapper)div,然后通过层级定位,用index或属性去定位更具体的按钮。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何找到second这个按钮。其处理方法是先找到button group的父div,class为btn-group的div,然后再找到下面所有的div(也就是button),返回text是second的div。 11 | ### button_group.html 12 | ``` 13 | 14 | 15 | 16 | button group 17 | 18 | 19 | 26 | 27 | 28 |

button group

29 |
30 |
31 |
32 |
33 |
34 |
first
35 |
second
36 |
third
37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### button_group.rb 48 | ``` 49 | #encoding: utf-8 50 | require 'selenium-webdriver' 51 | 52 | dr = Selenium::WebDriver.for :chrome 53 | file_path = 'file:///' + File.expand_path(File.join('.', 'button_group.html')) 54 | dr.get file_path 55 | 56 | # 定位text是second的按钮 57 | second_btn = dr.find_element(:class, 'btn-group').find_elements(:class, 'btn').detect {|btn| btn.text == 'second'} 58 | second_btn.click() 59 | sleep(2) 60 | 61 | dr.quit() 62 | ``` 63 | 64 | 讨论 65 | ---- 66 | 自己查资料搞清楚detect方法的作用。 67 | -------------------------------------------------------------------------------- /24/alert.md: -------------------------------------------------------------------------------- 1 | 处理alert/confirm/prompt 2 | ======================== 3 | 4 | 场景 5 | ---- 6 | webdriver中处理原生的js alert confirm 以及prompt是很简单的。具体思路是使用switch_to.alert()方法定位到alert/confirm/prompt。然后使用text/accept/dismiss/send_keys按需进行操做 7 | 8 | * text。返回alert/confirm/prompt中的文字信息 9 | * accept。点击确认按钮 10 | * dismiss。点击取消按钮,如果有的话 11 | * send_keys。向prompt中输入文字 12 | 13 | 代码 14 | ---- 15 | 下面代码简单的演示了如何去处理原生的alert 16 | ### alert.html 17 | 18 | ``` 19 | 20 | 21 | 22 | alert 23 | 24 | 25 | 33 | 34 | 35 | 36 |
37 |
38 |

alert

39 | hover to see tooltip 40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### alert.rb 48 | ``` 49 | #encoding: utf-8 50 | require 'selenium-webdriver' 51 | 52 | dr = Selenium::WebDriver.for :chrome 53 | file_path = 'file:///' + File.expand_path(File.join('.', 'alert.html')) 54 | dr.get file_path 55 | 56 | # 点击链接弹出alert 57 | dr.find_element(:id, 'tooltip').click() 58 | 59 | alert = dr.switch_to.alert 60 | alert.accept() 61 | 62 | sleep(1) 63 | dr.quit() 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /28/upload_file.java.md: -------------------------------------------------------------------------------- 1 | 上传文件 2 | ======== 3 | 4 | 场景 5 | ---- 6 | 上传文件的方法是找到上传文件的对象,通常是的对象。然后直接往这个对象sendKeys,传入需要上传文件的正确路径。绝对路径和相对路径都可以,但是上传的文件必须存在,否则会报错。 7 | 8 | 代码 9 | ---- 10 | 11 | ### upload_file.html 12 | ``` 13 | 14 | 15 | 16 | upload_file 17 | 18 | 19 | 21 | 22 | 23 | 24 |
25 |
26 |

upload_file

27 | 28 |
29 |
30 | 31 | 32 | 33 | ``` 34 | 35 | ### upload_file.java 36 | ``` 37 | import java.io.File; 38 | import java.util.List; 39 | 40 | import org.openqa.selenium.Alert; 41 | import org.openqa.selenium.By; 42 | import org.openqa.selenium.Keys; 43 | import org.openqa.selenium.WebDriver; 44 | import org.openqa.selenium.WebElement; 45 | import org.openqa.selenium.chrome.ChromeDriver; 46 | 47 | 48 | public class Upload { 49 | 50 | public static void main(String[] args) throws InterruptedException { 51 | WebDriver dr = new ChromeDriver(); 52 | 53 | File file = new File("src/upload_file.html"); 54 | String filePath = "file:///" + file.getAbsolutePath(); 55 | System.out.printf("now accesss %s \n", filePath); 56 | 57 | dr.get(filePath); 58 | Thread.sleep(1000); 59 | 60 | dr.findElement(By.cssSelector("input[type=file]")).sendKeys("src/navs.html"); 61 | 62 | Thread.sleep(1000); 63 | System.out.println("browser will be close"); 64 | dr.quit(); 65 | } 66 | 67 | } 68 | ``` 69 | -------------------------------------------------------------------------------- /19/attribute.py.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的属性及内容 2 | ======================== 3 | 4 | 场景 5 | ---- 6 | 获取测试对象的内容是前端自动化测试里一定会使用到的技术。比如我们要判断页面上是否显示了一个提示,那么我们就需要找到这个提示对象,然后获取其中的文字,再跟我们的预期进行比较。在webdriver中使用element.attribute()方法可以获取dom元素(测试对象)的属性。 7 | 8 | 获取测试对象的属性能够帮我们更好的进行对象的定位。比如页面上有很多class都是'btn'的div,而我们需要定位其中1个有具有title属性的div。由于selenium-webdriver是不支持直接使用title来定位对象的,所以我们只能先把所有class是btn的div都找到,然后遍历这些div,获取这些div的title属性,一旦发现具体title属性的div,那么返回这个div既可。在webdriver中,使用element.text()方法可以返回dom节点的内容(text)。 9 | 10 | 代码 11 | ---- 12 | 下面的代码演示了如何获取测试对象的title属性和该对象的文字内容 13 | 14 | ### attribute.html 15 | ``` 16 | 17 | 18 | 19 | attribute 20 | 21 | 22 | 27 | 28 | 29 | 30 |

attribute

31 |
32 | 35 |
36 | 37 | 38 | 39 | ``` 40 | 41 | ### attribute.py 42 | ``` 43 | # -*- coding: utf-8 -*- 44 | from selenium import webdriver 45 | from time import sleep 46 | import os 47 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 48 | 49 | dr = webdriver.Chrome() 50 | file_path = 'file:///' + os.path.abspath('attribute.html') 51 | 52 | dr.get(file_path) 53 | 54 | link = dr.find_element_by_id('tooltip') 55 | 56 | sleep(1) 57 | # 获得tooltip的内容 58 | print link.get_attribute('title') 59 | 60 | # 获取该链接的text 61 | print link.text 62 | 63 | dr.quit() 64 | 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /12/send_keys.py.md: -------------------------------------------------------------------------------- 1 | send keys模拟按键输入 2 | ========= 3 | 4 | 场景 5 | ---- 6 | send_keys方法可以模拟一些组合键操作,比如ctrl+a等。另外有时候我们需要在测试时使用tab键将焦点转移到下一个元素,这时候也需要send_keys。在某些更复杂的情况下,还会出现使用send_keys来模拟上下键来操作下拉列表的情况。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何将A多行文本框中的内容清空并复制到B文本框中。 11 | ### send_keys.html 12 | ``` 13 | 14 | 15 | 16 | send keys 17 | 18 | 19 | 20 | 21 |

send keys

22 |
23 |
24 |
25 | 26 | 27 |
28 |
29 |
30 |
31 | 32 | 33 |
34 |
35 |
36 | 37 | 38 | 39 | ``` 40 | 41 | ### send_keys.py 42 | ``` 43 | from selenium import webdriver 44 | from selenium.webdriver.common.keys import Keys 45 | from time import sleep 46 | import os 47 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 48 | 49 | dr = webdriver.Chrome() 50 | file_path = 'file:///' + os.path.abspath('send_keys.html') 51 | 52 | dr.get(file_path) 53 | 54 | # copy content of A 55 | dr.find_element_by_id('A').send_keys((Keys.CONTROL, 'a')) 56 | dr.find_element_by_id('A').send_keys((Keys.CONTROL, 'x')) 57 | sleep(1) 58 | 59 | # paste to B 60 | dr.find_element_by_id('B').send_keys((Keys.CONTROL, 'v')) 61 | sleep(1) 62 | 63 | # # send keys to A 64 | dr.find_element_by_id('A').send_keys('watir', '-', 'webdriver', Keys.SPACE, 'is', Keys.SPACE, 'better') 65 | sleep(2) 66 | 67 | dr.quit() 68 | 69 | ``` 70 | 71 | 72 | -------------------------------------------------------------------------------- /34/expected_conditions.py: -------------------------------------------------------------------------------- 1 | #encoding:utf-8 2 | # example of how to use https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/support/expected_conditions.py 3 | 4 | from selenium import webdriver 5 | from selenium.webdriver.support import expected_conditions as EC 6 | from selenium.webdriver.support.wait import WebDriverWait 7 | from selenium.webdriver.common.by import By 8 | 9 | import unittest 10 | 11 | # dr = webdriver.PhantomJS('phantomjs') 12 | dr = webdriver.Firefox() 13 | # dr = webdriver.Chrome() 14 | url = 'http://www.baidu.com' 15 | search_text_field_id = 'kw' 16 | dr.get(url) 17 | 18 | class ECExample(unittest.TestCase): 19 | 20 | def test_title_is(self): 21 | ''' 判断title是否符合预期 ''' 22 | title_is_baidu = EC.title_is(u'百度一下,你就知道') 23 | self.assertTrue(title_is_baidu(dr)) 24 | 25 | def test_titile_contains(self): 26 | ''' 判断title是否包含预期字符 ''' 27 | title_should_contains_baidu = EC.title_contains(u'百度') 28 | self.assertTrue(title_should_contains_baidu(dr)) 29 | 30 | def test_presence_of_element_located(self): 31 | ''' 判断element是否出现在dom树 ''' 32 | locator = (By.ID, search_text_field_id) 33 | search_text_field_should_present = EC.visibility_of_element_located(locator) 34 | 35 | ''' 动态等待10s,如果10s内element加载完成则继续执行下面的代码,否则抛出异常 ''' 36 | WebDriverWait(dr, 10).until(EC.presence_of_element_located(locator)) 37 | WebDriverWait(dr, 10).until(EC.visibility_of_element_located(locator)) 38 | 39 | self.assertTrue(search_text_field_should_present(dr)) 40 | 41 | def test_visibility_of(self): 42 | search_text_field = dr.find_element_by_id(search_text_field_id) 43 | search_text_field_should_visible = EC.visibility_of(search_text_field) 44 | self.assertTrue(search_text_field_should_visible('yes')) 45 | 46 | def test_text_to_be_present_in_element(self): 47 | text_should_present = EC.text_to_be_present_in_element((By.NAME, 'tj_trhao123'), 'hao123') 48 | self.assertTrue(text_should_present(dr)) 49 | 50 | 51 | @classmethod 52 | def tearDownClass(kls): 53 | print 'after all test' 54 | dr.quit() 55 | print 'quit dr' 56 | 57 | if __name__ == '__main__': 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /24/alert.py.md: -------------------------------------------------------------------------------- 1 | 处理alert/confirm/prompt 2 | ======================== 3 | 4 | 场景 5 | ---- 6 | webdriver中处理原生的js alert confirm 以及prompt是很简单的。具体思路是使用switch_to.alert()方法定位到alert/confirm/prompt。然后使用text/accept/dismiss/send_keys按需进行操做 7 | 8 | * text。返回alert/confirm/prompt中的文字信息 9 | * accept。点击确认按钮 10 | * dismiss。点击取消按钮,如果有的话 11 | * send_keys。向prompt中输入文字 12 | 13 | 代码 14 | ---- 15 | 下面代码简单的演示了如何去处理原生的alert 16 | ### alert.html 17 | 18 | ``` 19 | 20 | 21 | 22 | alert 23 | 24 | 25 | 33 | 34 | 35 | 36 |
37 |
38 |

alert

39 | hover to see tooltip 40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### alert.py 48 | ``` 49 | # -*- coding: utf-8 -*- 50 | from selenium import webdriver 51 | from time import sleep 52 | import os 53 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 54 | 55 | dr = webdriver.Chrome() 56 | file_path = 'file:///' + os.path.abspath('alert.html') 57 | dr.get(file_path) 58 | 59 | # 点击链接弹出alert 60 | dr.find_element_by_id('tooltip').click() 61 | 62 | try: 63 | alert = dr.switch_to_alert() 64 | alert.accept() 65 | except: 66 | print 'no alerts display' 67 | 68 | sleep(1) 69 | dr.quit() 70 | 71 | ``` 72 | 73 | -------------------------------------------------------------------------------- /14/button_dropdown.md: -------------------------------------------------------------------------------- 1 | 处理button dropdown 2 | =================== 3 | 4 | 场景 5 | ---- 6 | button dropdown就是把按钮和下拉菜单弄到了一起。处理这种对象的思路一般是先点击这个按钮,等待下拉菜单显示出来,然后使用层级定位方法来获取下拉菜单中的具体项。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何找到watir-webdriver这个菜单项。其处理方法是先点击info按钮,然后等到下拉菜单出现后定位下拉菜单的ul元素,再定位ul元素中link text为watir-webdriver的link,并点击之。 11 | ### button_dropdown.html 12 | ``` 13 | 14 | 15 | 16 | button group 17 | 18 | 19 | 26 | 27 | 28 |

button group

29 |
30 |
31 |
32 |
33 |
34 |
first
35 |
second
36 |
third
37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### button_dropdown.rb 48 | ``` 49 | #encoding: utf-8 50 | require 'selenium-webdriver' 51 | 52 | dr = Selenium::WebDriver.for :chrome 53 | file_path = 'file:///' + File.expand_path(File.join('.', 'button_dropdown.html')) 54 | dr.get file_path 55 | 56 | # 定位text是watir-webdriver的下拉菜单 57 | # 首先显示下拉菜单 58 | dr.find_element(:link_text, 'Info').click() 59 | wait = Selenium::WebDriver::Wait.new(timeout: 10) 60 | wait.until { dr.find_element(:class, 'dropdown-menu').displayed? } 61 | 62 | # 通过ul再层级定位 63 | dr.find_element(:class, 'dropdown-menu').find_element(:link_text, 'watir-webdriver').click() 64 | sleep(1) 65 | 66 | dr.quit() 67 | 68 | ``` 69 | 70 | 71 | -------------------------------------------------------------------------------- /17/pagination.md: -------------------------------------------------------------------------------- 1 | 处理分页 2 | ========= 3 | 4 | 场景 5 | ---- 6 | 对分页来说,我们最感兴趣的是下面几个信息 7 | 8 | * 总共有多少页 9 | * 当前是第几页 10 | * 是否可以上一页和下一页 11 | 12 | 代码 13 | ---- 14 | 下面的代码演示了如何获取分页的总数以及当前是第几页 15 | 16 | ### pagination.html 17 | ```html 18 | 19 | 20 | 21 | Pagination 22 | 23 | 24 | 32 | 33 | 34 | 35 |

Pagination

36 |
37 |
38 | 49 |
50 |
51 | 52 | 53 | 54 | 55 | ``` 56 | 57 | ### pagination.rb 58 | ```ruby 59 | #encoding: utf-8 60 | require 'selenium-webdriver' 61 | 62 | dr = Selenium::WebDriver.for :chrome 63 | file_path = 'file:///' + File.expand_path(File.join('.', 'pagination.html')) 64 | dr.get file_path 65 | 66 | # 获得所有分页的数量 67 | # -2是因为要去掉上一个和下一个 68 | total_pages = dr.find_element(:class, 'pagination').find_elements(:tag_name, 'li').size - 2 69 | puts "total page is #{total_pages}" 70 | 71 | # 获取当前页面的url以及当前页面是第几页 72 | current_page = dr.find_element(:class, 'pagination').find_element(:class, 'active') 73 | puts "current page is #{current_page.text}" 74 | dr.quit() 75 | ``` 76 | -------------------------------------------------------------------------------- /13/button_group.py.md: -------------------------------------------------------------------------------- 1 | 处理button group 2 | ================== 3 | 4 | 场景 5 | ---- 6 | button group就是按钮组,将一组按钮排列在一起。处理这种对象的思路一般是先找到button group的包裹(wrapper)div,然后通过层级定位,用index或属性去定位更具体的按钮。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何找到second这个按钮。其处理方法是先找到button group的父div,class为btn-group的div,然后再找到下面所有的div(也就是button),返回text是second的div。 11 | ### button_group.html 12 | ``` 13 | 14 | 15 | 16 | button group 17 | 18 | 19 | 26 | 27 | 28 |

button group

29 |
30 |
31 |
32 |
33 |
34 |
first
35 |
second
36 |
third
37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### button_group.py 48 | ```python 49 | # -*- coding: utf-8 -*- 50 | from selenium import webdriver 51 | from selenium.webdriver.common.keys import Keys 52 | from time import sleep 53 | import os 54 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 55 | 56 | dr = webdriver.Chrome() 57 | file_path = 'file:///' + os.path.abspath('button_group.html') 58 | 59 | dr.get(file_path) 60 | 61 | sleep(1) 62 | 63 | # 定位text是second的按钮 64 | buttons = dr.find_element_by_class_name('btn-group').find_elements_by_class_name('btn') 65 | for btn in buttons: 66 | if btn.text == 'second': print 'find second button' 67 | 68 | sleep(1) 69 | dr.quit() 70 | 71 | ``` 72 | 73 | 讨论 74 | ---- 75 | 自己查资料搞清楚detect方法的作用。 76 | -------------------------------------------------------------------------------- /17/pagination.py.md: -------------------------------------------------------------------------------- 1 | 处理分页 2 | ========= 3 | 4 | 场景 5 | ---- 6 | 对分页来说,我们最感兴趣的是下面几个信息 7 | 8 | * 总共有多少页 9 | * 当前是第几页 10 | * 是否可以上一页和下一页 11 | 12 | 代码 13 | ---- 14 | 下面的代码演示了如何获取分页的总数以及当前是第几页 15 | 16 | ### pagination.html 17 | ``` 18 | 19 | 20 | 21 | Pagination 22 | 23 | 24 | 32 | 33 | 34 | 35 |

Pagination

36 |
37 |
38 | 49 |
50 |
51 | 52 | 53 | 54 | 55 | ``` 56 | 57 | ### pagination.py 58 | ``` 59 | # -*- coding: utf-8 -*- 60 | from selenium import webdriver 61 | from time import sleep 62 | import os 63 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 64 | 65 | dr = webdriver.Chrome() 66 | file_path = 'file:///' + os.path.abspath('pagination.html') 67 | 68 | dr.get(file_path) 69 | 70 | # 获得所有分页的数量 71 | # -2是因为要去掉上一个和下一个 72 | total_pages = len(dr.find_element_by_class_name('pagination').find_elements_by_tag_name('li')) - 2 73 | print "total page is %s" %(total_pages) 74 | 75 | # 获取当前页面的url以及当前页面是第几页 76 | current_page = dr.find_element_by_class_name('pagination').find_element_by_class_name('active') 77 | print "current page is %s" %(current_page.text) 78 | 79 | dr.quit() 80 | 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /20/css.java.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的css属性 2 | ===================== 3 | 4 | 场景 5 | ---- 6 | 当你的测试用例纠结细枝末节的时候,你就需要通过判断元素的css属性来验证你的操作是否达到了预期的效果。比如你可以通过判断页面上的标题字号以字体来验证页面的显示是否符合预期。当然,这个是强烈不推荐的。因为页面上最不稳定的就是css了,css变动频繁,而且通过属性也不能直观的判断页面的显示效果,还不如让人为的去看一眼,大问题一望即知。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何获取测试对象的css属性。 11 | 12 | ### css.html 13 | ``` 14 | 15 | 16 | 17 | attribute 18 | 19 | 20 | 25 | 26 | 27 | 28 |

attribute

29 |
30 | 33 |
34 | 35 | 36 | 37 | ``` 38 | 39 | ### css.java 40 | ``` 41 | import java.io.File; 42 | import java.util.List; 43 | 44 | import org.openqa.selenium.By; 45 | import org.openqa.selenium.WebDriver; 46 | import org.openqa.selenium.WebElement; 47 | import org.openqa.selenium.chrome.ChromeDriver; 48 | 49 | 50 | public class Css { 51 | 52 | public static void main(String[] args) throws InterruptedException { 53 | WebDriver dr = new ChromeDriver(); 54 | 55 | File file = new File("src/css.html"); 56 | String filePath = "file:///" + file.getAbsolutePath(); 57 | System.out.printf("now accesss %s \n", filePath); 58 | 59 | dr.get(filePath); 60 | Thread.sleep(1000); 61 | 62 | WebElement link = dr.findElement(By.id("tooltip")); 63 | 64 | System.out.println(link.getCssValue("color")); 65 | 66 | System.out.println(dr.findElement(By.tagName("h3")).getCssValue("font")); 67 | 68 | Thread.sleep(1000); 69 | System.out.println("browser will be close"); 70 | dr.quit(); 71 | } 72 | 73 | } 74 | 75 | 76 | ``` 77 | 78 | -------------------------------------------------------------------------------- /25/wait.md: -------------------------------------------------------------------------------- 1 | wait 2 | ==== 3 | 4 | 场景 5 | ---- 6 | Wait类的使用场景是在页面上进行某些操作,然后页面上就会出现或隐藏一些元素,此时使用Wait类的until方法来等待这些效果完成以便进行后续的操作。另外页面加载时有可能会执行一些ajax,这时候也需要去Wait的until的等待ajax的请求执行完毕。 7 | 8 | 具体一点的例子前面也曾出现过,点击一个链接然后会出现一个下拉菜单,此时需要先等待下拉菜单出现方可进行点击菜单项的操作。 9 | 10 | 在实例化Wait类时,可以传入以下的一些参数 11 | 12 | * timeout。总共等待多久,默认5s 13 | * interval。每隔多久检查一次代码块里的值,默认0.2秒 14 | * message。如果超时则显示message 15 | * ignored。代码块中忽略的异常。也就是说如果代码块中抛出了这个异常,那么webdriver将忽略这个异常,继续进行等待,直到满足下面所列举的退出条件为止。默认情况下NoSuchElement异常是被忽略的。 16 | 17 | until方法会一直等下去,直到 18 | 19 | * 代码块中的内容为true(不为false或没有抛出异常) 20 | * 超时,也就是超过了timeout设置的时间 21 | 22 | 23 | 代码 24 | ---- 25 | 下面代码演示了点击按钮后如何等待label出现。这个例子其实没有前面的下拉菜单例子实用。 26 | ### wait.html 27 | 28 | ``` 29 | 30 | 31 | 32 | wait 33 | 34 | 35 | 43 | 44 | 45 | 46 |
47 |
48 |

wait

49 | 50 |
51 |
52 | 53 | 54 | 55 | ``` 56 | 57 | ### wait.rb 58 | ``` 59 | #encoding: utf-8 60 | require 'selenium-webdriver' 61 | 62 | dr = Selenium::WebDriver.for :chrome 63 | file_path = 'file:///' + File.expand_path(File.join('.', 'wait.html')) 64 | dr.get file_path 65 | 66 | # 点击按钮 67 | dr.find_element(:id, 'btn').click() 68 | 69 | wait = Selenium::WebDriver::Wait.new() 70 | wait.until { dr.find_element(class: 'label').displayed? } 71 | 72 | sleep(2) 73 | dr.quit() 74 | 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /25/wait.py.md: -------------------------------------------------------------------------------- 1 | wait 2 | ==== 3 | 4 | 场景 5 | ---- 6 | Wait类的使用场景是在页面上进行某些操作,然后页面上就会出现或隐藏一些元素,此时使用Wait类的until方法来等待这些效果完成以便进行后续的操作。另外页面加载时有可能会执行一些ajax,这时候也需要去WebDriverWait的until的等待ajax的请求执行完毕。 7 | 8 | 具体一点的例子前面也曾出现过,点击一个链接然后会出现一个下拉菜单,此时需要先等待下拉菜单出现方可进行点击菜单项的操作。 9 | 10 | 这时候就需要用到selenium.webdriver.support.ui.WebDriverWait类,实例化该类时可以传入timeout的时间,单位是s。 11 | 12 | until方法会一直等下去,直到 13 | 14 | * 代码块中的内容为true(不为false或没有抛出异常) 15 | * 超时,也就是超过了timeout设置的时间 16 | 17 | 18 | 代码 19 | ---- 20 | 下面代码演示了点击按钮后如何等待label出现。这个例子其实没有前面的下拉菜单例子实用。 21 | ### wait.html 22 | 23 | ``` 24 | 25 | 26 | 27 | wait 28 | 29 | 30 | 38 | 39 | 40 | 41 |
42 |
43 |

wait

44 | 45 |
46 |
47 | 48 | 49 | 50 | ``` 51 | 52 | ### wait.py 53 | ``` 54 | # -*- coding: utf-8 -*- 55 | from selenium import webdriver 56 | from selenium.webdriver.common.keys import Keys 57 | from time import sleep 58 | import os 59 | import selenium.webdriver.support.ui as ui 60 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 61 | 62 | dr = webdriver.Chrome() 63 | file_path = 'file:///' + os.path.abspath('wait.html') 64 | 65 | dr.get(file_path) 66 | 67 | # 点击按钮 68 | dr.find_element_by_id('btn').click() 69 | 70 | wait = ui.WebDriverWait(dr, 10) 71 | wait.until(lambda dr: dr.find_element_by_class_name('label').is_displayed()) 72 | 73 | sleep(2) 74 | dr.quit() 75 | 76 | ``` 77 | 78 | -------------------------------------------------------------------------------- /15/navs.java.md: -------------------------------------------------------------------------------- 1 | 处理navs 2 | ========= 3 | 4 | 场景 5 | ---- 6 | navs可以看作是简单的类似于tab的导航栏。一般来说导航栏都是ul+li。先定位ul再去层级定位li中的link基本就能解决问题。 7 | 8 | 代码 9 | ---- 10 | ### navs.html 11 | ``` 12 | 13 | 14 | 15 | Navs 16 | 17 | 18 | 28 | 29 | 30 |

Navs

31 |
32 |
33 | 40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### navs.java 48 | ``` 49 | import java.io.File; 50 | import java.util.List; 51 | 52 | import org.openqa.selenium.By; 53 | import org.openqa.selenium.Keys; 54 | import org.openqa.selenium.WebDriver; 55 | import org.openqa.selenium.WebElement; 56 | import org.openqa.selenium.chrome.ChromeDriver; 57 | 58 | 59 | public class Navs { 60 | 61 | public static void main(String[] args) throws InterruptedException { 62 | WebDriver dr = new ChromeDriver(); 63 | 64 | File file = new File("src/navs.html"); 65 | String filePath = "file:///" + file.getAbsolutePath(); 66 | System.out.printf("now accesss %s \n", filePath); 67 | 68 | dr.get(filePath); 69 | Thread.sleep(1000); 70 | 71 | // 方法1:层级定位,先定位ul再定位li 72 | dr.findElement(By.className("nav")).findElement(By.linkText("About")).click(); 73 | Thread.sleep(1000); 74 | 75 | // 方法2: 直接定位link 76 | dr.findElement(By.linkText("Home")).click(); 77 | 78 | Thread.sleep(1000); 79 | System.out.println("browser will be close"); 80 | dr.quit(); 81 | } 82 | 83 | } 84 | 85 | ``` 86 | 87 | -------------------------------------------------------------------------------- /35/select.py.md: -------------------------------------------------------------------------------- 1 | # Select 2 | 3 | ### 场景 4 | 5 | 在处理下拉框(select)的时候selenium给我们提供了一系列的便捷方法,我们只需要使用```selenium.webdriver.support.select.Select```类来稍微封装一下就好了。 6 | 7 | 源代码在[这里](https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/support/select.py) 8 | 9 | 下面是我们经常会用到的一些方法 10 | 11 | * options: 返回下拉框里所有的选项 12 | * all_selected_options: 返回所有选中的选项 13 | * select_by_value(value): 通过option的value值来选择 14 | * select_by_index(index) 通过option的顺序来选择 15 | * select_by_visible_text(text): 通过option的text来选择 16 | 17 | 18 | ### 代码 19 | 20 | select.html 21 | 22 | ```html 23 | 24 | 25 | 26 | Select 27 | 28 | 29 | 30 | 31 | 32 |
33 |

Select

34 |
35 |
36 |
37 | 38 | 45 |
46 | 47 |
48 |
49 |
50 | 51 | 52 | 53 | ``` 54 | 55 | select.py 56 | 57 | ```python 58 | 59 | # -*- coding: utf-8 -*- 60 | from selenium import webdriver 61 | from selenium.webdriver.support.select import Select 62 | from time import sleep 63 | import os 64 | 65 | dr = webdriver.Firefox() 66 | file_path = 'file:///' + os.path.abspath('select.html') 67 | dr.get(file_path) 68 | 69 | phone_selector = Select(dr.find_element_by_tag_name('select')) 70 | 71 | # 返回所有的options 72 | print(phone_selector.options) 73 | sleep(1) 74 | 75 | # 返回所有选中的options 76 | print(phone_selector.all_selected_options) 77 | sleep(1) 78 | 79 | # 通过option的value值来选择iphone 7 80 | phone_selector.select_by_value('ip7') 81 | sleep(2) 82 | 83 | # 通过index来选择,比如选择第2项 84 | phone_selector.select_by_index(1) 85 | sleep(1) 86 | 87 | # 通过option的text来选择 88 | phone_selector.select_by_visible_text('iPhone 6s') 89 | 90 | dr.quit() 91 | ``` 92 | -------------------------------------------------------------------------------- /12/send_keys.java.md: -------------------------------------------------------------------------------- 1 | send keys模拟按键输入 2 | ========= 3 | 4 | 场景 5 | ---- 6 | sendKeys方法可以模拟一些组合键操作,比如ctrl+a等。另外有时候我们需要在测试时使用tab键将焦点转移到下一个元素,这时候也需要sendKeys。在某些更复杂的情况下,还会出现使用sendKeys来模拟上下键来操作下拉列表的情况。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何将A多行文本框中的内容清空并复制到B文本框中。 11 | ### send_keys.html 12 | ``` 13 | 14 | 15 | 16 | send keys 17 | 18 | 19 | 20 | 21 |

send keys

22 |
23 |
24 |
25 | 26 | 27 |
28 |
29 |
30 |
31 | 32 | 33 |
34 |
35 |
36 | 37 | 38 | 39 | ``` 40 | 41 | ### send_keys.java 42 | ``` 43 | import java.io.File; 44 | 45 | import org.openqa.selenium.By; 46 | import org.openqa.selenium.Keys; 47 | import org.openqa.selenium.WebDriver; 48 | import org.openqa.selenium.chrome.ChromeDriver; 49 | 50 | 51 | public class SendKeys { 52 | 53 | public static void main(String[] args) throws InterruptedException { 54 | WebDriver dr = new ChromeDriver(); 55 | 56 | File file = new File("src/send_keys.html"); 57 | String filePath = "file:///" + file.getAbsolutePath(); 58 | System.out.printf("now accesss %s \n", filePath); 59 | 60 | dr.get(filePath); 61 | Thread.sleep(1000); 62 | 63 | // copy content of A 64 | dr.findElement(By.id("A")).sendKeys(Keys.chord(Keys.CONTROL + "a")); 65 | Thread.sleep(1000); 66 | dr.findElement(By.id("A")).sendKeys(Keys.chord(Keys.CONTROL + "x")); 67 | 68 | // paste to B 69 | dr.findElement(By.id("B")).sendKeys(Keys.chord(Keys.CONTROL + "v")); 70 | 71 | // SendKeys to A 72 | dr.findElement(By.id("A")).sendKeys(Keys.chord("watir webdriver is better than selenium webdriver")); 73 | 74 | Thread.sleep(1000); 75 | System.out.println("browser will be close"); 76 | dr.quit(); 77 | } 78 | 79 | } 80 | 81 | ``` 82 | 83 | 84 | -------------------------------------------------------------------------------- /14/button_dropdown.py.md: -------------------------------------------------------------------------------- 1 | 处理button dropdown 2 | =================== 3 | 4 | 场景 5 | ---- 6 | button dropdown就是把按钮和下拉菜单弄到了一起。处理这种对象的思路一般是先点击这个按钮,等待下拉菜单显示出来,然后使用层级定位方法来获取下拉菜单中的具体项。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何找到watir-webdriver这个菜单项。其处理方法是先点击info按钮,然后等到下拉菜单出现后定位下拉菜单的ul元素,再定位ul元素中link text为watir-webdriver的link,并点击之。 11 | ### button_dropdown.html 12 | ``` 13 | 14 | 15 | 16 | button dropdown 17 | 18 | 19 | 26 | 27 | 28 |

button dropdown

29 |
30 |
31 |
32 | 43 |
44 |
45 |
46 | 47 | 48 | 49 | ``` 50 | 51 | ### button_dropdown.py 52 | ``` 53 | #coding=utf-8 54 | 55 | from selenium import webdriver 56 | from selenium.webdriver.support.ui import WebDriverWait 57 | from time import sleep 58 | import os 59 | 60 | if 'HTTP_PROXY' in os.environ: del os.environ['HTTP_PROXY'] 61 | 62 | dr = webdriver.Chrome() 63 | file_path = 'file:///' + os.path.abspath('button_dropdown.html') 64 | dr.get(file_path) 65 | 66 | sleep(1) 67 | 68 | #点击下拉菜单 69 | dr.find_element_by_link_text('Info').click() 70 | 71 | #找到dropdown-menu父元素 72 | WebDriverWait(dr,10).until(lambda the_driver: the_driver.find_element_by_class_name('dropdown-menu').is_displayed()) 73 | 74 | #找到better than 75 | menu = dr.find_element_by_class_name('dropdown-menu').find_element_by_link_text('better than') 76 | 77 | menu.click() 78 | 79 | sleep(3) 80 | 81 | dr.quit() 82 | 83 | ``` 84 | 85 | 86 | -------------------------------------------------------------------------------- /21/status.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的状态 2 | =================== 3 | 4 | 场景 5 | ---- 6 | 在web自动化测试中,我们需要获取测试对象的四种状态 7 | 8 | * 是否显示。使用element.displayed?()方法; 9 | * 是否存在。使用find_element方法,捕获其抛出的异常,如果是NoSuchElement异常的话则可以确定该元素不存在; 10 | * 是否被选中。一般是判断表单元素,比如radio或checkbox是否被选中。使用element.selected?()方法; 11 | * 是否enable,也就是是否是灰化状态。使用element.enabled?()方法; 12 | 13 | 代码 14 | ---- 15 | 16 | ### status.html 17 | ``` 18 | 19 | 20 | 21 | status 22 | 23 | 24 | 29 | 30 | 31 | 32 |

status

33 |
34 |
35 | 36 |
37 |
38 | Disabled Button 39 |
40 |
41 | 42 |
43 |
44 | 45 | 46 | 47 | ``` 48 | 49 | ### status.rb 50 | ``` 51 | #encoding: utf-8 52 | require 'selenium-webdriver' 53 | 54 | dr = Selenium::WebDriver.for :chrome 55 | file_path = 'file:///' + File.expand_path(File.join('.', 'status.html')) 56 | dr.get file_path 57 | 58 | text_field = dr.find_element(:name, 'user') 59 | puts text_field.enabled? 60 | 61 | # 直接用enabled?方法去判断该button的话返回的会是true 62 | # 这是因为button是使用css方法去disabled的,并不是真正的disable 63 | # 这时候需要判断其class里是否有disabled这值来判断其是否处于disable状态 64 | puts dr.find_element(:class, 'btn').enabled? 65 | 66 | # 隐藏掉text_field 67 | # 判断其是否显示 68 | dr.execute_script('$(arguments[0]).hide()', text_field) 69 | puts text_field.displayed? 70 | 71 | # 使用click方法选择raido 72 | radio = dr.find_element(name: 'radio') 73 | radio.click() 74 | puts radio.selected? 75 | 76 | # 判断元素是否存在 77 | begin 78 | dr.find_element(id: 'none') 79 | rescue Selenium::WebDriver::Error::NoSuchElementError 80 | puts 'element does not exist' 81 | end 82 | 83 | dr.quit() 84 | 85 | ``` 86 | 87 | 讨论 88 | ---- 89 | 在这里我们遇到了一种情况,那就是测试对象看上去是disabled,但是使用enabled方法却返回true。这时候一般思路是判断该对象的css属性或class,通过这些值去进一步判断对象是否disable。 90 | -------------------------------------------------------------------------------- /22/form.md: -------------------------------------------------------------------------------- 1 | form的操作 2 | =================== 3 | 4 | 场景 5 | ----- 6 | 表单对象的操作比较简单,只需要记住下面几点 7 | 8 | * 使用send_keys方法往多行文本框和单行文本框赋值; 9 | * 使用click方法选择checkbox 10 | * 使用click方法选择radio 11 | * 使用click方法点击button 12 | * 使用click方法选择option,从而达到选中select下拉框中某个具体菜单项的效果 13 | 14 | 代码 15 | ---- 16 | 17 | ### form.html 18 | ``` 19 | 20 | 21 | 22 | form 23 | 24 | 25 | 32 | 33 | 34 | 35 |

form

36 |
37 |
38 |
39 |
40 | Legend 41 | 44 | 45 | 48 | 49 | 56 | 57 | 58 |
59 |
60 |
61 |
62 | 63 | 64 | 65 | ``` 66 | 67 | ### form.rb 68 | ``` 69 | #encoding: utf-8 70 | require 'selenium-webdriver' 71 | 72 | dr = Selenium::WebDriver.for :chrome 73 | file_path = 'file:///' + File.expand_path(File.join('.', 'form.html')) 74 | dr.get file_path 75 | 76 | # 选中checkbox 77 | dr.find_element(:css, 'input[type=checkbox]').click() 78 | sleep(1) 79 | 80 | # 选中radio 81 | dr.find_element(:css, 'input[type=radio]').click() 82 | sleep(1) 83 | 84 | # 选择下拉菜单中的最后一项 85 | dr.find_element(:tag_name, 'select').find_elements(:tag_name, 'option').last.click() 86 | sleep(1) 87 | 88 | # 点击提交按钮 89 | dr.find_element(:css, 'input[type=submit]').click() 90 | sleep(1) 91 | 92 | alert = dr.switch_to.alert 93 | puts alert.text 94 | alert.accept() 95 | 96 | dr.quit() 97 | ``` 98 | 99 | -------------------------------------------------------------------------------- /19/attribute.java.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的属性及内容 2 | ======================== 3 | 4 | 场景 5 | ---- 6 | 获取测试对象的内容是前端自动化测试里一定会使用到的技术。比如我们要判断页面上是否显示了一个提示,那么我们就需要找到这个提示对象,然后获取其中的文字,再跟我们的预期进行比较。在webdriver中使用element.getAttribute()方法可以获取dom元素(测试对象)的属性。 7 | 8 | 获取测试对象的属性能够帮我们更好的进行对象的定位。比如页面上有很多class都是'btn'的div,而我们需要定位其中1个有具有title属性的div。由于selenium-webdriver是不支持直接使用title来定位对象的,所以我们只能先把所有class是btn的div都找到,然后遍历这些div,获取这些div的title属性,一旦发现具体title属性的div,那么返回这个div既可。在webdriver中,使用element.getText()方法可以返回dom节点的内容(text)。 9 | 10 | 代码 11 | ---- 12 | 下面的代码演示了如何获取测试对象的title属性和该对象的文字内容 13 | 14 | ### attribute.html 15 | ``` 16 | 17 | 18 | 19 | attribute 20 | 21 | 22 | 27 | 28 | 29 | 30 |

attribute

31 |
32 | 35 |
36 | 37 | 38 | 39 | ``` 40 | 41 | ### attribute.java 42 | ``` 43 | import java.io.File; 44 | import java.util.List; 45 | 46 | import org.openqa.selenium.By; 47 | import org.openqa.selenium.WebDriver; 48 | import org.openqa.selenium.WebElement; 49 | import org.openqa.selenium.chrome.ChromeDriver; 50 | 51 | 52 | public class Attribute { 53 | 54 | public static void main(String[] args) throws InterruptedException { 55 | WebDriver dr = new ChromeDriver(); 56 | 57 | File file = new File("src/attribute.html"); 58 | String filePath = "file:///" + file.getAbsolutePath(); 59 | System.out.printf("now accesss %s \n", filePath); 60 | 61 | dr.get(filePath); 62 | Thread.sleep(1000); 63 | 64 | WebElement link = dr.findElement(By.id("tooltip")); 65 | 66 | // 获得tooltip的内容 67 | System.out.println(link.getAttribute("data-original-title")); 68 | 69 | // 获取该链接的text 70 | System.out.println(link.getText()); 71 | 72 | Thread.sleep(1000); 73 | System.out.println("browser will be close"); 74 | dr.quit(); 75 | } 76 | 77 | } 78 | 79 | ``` 80 | 81 | -------------------------------------------------------------------------------- /16/breadcrumb.java.md: -------------------------------------------------------------------------------- 1 | 处理面包屑 2 | =========== 3 | 4 | 场景 5 | ---- 6 | 在实际的测试脚本中,有可能需要处理面包屑。处理面包屑主要是获取其层级关系,以及获得当前的层级。一般来说当前层级都不会是链接,而父层级则基本是以链接,所以处理面包屑的思路就很明显了。找到面包屑所在的div或ul,然后再通过该div或ul找到下面的所有链接,这些链接就是父层级。最后不是链接的部分就应该是当前层级了。 7 | 8 | 代码 9 | ---- 10 | ### breadcrumb.html 11 | ``` 12 | 13 | 14 | 15 | breadcrumb 16 | 17 | 18 | 25 | 26 | 27 |

breadcrumb

28 |
29 |
30 | 35 |
36 |
37 | 38 | 39 | 40 | 41 | ``` 42 | 43 | ### breadcrumb.java 44 | ``` 45 | import java.io.File; 46 | import java.util.List; 47 | 48 | import org.openqa.selenium.By; 49 | import org.openqa.selenium.WebDriver; 50 | import org.openqa.selenium.WebElement; 51 | import org.openqa.selenium.chrome.ChromeDriver; 52 | 53 | 54 | public class Breadcrumb { 55 | 56 | public static void main(String[] args) throws InterruptedException { 57 | WebDriver dr = new ChromeDriver(); 58 | 59 | File file = new File("src/breadcrumb.html"); 60 | String filePath = "file:///" + file.getAbsolutePath(); 61 | System.out.printf("now accesss %s \n", filePath); 62 | 63 | dr.get(filePath); 64 | Thread.sleep(1000); 65 | 66 | // 获得其父层级 67 | List ancestors = dr.findElement(By.className("breadcrumb")).findElements(By.tagName("a")); 68 | for(WebElement link : ancestors){ 69 | System.out.println(link.getText()); 70 | } 71 | 72 | // 获取当前层级 73 | // 由于页面上可能有很多class为active的元素 74 | // 所以使用层级定位最为保险 75 | WebElement current = dr.findElement(By.className("breadcrumb")).findElement(By.className("active")); 76 | System.out.println(current.getText()); 77 | 78 | Thread.sleep(1000); 79 | System.out.println("browser will be close"); 80 | dr.quit(); 81 | } 82 | 83 | } 84 | 85 | 86 | ``` 87 | 88 | -------------------------------------------------------------------------------- /21/status.py.md: -------------------------------------------------------------------------------- 1 | 获取测试对象的状态 2 | =================== 3 | 4 | 场景 5 | ---- 6 | 在web自动化测试中,我们需要获取测试对象的四种状态 7 | 8 | * 是否显示。使用element.is_displayed()方法; 9 | * 是否存在。使用find_element_by_xxx方法,捕获其抛出的异常, 如果存在异常的话则可以确定该元素不存在; 10 | * 是否被选中。一般是判断表单元素,比如radio或checkbox是否被选中。使用element.is_selected()方法; 11 | * 是否enable,也就是是否是灰化状态。使用element.is_enabled()方法; 12 | 13 | 代码 14 | ---- 15 | 16 | ### status.html 17 | ``` 18 | 19 | 20 | 21 | status 22 | 23 | 24 | 29 | 30 | 31 | 32 |

status

33 |
34 |
35 | 36 |
37 |
38 | Disabled Button 39 |
40 |
41 | 42 |
43 |
44 | 45 | 46 | 47 | ``` 48 | 49 | ### status.py 50 | ``` 51 | # -*- coding: utf-8 -*- 52 | from selenium import webdriver 53 | from time import sleep 54 | import os 55 | if 'HTTP_PROXY'in os.environ: del os.environ['HTTP_PROXY'] 56 | 57 | dr = webdriver.Chrome() 58 | file_path = 'file:///' + os.path.abspath('status.html') 59 | dr.get(file_path) 60 | 61 | text_field = dr.find_element_by_name('user') 62 | print text_field.is_enabled() 63 | 64 | # 直接用enabled?方法去判断该button的话返回的会是true 65 | # 这是因为button是使用css方法去disabled的,并不是真正的disable 66 | # 这时候需要判断其class里是否有disabled这值来判断其是否处于disable状态 67 | print dr.find_element_by_class_name('btn').is_enabled() 68 | 69 | # 隐藏掉text_field 70 | # 判断其是否显示 71 | dr.execute_script('$(arguments[0]).hide()', text_field) 72 | print text_field.is_displayed() 73 | 74 | # 使用click方法选择raido 75 | radio = dr.find_element_by_name('radio') 76 | radio.click() 77 | print radio.is_selected() 78 | 79 | # 判断元素是否存在 80 | try: 81 | dr.find_element_by_id('none') 82 | except: 83 | print 'element does not exist' 84 | 85 | dr.quit() 86 | 87 | ``` 88 | 89 | 讨论 90 | ---- 91 | 在这里我们遇到了一种情况,那就是测试对象看上去是disabled,但是使用enabled方法却返回true。这时候一般思路是判断该对象的css属性或class,通过这些值去进一步判断对象是否disable。 92 | -------------------------------------------------------------------------------- /23/js.java.md: -------------------------------------------------------------------------------- 1 | 执行js 2 | ======= 3 | 4 | 场景 5 | ---- 6 | 如果你熟悉js的话,那么使用webdriver执行js就是一件很高效的事情了。在webdriver脚本中直接执行js的好处很多,这里就不一一枚举了。 7 | 8 | webdriver提供了JavascriptExecutor(dr).executeScript()接口来帮助我们完成这一工作。在实际的测试脚本中,以下两种场景是经常遇到的 9 | 10 | * 在页面直接执行一段js 11 | * 在某个已经定位的元素的上执行js 12 | 13 | 代码 14 | ---- 15 | 下面的代码演示了如何在页面以及在已经定位的元素上执行js 16 | 17 | ### js.html 18 | ``` 19 | 20 | 21 | 22 | js 23 | 24 | 25 | 30 | 31 | 32 | 33 |

js

34 |
35 |
36 | hover to see tooltip 37 | Button 38 |
39 |
40 | 41 | 42 | 43 | 44 | ``` 45 | 46 | ### js.java 47 | ``` 48 | import java.io.File; 49 | import java.util.List; 50 | 51 | import org.openqa.selenium.Alert; 52 | import org.openqa.selenium.By; 53 | import org.openqa.selenium.JavascriptExecutor; 54 | import org.openqa.selenium.Keys; 55 | import org.openqa.selenium.WebDriver; 56 | import org.openqa.selenium.WebElement; 57 | import org.openqa.selenium.chrome.ChromeDriver; 58 | 59 | 60 | public class Js { 61 | 62 | public static void main(String[] args) throws InterruptedException { 63 | WebDriver dr = new ChromeDriver(); 64 | 65 | File file = new File("src/js.html"); 66 | String filePath = "file:///" + file.getAbsolutePath(); 67 | System.out.printf("now accesss %s \n", filePath); 68 | 69 | dr.get(filePath); 70 | Thread.sleep(1000); 71 | 72 | // 在页面上直接执行js 73 | ((JavascriptExecutor)dr).executeScript("$('#tooltip').fadeOut();"); 74 | Thread.sleep(1000); 75 | 76 | // 在已经定位的元素上执行js 77 | WebElement button = dr.findElement(By.className("btn")); 78 | ((JavascriptExecutor)dr).executeScript("$(arguments[0]).fadeOut();", button); 79 | 80 | 81 | Thread.sleep(1000); 82 | System.out.println("browser will be close"); 83 | dr.quit(); 84 | } 85 | 86 | } 87 | ``` 88 | 89 | -------------------------------------------------------------------------------- /13/button_group.java.md: -------------------------------------------------------------------------------- 1 | 处理button group 2 | ================== 3 | 4 | 场景 5 | ---- 6 | button group就是按钮组,将一组按钮排列在一起。处理这种对象的思路一般是先找到button group的包裹(wrapper)div,然后通过层级定位,用index或属性去定位更具体的按钮。 7 | 8 | 代码 9 | ---- 10 | 下面的代码演示了如何找到second这个按钮。其处理方法是先找到button group的父div,class为btn-group的div,然后再找到下面所有的div(也就是button),返回text是second的div。 11 | ### button_group.html 12 | ``` 13 | 14 | 15 | 16 | button group 17 | 18 | 19 | 26 | 27 | 28 |

button group

29 |
30 |
31 |
32 |
33 |
34 |
first
35 |
second
36 |
third
37 |
38 |
39 |
40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### button_group.java 48 | ``` 49 | import java.io.File; 50 | import java.util.List; 51 | 52 | import org.openqa.selenium.By; 53 | import org.openqa.selenium.Keys; 54 | import org.openqa.selenium.WebDriver; 55 | import org.openqa.selenium.WebElement; 56 | import org.openqa.selenium.chrome.ChromeDriver; 57 | 58 | 59 | public class ButtonGroup { 60 | 61 | public static void main(String[] args) throws InterruptedException { 62 | WebDriver dr = new ChromeDriver(); 63 | 64 | File file = new File("src/button_group.html"); 65 | String filePath = "file:///" + file.getAbsolutePath(); 66 | System.out.printf("now accesss %s \n", filePath); 67 | 68 | dr.get(filePath); 69 | Thread.sleep(1000); 70 | 71 | // 定位text是second的按钮 72 | List btns = dr.findElement(By.className("btn-group")).findElements(By.className("btn")); 73 | 74 | for(WebElement btn : btns){ 75 | if(btn.getText().equals("second")){ 76 | btn.click(); 77 | break; 78 | } 79 | } 80 | 81 | Thread.sleep(1000); 82 | System.out.println("browser will be close"); 83 | dr.quit(); 84 | } 85 | 86 | } 87 | 88 | ``` 89 | 90 | 讨论 91 | ---- 92 | 自己查资料搞清楚detect方法的作用。 93 | -------------------------------------------------------------------------------- /24/alert.java.md: -------------------------------------------------------------------------------- 1 | 处理alert/confirm/prompt 2 | ======================== 3 | 4 | 场景 5 | ---- 6 | webdriver中处理原生的js alert confirm 以及prompt是很简单的。具体思路是使用switch_to.alert()方法定位到alert/confirm/prompt。然后使用text/accept/dismiss/send_keys按需进行操做 7 | 8 | * getText。返回alert/confirm/prompt中的文字信息 9 | * accept。点击确认按钮 10 | * dismiss。点击取消按钮,如果有的话 11 | * sendKeys。向prompt中输入文字 12 | 13 | 代码 14 | ---- 15 | 下面代码简单的演示了如何去处理原生的alert 16 | ### alert.html 17 | 18 | ``` 19 | 20 | 21 | 22 | alert 23 | 24 | 25 | 33 | 34 | 35 | 36 |
37 |
38 |

alert

39 | hover to see tooltip 40 |
41 |
42 | 43 | 44 | 45 | ``` 46 | 47 | ### alert.java 48 | ``` 49 | import java.io.File; 50 | import java.util.List; 51 | import org.openqa.selenium.Alert; 52 | import org.openqa.selenium.By; 53 | import org.openqa.selenium.JavascriptExecutor; 54 | import org.openqa.selenium.Keys; 55 | import org.openqa.selenium.WebDriver; 56 | import org.openqa.selenium.WebElement; 57 | import org.openqa.selenium.chrome.ChromeDriver; 58 | 59 | 60 | public class AlertExample { 61 | 62 | public static void main(String[] args) throws InterruptedException { 63 | WebDriver dr = new ChromeDriver(); 64 | 65 | File file = new File("src/alert.html"); 66 | String filePath = "file:///" + file.getAbsolutePath(); 67 | System.out.printf("now accesss %s \n", filePath); 68 | 69 | dr.get(filePath); 70 | Thread.sleep(1000); 71 | 72 | // 点击链接弹出alert 73 | dr.findElement(By.id("tooltip")).click(); 74 | 75 | Alert alert = dr.switchTo().alert(); 76 | alert.accept(); 77 | 78 | Thread.sleep(1000); 79 | System.out.println("browser will be close"); 80 | dr.quit(); 81 | } 82 | 83 | } 84 | ``` 85 | 86 | --------------------------------------------------------------------------------