Transcript

Meet SeleniumAutomated application testing

Application Testing

Running WebsiteAutomated

Browser

Application Testing

Type text here

Application Testing

Click here

Application TestingCheck text is ...

Application Testing

• Don’t need to change source code

• Can test (almost) anything

• Less focused than unit testing

Testing Tools

• Selenium server

• Web driver client

• Browsers

Testing ToolsSelenium ServerSelenium Driver

Supported Languages

• Official:

• Java, C#, Ruby, Python, JavaScript

• Community:

• perl, php, Haskell, Objective-C

Sample Driver Coderequire 'selenium-webdriver' !driver = Selenium::WebDriver.for :firefox driver.navigate.to "https://duckduckgo.com/" !!driver.find_element(:id, 'search_form_input_homepage') .send_keys("webdriver") !driver.find_element(:id, 'search_button_homepage') .click !puts "Search page title = #{driver.title}" !driver.quit

Online Resources

• Ruby Selenium Wiki: https://code.google.com/p/selenium/wiki/RubyBindings

• Selenium Ruby API: http://selenium.googlecode.com/git/docs/api/rb/index.html

Selenium API

Agenda

WebDriver WebElement

Main Classes

# Create a driver for Firefox driver = Selenium::WebDriver.for :firefox !# Create a driver for Safari driver = Selenium::WebDriver.for :safari !# If your FF is installed in a non-default location # Use this before creating the driver Selenium::WebDriver::Firefox.path = "/path/to/firefox"

WebDriver Functions# Load a web page driver.navigate.to "http://www.google.com" !# Returns page title driver.title !# Returns HTML page source driver.page_source !# Call a JS function driver.execute_script("alert('hello world');") !# Quit the browser driver.quit

Web Element

• Query and interact with elements on the page

• Both visual and functional

• Get using a locator

Locating Web Elements# Get an element on the page # By name el = driver.find_element(:name, 'btnK') !# By css selector el = driver.find_element(:css, '.menu-item') !# By id el = driver.find_element(:id, 'login-form') !# By xpath el = driver.find_element(:xpath, "//h2[@class='title']")

Web Element

• Visual Methods:

el = driver.find_element(:css, '.menu-item') !# Get the location of the element # (top-left corner) el.location !# Get size of an element el.size !# Bool: is element visible el.displayed?

Web Element• Functional Methods# Get attribute value el.attribute('id') !# Get inner text value el.text !# Mouse click on the element el.click !# Focus and send keyboard presses el.send_keys('hello')

Testing with Ruby, RSpec and Selenium

RSpec

• Ruby’s testing framework

• Looks like jasmine / mocha

RSpec 1 require 'person'! 2 ! 3 describe 'Person' do! 4 describe '#grow_up' do! 5 it "should increase a persons's age" do! 6 p = Person.new(10)! 7 p.grow_up! 8 ! 9 expect(p.age).to eq(11)!10 end!11 end!12 end!

Running RSpec

• Save your code in lib/

• Save your spec in spec/

• Just type rspec

1 " Press ? for help!2 !3 .. (up a dir)!5 ▾ lib/!6 Person.rb!7 ▾ spec/!8 person_spec.rb!

Running Cloud RSpec

• Sign up and use a cloud based selenium testing provider

Sauce Cloud Demo

• Use ruby-sauce gem

• Specify all browsers in Config

1 require 'sauce'! 2 ! 3 Sauce.config do |c|! 4 c[:browsers] = [! 5 ["Windows 7","Firefox","18"],! 6 ]! 7 end! 8 ! 9 # s / selenium are automatically available!10 # inside the test!11 describe 'Testing Google', :sauce => :true do!12 it 'should be Google' do!13 s.navigate.to('http://www.google.com')!14 expect(s.title).to eq('Google')!15 end!16 end!

Demos

• Let’s test duckduckgo’s title for the input search string (http://duckduckgo.com/)

• Let’s test designmodo’s siedbar disappears on small screen (http://designmodo.com/)

RSpec Hooks

• Use hooks for setup/teardown code

• before(:each), before(:all), after(:each) and after(:all)

describe Thing do! before(:each) do! @thing = Thing.new! end!! describe "initialized in before(:each)" do! it "has 0 widgets" do! expect(@thing.widgets.count).to eq(0)! end!! it "can get accept new widgets" do! @thing.widgets << Object.new! end!! it "does not share state across examples" do! expect(@thing.widgets.count).to eq(0)! end! end

Advanced Selenium APIs

Target Locator

• Selenium driver is “focused” on a single frame or modal dialog

• Change active frame using switch_to

Target Locator

1 frame = driver.find_elements(:css, 'iframe').first!2 !3 driver.switch_to.frame(frame['id'])!4 element = driver.find_element(:css, 'button')!5 element.click!6 !7 alert = driver.switch_to.alert!8 puts alert.text!9 alert.accept!

Demo URL: http://jsfiddle.net/Wchm5/embedded/result/

Explicit Waits

• When async JS is involved, you may need to wait for state change

• Selenium has a Wait object

Explicit Wait# Create a wait object with 30 seconds timeout wait = Selenium::WebDriver::Wait.new( :timeout => 30 ) !driver.find_element(:name, 'q').send_keys('webdriver') driver.find_element(:name, 'btnK').click !# Page title is not yet changed # so this just prints google puts driver.title !# So we wait... wait.until { driver.title != 'Google' } !# And now get the right value puts driver.title

Selenium Actions

Simulating mouse interactions and complex ui gestures

Selenium Actions# Use method chaining to describe the sequence, # and perform to execute !# Move mouse to el1 center and click driver.action.move_to(el1).click.perform !# Press and hold shift, move mouse to el1 and click # then move mouse to second_element and click again # release shift key, and drag element to third_element driver.action.key_down(:shift). click(el1). click(second_element). key_up(:shift). drag_and_drop(element, third_element). perform

Live Demo #1

• Enter AccuWeather

• Check weather for Tel Aviv

• Make sure (F) and (C) match

• Use SaucaLabs to run on multiple browsers

Takeaways

• Wrap website access in your own ruby class (which uses Selenium)

• Aim for short test specs

System Testing

• Be selective about what you test

• Run tests nightly

• Use a remote test server