+ All Categories
Home > Technology > Testing Your Website with Selenium (and Perl)

Testing Your Website with Selenium (and Perl)

Date post: 04-Aug-2015
Category:
Upload: tim-vroom
View: 287 times
Download: 12 times
Share this document with a friend
58
Testing Your Website With Selenium (and Perl) Tim Vroom - [email protected] YAPC NA - June 2015 Salt Lake City, Utah Photo by waynerd on flickr
Transcript
Page 1: Testing Your Website with Selenium (and Perl)

Testing Your Website With Selenium (and Perl)

Tim Vroom - [email protected] YAPC NA - June 2015 Salt Lake City, Utah

Photo by waynerd on flickr

Page 2: Testing Your Website with Selenium (and Perl)

About Me

Tim Vroom Once upon a time was creator

of perlmonks.org

Currently work at slashdot.org

@vroomtim on twitter

Page 3: Testing Your Website with Selenium (and Perl)

GitHub Repo

• https://github.com/tvroom/selenium-testing-with-perl

Short url of ( http://tinyurl.com/sel-perl )

(slides / example code / web pages / scripts) — final updates may come in next few days

Page 4: Testing Your Website with Selenium (and Perl)

What is Selenium?

• A tool for web-browser automation & testing

• Allows for functional testing that also runs JavaScript loaded on the page

• Can run tests against multiple web browsers

Page 5: Testing Your Website with Selenium (and Perl)

Why might you want to use it?

Page 6: Testing Your Website with Selenium (and Perl)
Page 7: Testing Your Website with Selenium (and Perl)

Test close to where users experience your code (in the browser)

Test things your JS, and CSS are responsible for, layout in browser, visibility of messages etc…

Page 8: Testing Your Website with Selenium (and Perl)

Speed up involved debugging / testing

while developing long flows

Don’t spend your time typing and clicking to test code as you develop, in complicated code, and flows.

Automate the tedium of testing… so you can write more code, and test your code changes more quickly.

Page 9: Testing Your Website with Selenium (and Perl)

What we’ll cover

• Running your first Selenium test with Perl

• SeleniumRC vs Selenium Webdriver

• Key Perl libraries to consider using for your tests

• Locating Elements & Handling Waits

• Variety of Example Tests

Page 10: Testing Your Website with Selenium (and Perl)

What we’ll finish up with… Time in the Selenium Playground working through listed test tasks

Page 11: Testing Your Website with Selenium (and Perl)

Steps to running your first Selenium Test with Perl

1. Download Selenium Server - selenium-server-standalone-2.45.0.jar (latest currently) at http://www.seleniumhq.org/download/

2. Run the server:

3. Install Selenium::Remote::Driver from CPAN

java -jar selenium-server-standalone-2.45.0.jar

Page 12: Testing Your Website with Selenium (and Perl)

Sample YAPC Testuse Selenium::Remote::Driver; use Selenium::Remote::WDKeys; use Test::More;

my $driver = Selenium::Remote::Driver->new(default_finder => 'css');

$driver->get('http://www.google.com');

$driver->find_element('q','name')->send_keys('YAPC Salt Lake City',KEYS->{'enter'});

$driver->set_implicit_wait_timeout(5000);

$driver->find_element('#rso li h3 a')->click(); my $title = $driver->get_title(); like($title, qr/YAPC/, "Title for YAPC page is what is expected");

$driver->find_element('Talks and Schedule', 'link_text')->click(); $driver->find_element('Schedule','link_text')->click(); $driver->find_element('Wednesday','link_text')->click(); $driver->find_element('Selenium','partial_link_text')->click();

$title = $driver->get_title(); like($title, qr/Selenium/, "Title seems to be about testing with Selenium"); sleep 5; # For demo purposes wait a bit before closing so we can see the final page $driver->quit();

done_testing();

Page 13: Testing Your Website with Selenium (and Perl)

Versions of Selenium

Remote Control - Vs - WebDriver

Page 14: Testing Your Website with Selenium (and Perl)

Selenium RC (Selenium 1)

• Selenium Remote Control serves as middle layer between code and browser

• When you run a test it pops one window for the Remote Control, and then that window operates your test window via javascript

• Operates browser actions by running Javascript to mimic those actions

• Due to translation in middle layer sometimes did things differently than the browser actually would

Your Code -> Selenium RC —> Browser test is running in

Page 15: Testing Your Website with Selenium (and Perl)

Selenium 2 (WebDriver API)

• Talks directly to browser via WebDriver API calls

• Browser makers have built WebDriver support right into the browser

• Typically faster running tests due to more direct nature

• Behaves more consistently with actual browser behavior, because you’re executing native code with-in the browser, which matches up with WebDriver API Calls

Page 16: Testing Your Website with Selenium (and Perl)

Additional Reading on JsonWireProtocol (or WebDriver wire protocol)

• JsonWireProtocol - learn about the protocol (and capabilities provided) in the Protocol used to power WebDriver

• https://code.google.com/p/selenium/wiki/JsonWireProtocol

• Particularly - the command reference section: https://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference

Page 17: Testing Your Website with Selenium (and Perl)

SELENIUM VERSION REMOTE CONTROL (RC) WEBDRIVER

BASE PERL MODULE WWW:::Selenium Selenium::Remote::Driver

TEST MODULE Test::WWW::Selenium Test::Selenium::Remote::Driver

OTHER STUFF WWW::Selenium::NetworkCaptureWWW::Selenium::Util

Selenium::FirefoxSelenium::ChromeSelenium::PhantomJS

Perl Modules By Selenium Version

Page 18: Testing Your Website with Selenium (and Perl)

• Selenium::Firefox • Selenium::Chrome • Selenium::PhantomJS

New modules in the space - run WebDriver tests w/o Selenium Standalone Server

(from Selenium::Remote::Driver docs)

Page 19: Testing Your Website with Selenium (and Perl)

Sample code for this presentation

• Will primarily show code interacting with Selenium Webdriver (Selenium::Remote::Driver Perl Module)

• Repo will contain examples with SeleniumRC in most cases for comparison

Page 20: Testing Your Website with Selenium (and Perl)

Typical Test FlowStep 0. Find a Thing in the DOM

Step 1. Do something to that thing, or look at its attributes

Step 2. Wait appropriate amount of time if necessary before doing next thing

Repeat…

Page 21: Testing Your Website with Selenium (and Perl)

Key Concepts While Writing Tests

Page 22: Testing Your Website with Selenium (and Perl)
Page 23: Testing Your Website with Selenium (and Perl)

Use Dev Tools in Chrome or similar to inspect the element you’re interested in

and find a selector for it

Page 24: Testing Your Website with Selenium (and Perl)

Methods to Find Your Elements

Page 25: Testing Your Website with Selenium (and Perl)

find_elementfind_element($search_string, $locator_type);

# find using css locator — type$driver->find_element(‘h3.articlehead’,’css’);

# use default of path for locator$driver->find_element(‘//*[@id=“logo”]/a’);

If your element is not found — will CROAK, killing your script. (unless you check for and trap in try/catch or eval block etc)

Returns Selenium::Remote::WebElement object

Page 26: Testing Your Website with Selenium (and Perl)

How to override default_finder on driver initialization

my $driver = Selenium::Remote::Driver->new(default_finder => ‘css');

# default to css now instead of path $driver->find_element(‘h3.article’);

Page 27: Testing Your Website with Selenium (and Perl)

Convenience methodsfind_element_by_class

find_element_by_class_name

find_element_by_css

find_element_by_id

find_element_by_link

find_element_by_link_text

find_element_by_name

find_element_by_partial_link_text

find_element_by_tag_name

find_element_by_xpath

Page 28: Testing Your Website with Selenium (and Perl)

find_elementsmy $ar = $driver->find_elements($search,$opt_locator);

Same as find_element, but returns an array, or array ref

Warning — latest Selenium::Remote::Driver does not croak now on find_elements with size of 0 (none found)

— but may in the future

Page 29: Testing Your Website with Selenium (and Perl)

Strategies for testing for elements that aren’t there

• find_element (trap croak / eval / try/catch) • find_elements?? (0 size array(ref), or croak pay

attention to what your version does)

• Test::Selenium::RemoteDriver method $driver-

>find_no_element_ok($search_target [,$finder,

$desc ]); • use JavaScript $driver->execute_script(‘return

your_test_for_no_element()’);

Page 30: Testing Your Website with Selenium (and Perl)

css # <div class=“header”></div> $driver->find_element(‘.header’,’css);

Locate Via…

name # <input type=“text” name=“user” value=“” /> $driver->find_element(‘user’,’name’);

link_text # <a href=“/schedule.html”>Schedule</a> $driver->find_element(‘Schedule’,’link_text’);

xpath # <div id=“logo”><a href=“/”></div> $driver->find_element(‘//*[@id=“logo"]/a’,’xpath’);and more… class, class_name, id, link, partial_link_text, tag_name

Page 31: Testing Your Website with Selenium (and Perl)

find_element methods return (on success)

Selenium::Remote::WebElement objects

Page 32: Testing Your Website with Selenium (and Perl)

Selenium::Remote::WebElement defines methods to take action on the elements or test attributes of them, look at the documentation to see what’s available

This allows you to chain calls like: $driver->find_element(‘.foo’,’css’)->click(); $driver-find_element(‘username’,’name’)->send_keys(‘bob’);

Selenium::Remote::WebElement

Page 33: Testing Your Website with Selenium (and Perl)

click submit send_keys is_selected set_selected toggle is_enabled get_element_location get_element_location_in_view get_tag_name

clear get_attribute get_value is_displayed is_hidden drag get_size get_text get_css_attribute describe

Selenium::Remote::WebElement Methods

Page 34: Testing Your Website with Selenium (and Perl)

Managing Waits For Your

Tests

Page 35: Testing Your Website with Selenium (and Perl)
Page 36: Testing Your Website with Selenium (and Perl)

WaitsTests need to properly wait for completion of

actions, before looking for an element provided as a result of previous action

Load a new page

Change current page via Ajax or JS

When you….

Page 37: Testing Your Website with Selenium (and Perl)

Too short/ Non-Existent = failing tests

Too long = (long sleeps), slow test suites

Just right - wait only as long as you need to = passing tests + fast test suites

Range of Waits

Page 38: Testing Your Website with Selenium (and Perl)

Selenium::Remote::Driver waits for new page loads

Default Behavior:polls and waits for up to ‘page load’ timeout (default 180 secs)

You can change this timeout via:

$driver->set_timeout('page load', 10000); # 10 second timeout in ms

Controls actions that take you to a new page. ie: navigate to a new page, full page form submit

Page 39: Testing Your Website with Selenium (and Perl)

Selenium::Remote::Driver waits for in page element

changes

poll and wait up to implicit_wait_timeout for find_element - default is 0 ms

You can change this timeout via:

$driver->set_implicit_wait_timeout(5000) # change to 5 secs in ms

Page 40: Testing Your Website with Selenium (and Perl)

Selenium::Remote::Driver (wait for condition)

Selenium RC has a method, which runs a piece of JS checking for a condition for up to a timeout threshold

# wait until a new article is inserted $sel->wait_for_condition(‘window.$(".article").length >’.$orig_count, 10000);

You could write your own method to extend Selenium::Remote::Driver to provide the same functionality (sample of this in repo)

Page 41: Testing Your Website with Selenium (and Perl)

Example Tests

These will cover some tests that go beyond navigating pages / links / and

filling out forms

Page 42: Testing Your Website with Selenium (and Perl)

Taking a Screenshot

use Selenium::Remote::Driver;

my $driver = Selenium::Remote::Driver->new(); $driver->get("http://blogs.perl.org"); $driver->capture_screenshot("screenshot.png"); $driver->quit();

Page 43: Testing Your Website with Selenium (and Perl)

Running JS in your tests$driver->execute_script() method to run JS and return

resultsuse Selenium::Remote::Driver; use Test::More; my $driver = Selenium::Remote::Driver->new(); $driver->navigate("http://timvroom.com/selenium/js_testing.html"); my $shopping_count = $driver->execute_script( 'return $(".shopping-list li").length' ); ok($shopping_count >= 3, "Shopping list has at least 3 items");

done_testing();

Page 44: Testing Your Website with Selenium (and Perl)

Verify JS library inclusionuse Selenium::Remote::Driver;use Test::More;

my $driver = Selenium::Remote::Driver->new();

$driver->navigate("http://timvroom.com/selenium/js_testing.html");

ok(js_defined("window.jQuery"), "jQuery installed on $_[0]");ok(js_defined("window.jQuery.cookie"), "jQuery cookie plugin installed");ok(js_defined("window.Handlebars"), "has Handlebars installed");

done_testing();

sub js_defined { my $val = shift; my $ret = $driver->execute_script("return !(typeof $val === 'undefined')"); return $ret;}

Page 45: Testing Your Website with Selenium (and Perl)

Capturing Network Data

WWW::Selenium::NetworkCapture - gives you a way of seeing all the HTTP requests, and response information generated by your Selenium

session

Webdriver doesn’t offer this capability, but you could run your tests through a webproxy, and then analyze results

Page 46: Testing Your Website with Selenium (and Perl)

Ex) Test for missing failed resources loading (Source HTML)

<html> <head> <title>Broken resources test page</title> </head> <body> <h1>Broken resources test page</h1> <style type="text/css"> #logo { background:transparent url(/missing_logo_call_from_css.png) no-repeat top left; float:left; height: 20px; width: 120px; } </style> <div id="logo"></div> <img src="broken_image.png" alt="broken_image"> <script src="broken_script.js" type="text/javascript"> </body> </html>

Page 47: Testing Your Website with Selenium (and Perl)

use WWW::Selenium;use WWW::Selenium::NetworkCapture;use Data::Dumper;use Test::More;

my $sel=WWW::Selenium->new( browser_url => "http://timvroom.com/selenium/ga_test.html");$sel->start();$sel->{session_id} = $sel->get_string( "getNewBrowserSession", $sel->{browser_start_command}, $sel->{browser_url}, undef, 'captureNetworkTraffic=true');

$sel->open("http://timvroom.com/selenium/broken_resources.html");$sel->wait_for_page_to_load(10000);

my $traffic_xml = $sel->get_string('captureNetworkTraffic', 'xml');

my $netcap = WWW::Selenium::NetworkCapture->new($traffic_xml);my @stat_code_urls = map { [$_->{statusCode}, $_->{url}]} grep { $_->{url} !~ /favicon.ico/ } grep { $_->{statusCode} =~/^(4|5)/ } @{$netcap->{dom}{entry}};

ok(!@stat_code_urls, "Resources loaded w/o 40x or 50x errors for $key $url\n") or diag Dumper(@stat_code_urls);$sel->stop();done_testing();

Test Script

Page 48: Testing Your Website with Selenium (and Perl)

not ok 1 - Resources loaded w/o 40x or 50x errors for## Failed test 'Resources loaded w/o 40x or 50x errors for# '# at missing_resources.t line 27.# $VAR1 = [# [# '404',# 'http://timvroom.com/selenium/broken_image.png'# ],# [# '404',# 'http://timvroom.com/selenium/broken_script.js'# ],# [# '404',# 'http://timvroom.com/missing_logo_call_from_css.png'# ]# ];1..1# Looks like you failed 1 test of 1.

Results

Page 49: Testing Your Website with Selenium (and Perl)

use WWW::Selenium;use WWW::Selenium::NetworkCapture;use Data::Dumper;use Test::More;

my $sel=WWW::Selenium->new( browser_url => "http://timvroom.com");$sel->start();$sel->{session_id} = $sel->get_string( "getNewBrowserSession", $sel->{browser_start_command}, $sel->{browser_url}, undef, 'captureNetworkTraffic=true');

$sel->open("http://timvroom.com/selenium/ga_test.html");$sel->wait_for_page_to_load(10000);

my $traffic_xml = $sel->get_string('captureNetworkTraffic', 'xml');

my $netcap = WWW::Selenium::NetworkCapture->new($traffic_xml);

my @requests = @{$netcap->{dom}{entry}};

my @ga_track_pv = grep { $_->{url} =~ m|www.google-analytics.com/r/collect\?.*t=pageview| } @requests;my @non_200_ga_track = grep { !$_->{statusCode} == 200 } @ga_track_pv; ok(@ga_track_pv == 1, "Got exactly 1 GA track pageview request");ok(!@non_200_ga_track, "All GA track pageview requests got a 200 statusCode");

Check for Google Analytics Tracking

Results:

ok 1 - Got exactly 1 GA track pageview request ok 2 - All GA track pageview requests got a 200 statusCode 1..2

Page 50: Testing Your Website with Selenium (and Perl)

Now let’s hit the

Selenium Playground!!!

Page 51: Testing Your Website with Selenium (and Perl)

Remind us again what this fun thing is? This is a static page with automation tasks you can run your

automated script against and then check the results. Hopefully a good way to get your feet wet with web

automation

Page 52: Testing Your Website with Selenium (and Perl)

Start with run_playground_empty.pl from the repo which will load the page and check results (which gives us lots

of test fails)

( http://tinyurl.com/selplay )

Page 53: Testing Your Website with Selenium (and Perl)

Navigate to:

http://tinyurl.com/selplayon your phone or computer if you want to give input on the tasks from the list we demo in the

presentation

(I’ll ask for suggestions — raise your hand and call out a number you’d like to see demo-ed once I call on you)

Page 54: Testing Your Website with Selenium (and Perl)

If you want to see the script that solves in action run… run_playground_answers.pl (or

check answers if you’re stuck on a task)

Page 55: Testing Your Website with Selenium (and Perl)

Questions? Talk repo at:

https://github.com/tvroom/selenium-testing-with-perl

Short url of ( http://tinyurl.com/sel-perl )

Page 56: Testing Your Website with Selenium (and Perl)

Thanks for your time!

and now a short Public Service Announcement….

Page 57: Testing Your Website with Selenium (and Perl)

Take a few minutes and provide your feedback - so we can learn what worked, what didn’t and how to improve

and probably all other speakers would like your HONEST feedback on the online speaker evaluations.

(Check your email for instructions)

This friendly guy…..

Page 58: Testing Your Website with Selenium (and Perl)

Thanks for listening

Talk repo at: https://github.com/tvroom/selenium-testing-with-perl

Short url of ( http://tinyurl.com/sel-perl )


Recommended