37
Meet Selenium Automated application testing

Introduction to Selenium and Ruby

Embed Size (px)

Citation preview

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