Download - Real World Selenium

Transcript
Page 1: Real World Selenium

Real World Selenium TestingMary Jo Sminkey!CF Webtools

Page 2: Real World Selenium

About Me

• 20+ Years in Web Development!

• ColdFusion Developer since CF 3.0 Release by Allaire!

• Author of the e-commerce application CFWebstore!

• Currently working for CFWebtools as the Lead Developer for a large e-commerce website selling classic car parts (Classic Industries)!

• Hobbies include dog training and showing, photography, playing music, baking, board games, scrapbooking, origami, and more!

Page 3: Real World Selenium

Why Selenium?• Automates Testing Applications in the Browser!

• Will simulate users interacting with the site and find bugs that unit tests can’t!

• Can use even for legacy sites that may not work with unit testing!

• Portable across many browsers and coding platforms!

• Popular so easy to find help and plugins, etc. !

• Easy to get started with but can also handle very advanced and complex testing.

Page 4: Real World Selenium

Installing Selenium• Includes IDE (Firefox Plugin) and Web Driver (runs tests on Selenium Server)!

• http://docs.seleniumhq.org!

• We will focus today on building tests to run in the IDE!

• Easy for newbies to learn, uses simple HTML syntax !

• Plugins available that help debug your scripts!

• User extensions can also be added to extend the language (loops, if/else if, etc) although there are caveats to be aware of.!

• Many tools available to convert IDE scripts to run on Web Driver (cfselenium)

Page 5: Real World Selenium

Some IDE Tips• Set your default timeout to something reasonable!

• To run an individual test, use keyboard shortcut “X” !

• If your site uses popup windows, be sure to configure FF to allow them for the address!

• The “Find” button can be helpful to highlight the target element, but don’t rely on for most XPath locators!

• The speed slider can be useful to debug a fast-running script, but should not be used for tests that don’t pass at full speed.!

• Some Firefox plugins may cause Selenium tests to work incorrectly (like form fillers) so you may want to have a separate FF profile specific for your testing.

Page 6: Real World Selenium

Useful Plugins• Download at http://docs.seleniumhq.org/download/!!

• Favorites !• Save and quick-launch your favorite test suites!!

• Test Results!• Generates reports of test and suite results after running !!

• Highlight Elements!• Highlights target elements on the page as your tests run!!

• Power Debugger!• Adds the Pause on Fail button !!

• Stored Variables Viewer!• View and delete stored variables in the IDE!!

!

Page 7: Real World Selenium

Developing a Testing Plan• What makes money (or provides value) most for the website?!

• Which pages are visited most often?!

• Which browsers are used most often? !

• What areas have been the most common to experience bugs? !

• If other test methods in place (unit testing, etc.) what types of things are not tested by these?

Page 8: Real World Selenium

Goals For Tests

• Robust, not brittle!

• Don’t rely on data that changes !

• Can run on multiple environments!

• Will run at any speed without errors !

• Start simple and make it work, then refactor adding more capability and tests

Page 9: Real World Selenium

Creating Selenium Tests • Macro Recording Feature!

• Useful to get started quickly!• Often creates very unreliable, brittle locators!

!• Manually writing tests in HTML!

!<tr>!! <td>Command</td>!! <td>Target</td>!! <td>Value</td>!</tr>

Page 10: Real World Selenium

Verifying Text on the Page!• verifyText(Not)Present/assertText(Not)Present (depricated)!

• Checks that the text exists/does not exist on the webpage, with no element specified!

!!

• verify(Not)Text/assert(Not)Text!• Checks that the text given is found/not found in the element specified!!!

• verify(Not)Title/assert(Not)Title!• Checks that the page HTML Title tag matches/does not match the text

Page 11: Real World Selenium

Verifying Elements on the Page!• verifyElement(Not)Present/assertElement(Not)Present !

• Checks that the element designated can/can not be located on the page!!

• verify(Not)Table/assert(Not)Table!• Checks that the given table designated is found/not found on the page!

!• verify(Not)Attribute/assert(Not)Attribute!

• Checks that the specified attribute of an element matches/does not match the pattern

Page 12: Real World Selenium

Verifying Form Elements• verify(Not)Checked/assert(Not)Checked!

• Checks if a toggle element (checkbox/radio button) is in a checked/ unchecked state!!

• verify(Not)SelectOptions/assert(Not)SelectOptions !• Checks if the array of options for a selectbox matches/does not match a given

array!!• verify(Not)Selected/assert(Not)Selected (depricated)!

• Checks that the option matching the pattern is selected (or not selected)

Page 13: Real World Selenium

Verifying Form Elements, cont.• verify(Not)SelectedId(s)/assert(Not)SelectedId(s) !

• Checks that the ID(s) of the selected option(s) matches/does not match the value(s)!!

• verify(Not)SelectedIndex(s)/assert(Not)SelectedIndex(s) !• Checks that the index(es) of the selected option(s) matches/does not match the

value(s) !!

• verify(Not)SelectedLabel(s)/assert(Not)SelectedLabel(s)!• Checks that the label(s) of the selected option(s) match the pattern !!

• verify(Not)SelectedValue(s)/assert(Not)SelectedValue(s)!• Checks that the value(s) of the selected option(s) match the pattern!!

• verify(Not)Editable/assert(Not)Editable!Checks if a form element is/is not editable, ie hasn’t been disabled!

!

Page 14: Real World Selenium

Verifying Cookies• verify(Not)CookiePresent/assert(Not)CookiePresent!

• Checks that the designated cookie is found/not found on the client!!

• verify(Not)Cookie)/assert(Not)Cookie!• Checks all the cookies on the page !!

• verify(Not)CookieByName/assert(Not)CookieByName!• Checks that the value of the specified cookie matches/does not match the

pattern

Page 15: Real World Selenium

Verifying Alerts• verify(Not)Alert/assert(Not)Alert!

• Checks that the last JS alert matches/does not match the text pattern!!

• verify(Not)AlertPresent/assert(Not)AlertPresent!• Checks if a JS alert occurred/did not occur !!

• verify(Not)Prompt/assert(Not)Prompt!• Checks that the last JS prompt matches/does not match the text pattern!!

• verify(Not)PromptPresent/assert(Not)PromptPresent!• Checks if a JS prompt occurred/did not occur

Page 16: Real World Selenium

Let’s Talk Locators!• identifier=id: Select the element with the specified @id attribute. If not found, look for a

match with @name. (default)!!

• id=id: Select the element with the specified @id attribute.!!• name=name: Select the element with the specified @name attribute.!

• May be optionally followed by one or more element-filters, e.g. value!!

• dom=javascriptExpression: Find an element by evaluating the JS DOM expression!!

• link=textPattern: Select the link element which contains the text matching the specified pattern!

!• css=cssSelector: Select the element using css selectors. !!• xpath=xpathExpression: Locate the element using an XPath expression.

Page 17: Real World Selenium

Locator Examplesid=loginBox!!name=txtBox!name=username value=myName!

!dom=document.forms['myForm'].myDropdown!dom=document.images[56]!dom=function foo() { return document.links[1]; }; foo();!

!link=Homepage

Page 18: Real World Selenium

Locator Examples: CSS SelectorsThis Selector: Finds

css=p first paragraph tag in the documentcss=a first link in the documentcss=a#id3 link with the matching id elementcss=#linkTest :link link inside the element with the id of linkTestcss=a[name^="foo"] link with a name attribute beginning with ‘foo’css=span#firstChild + span span that follows the span with the id of firstChildcss=div#childTest :last-child last child element of the childTest divcss=div#nthTest :nth-child(2n) 2nd child element of the nthTest divcss=div#linkTest a first link inside the linkTest elementcss=a[class~="class2"] the link that has a class containing the word ‘class2’css=input[type="text"]:disabled first text input element that is disabledcss=input[type="checkbox"]:checked first checkbox element that is checkedcss=a:contains("foobar") link that contains the text foobarcss=a[name*="foo"][alt] link with a name attribute that contains foo and has an alt attribute

Page 19: Real World Selenium

Locator Examples: XPath Selectors

This Selector: Finds

//img[@alt='The image alt text'] image tag with the given alt text//table[@id='table1']//tr[4]/td[2] 4th row, second cell of table1//a[contains(@href,'#id1')]/@class the class of the link with an href of ‘#id1’//*[text()="right"] the element with internal text of ‘right’//input[@name='name2' and @value='yes'] input field with name of ‘name2’ and value of ‘yes’//input[@type='submit' and @name='send'] submit button with name atribute of ‘send’

//input[@type='radio' and @value='1'] radio button with value of 1

//table[@id=’table1’]/tbody/../td/a[2]@href The link location for the second link in the first table cell of table1//*[contains(text(),'Sample Text')]/..//a[2] Locates the element that has the text "Sample Text", then goes up a level from there and finds the //td[contains(text()),’Label’]/following-sibling::td[1]/a Locates the table cell with the text "Label" and gest the link in the next table cell over

Page 20: Real World Selenium

So let’s look at some tests!Selenium Source:!!https://github.com/SeleniumHQ/selenium!!!Tests located in:!!/java/server/test/org/openqa/selenium/tests

Page 21: Real World Selenium

Selenium Actions• open!

• Opens a specified URL!!• openWindow/selectWindow!

• Opens a popup window; select the popup Window!!• check/uncheck!

• Checks/unchecks a toggle button (checkbox/radio) !!• select!

• Selects an option from a drop-down using an option locator!!• submit!

• Submits the specified form!!!• type! !

• Sets the value of an input field, as if typed into

Page 22: Real World Selenium

More Keystroke Actions• click/clickAndWait!

• Click on a link, button, checkbox or radio button (and wait for the next page to load)!!• clickAt/clickAtAndWait!

• Click on a link, button, checkbox or radio button based on specific coordinates (and wait for the next page to load)!!

• fireEvent!• Simulate triggering an event, along with its corresponding “onevent” handler!!

• focus!• Move the focus to the specified element!!

• keyDown/keyPress/keyUp!• Simulates a user pressing and/or releasing a key!!

• typeKeys!• Simulates keystroke events on the specified element

Page 23: Real World Selenium

Tips on Testing Keystrokes• Sending keystrokes don’t always trigger the corresponding “onevent” JS

methods. You can use the “fireEvent” to make sure the onevent gets fired. !!• The ‘typeKeys’ is a convenience way of not having to enter keydown/keyUp/

keyPress events for each character, however this command often does not have a visible effect on the page. You may need to combine it with a ‘type’ command to both have the text visible in a form as well as send the keystroke events. !

!• The ‘type’ command can also be used to set the value of selectboxes,

checkboxes, etc. To do this, set the value to the value of the option selected, versus the visible text.

Page 24: Real World Selenium

Selenium Actions: Wait• waitForPageToLoad!

• Use after any action that causes a new page to load. Replaces “andWait” !• waitForPopUp!

• Waits for a popup window to appear and load up!• waitForElement(Not)Present!

• Wait until a specific element is found/not on the page!• waitForElement(Not)Visible!

• Wait until a specific element is visible/not visible on the page!• waitForSelectedID/Index/Label/Value!

• Wait until a specified option is selected !• waitForText!

• Wait for specified text on an element !• setTimeout!

• Specifies the amount of time to wait for an action to complete

Page 25: Real World Selenium

Tips On Using Waits• These are going to be critical in testing pages utilizing Ajax!!• When used successfully you should never need to use a “pause” command in your

tests to get around tests failing for not waiting for Ajax code to complete.! !• Use the ‘setTimeout” for page loads or “wait” actions that will take longer typically

than the default timeout. !!• Global Ajax handlers can be very helpful for managing how your pages with Ajax

perform and thus make writing tests a lot simpler. For instance, we disable forms during Ajax calls and display a “loading” animation. Testing that the animation is not visible is a nice extra check on pages using Ajax to make sure that the code has completed before continuing.

Page 26: Real World Selenium

Implicit Waits• Available in Web Driver 2 or as a Selenium IDE user extension!!• Implicit Waits tell Selenium to automatically wait to continue until the locator or

condition is met. ! !• Adds the commands setImplicitWaitLocator to set implicit waits based on the locator

and setImplicitWaitCondition to set implicit waits based on a specific condition (for example, any test for no running Ajax transactions). !

!• Keep in mind that most tools to convert from IDE scripts to Selenium RC (web

driver) code are not going to support user extensions.

Page 27: Real World Selenium

Storing Variables• store (depricated) / storeExpression!

• Stores the expression in the specified variable!!• storeEval!

• Stores the result of evaluating the specified Javascript code snippet !!• storeText!

• Stores the text inside the element specified!!• storeAttribute!

• Stores the value of an element attribute!!• storeLocation!

• Stores the current page URL!!• storeTitle!

• Stores the HTML Title of the page

Page 28: Real World Selenium

Storing Form Data• storeSelectedId(s)!

• Stores the selected Id(s) of the specified selectbox!!• storeSelectedIndex(es)!

• Stores the selected index(s) of the specified selectbox!!• storeSelectedLabel(s)!

Stores the selected index(s) of the specified selectbox!!• storeSelectedValue(s)!

Stores the selected value(s) of the specified selectbox!!• storeSelectOptions!

• Stores all options labels in the specified selectbox!!• storeValue!

• Stores the value of an input field!!• storeChecked!

• Gets whether a checkbox/radio button element is checked

Page 29: Real World Selenium

Storing Alerts, Cookies• storeAlert!

• Stores the message of a JS alert dialog in the specified variable !!

• storeConfirmation!Stores the message of a JS confirmation dialog !!

• storePrompt!Stores the message of a JS question prompt dialog!!

• storeCookieByName!• Stores the value of a cookie

Page 30: Real World Selenium

Some Sample Stored Variables<tr>!! <td>storeExpression</td>!! <td>Mary Jo Sminkey</td>!! <td>fullName</td>!</tr>!<tr>!! <td>assertText</td>!! <td>//table[@id='contactDetailTable']//tr[2]//td</td>!! <td>${fullname}</td>!</tr>!<tr>!! <td>storeText</td>!! <td>css=span.spanProdPrice</td>!! <td>partprice</td>!</tr>!<tr>!! <td>storeEval</td>!! <td>parseFloat(storedVars[partprice])</td>!! <td>totalPrice</td>!</tr>

Page 31: Real World Selenium

Handling Alerts & Prompts• answerOnNextPrompt!

• Sets the answer to response with for the next Javascript prompt !!

• chooseCancelOnNextConfirmation/chooseOkOnNextConfirmation!Stores the response to the next Javascript confirmation dialog !!

• assertAlert/verifyAlert!• Use this to consume the alert and remove it from the browser!!

• assertConfirmation/verifyConfirmation!• Use this to consume the confirmation dialog and remove it from the browser!!

• assertPrompt/verifyPrompt!• Use this to consume the prompt and remove it from the browser

Page 32: Real World Selenium

More on Alerts and Other Dialogs• The proper sequence of commands is to use the “onNext” command as appropriate

for the next item, then the action that will generate the dialog, then the command to “consume” it. !

!• Note that in Selenium IDE you typically will not see JS alerts and dialogs in the

browser. !!• For newer sites, you may want to consider switching to jQuery or other modal

dialogs that are handled by making page elements visible/not visible. These are typically more reliable and easily handled in Selenium tests. !

!• For these dialogs, you typically will be using “waitForElementVisible” and/or

“waitForText” commands to determine when the dialog is showing and the corresponding “Not” version to determine when it’s been removed.

Page 33: Real World Selenium

Working with Cookies• createCookie!

• Adds a new cookie, with path and domain of the page under test as default!

!• deleteAllVisibleCookies!

• Deletes all cookies visible to the current page!!

• deleteCookie!• Delete a named cookie with the specified name and domain

Page 34: Real World Selenium

Logging/Debugging Commands• echo!

• Prints the specified message to the log, also helps debug when viewing the list of tests!

!• captureEntirePageScreenshot !

• Not widely supported but useful for grabbing a screenshot in your tests!!

• highlight!• Briefly changes the background of the specified element to yellow. Similar to the

Highlight Elements plugin!

Page 35: Real World Selenium

Other Types of Commands• mouse events!

• mouseDown, mouseUp, mouseOut, mouseOver, mouseUp, doubleClick, rightClick, etc. !

!• dragAndDrop events!

• dragAndDrop, dragAndDropToObject, setMouseSpeed!!

• more keyboard events!• altKeyDown/Up, controlKeyDown/Up, metaKeyDown/Up, shiftKeyDown/Up!!

• frames!• selectFrame, waitForFrameToLoad, !!

• advanced scripting!• addLocationStrategy, addScript, rollup, runScript, waitForCondition

Page 36: Real World Selenium

Creating Test Suites<html>!<head>! <title>Test Suite</title>!</head>!<body>!<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium">!<tbody>!! <tr><td><b>Test Suite</b></td></tr>!! <tr><td><a href="testLogin.html">Test Login</a></td></tr>!! <tr><td><a href="testShopping.html">Test Shopping</a></td></tr>!! <tr><td><a href="testCheckout.html">Test Checkout</a></td></tr>!</tbody>!</table>!</body>!</html>

Page 37: Real World Selenium

Let’s Look at a Real Site

Classic Industries !!

• Large ecommerce site with 300,000+ product inventory!!

• Heavy use of jQuery and Ajax!!

• Active development in process so frequent updates to production!!

• Some critical areas include product search, user functions and shopping cart/checkout processes

Page 38: Real World Selenium

Some Challenges• Search results always changing due to inventory/stock changing!!• Different messages, checkout process based on type of product(s)

ordered!!• Creating user accounts rely on unique email addresses!

!• Multiple server environments to test on, some using SSL !!• Dev/staging environments already handle some common issues like

test orders, PayPal sandbox usage, etc.

Page 39: Real World Selenium

Handling Dynamic Site Data• Our solution here was to create a page for adding “test products” to use!!

• This page runs stored procedures that are only available on development and staging servers. !!

• The test products are created with specific attributes to make them easy to locate in searches. !!

• The form allows for creating all the different types of products that we will need to test for. !

!• We then store the created product numbers that are output by the test data creation

form to use in our tests

Page 40: Real World Selenium

Demo of Test Data Creation Form

Page 41: Real World Selenium

Demo of Test Data Creation Form, cont.

Page 42: Real World Selenium

Generating Unique Users• We wanted to create users with a real email address in order to verify email sent by

various site actions.!!

• The site normally does not remove users once added, this is a function handled outside the website, but an option might be to add a Delete User function that would run after the tests complete. !!

• Instead we decided to rely on a trick involving gmail accounts. !!

• A gmail address can be modified with a plus sign (+) and random string of characters, and will email to the same base account address. !

!• So for instance, I can use my email account “[email protected]” and add a

random string of characters and use that for a unique email address on the website

Page 43: Real World Selenium

Sample Code for Unique Email Account!<tr>!! <td>store</td>!! <td>mjsminkey</td>!! <td>gMailAccount</td>!</tr>!<tr>!! <td>storeEval</td>!! <td>Math.random().toString(36).slice(5)</td>!! <td>emailString</td>!</tr>!<tr>!! <td>store</td>!! <td>javascript{storedVars['gMailAccount'] + "+" + storedVars['emailString'] + "@gmail.com";}</td>!! <td>email</td>!</tr>

Page 44: Real World Selenium

Running Test Suites on Different Servers• Both the IDE and the tests themselves allow for a baseURL!!

• However, it can be tedious to have to change these anytime you want to run on a different URL!!

• Instead, we set up a “setEnvironment” file for each server that creates stored variables for our base URL, SSL URL, any other settings unique to that environment, etc.!!

• All “open” commands or “assertLocation” commands append the baseURL or sslURL variables !

!• We then run this setEnvironment as the first test for our suite for that server. !!• Can include variable settings for commonly used items in our tests

Page 45: Real World Selenium

More Problem-Solving: Whitespace• Most of the assertions for text will treat whitespace as part of the string. !!

• Where possible, consider updating your HTML to remove unnecessary whitespace.!!

• Selenium supports Regex which can be a good option particularly when you are trying to store data and there may be whitespace in the element:!• parseFloat(storedVars['partprice'].replace(/[^0-9-.]/g, ''))!

!• For assertions, you can use contains() to search anywhere in the text for matches:!

• //*[contains(text(),'Sample Text')]/..//a[2]!!

• Alternatively you can use “normalize-space” to strip leading and trailing spaces:!• //td[normalize-space(text())='My Cell Contents']

Page 46: Real World Selenium

More Problem-Solving: CAPTCHA• We prefer to use cfformprotect and this is one area it will greatly help you in not having

to deal with Captchas in your tests!!!

• Most ideal is to set up a test setting for the captcha for your dev/staging environment that will return a known value!!

• If you are using a 3rd party captcha system that does not have a method for testing, you may want to swap it out for a different one that can be configured as above in test environments. !

!• A last resort might be to use JS prompt for the tester to enter the captcha (use

storeEval to create a prompt and store the result in a variable that can then be used to type in the captcha)

Page 47: Real World Selenium

Building a Complete Test: Checkout Test1. Set up environment !

2. Create stored variables to hold a test user’s contact data, etc. !

3. Add some test products to order. !

4. Search for test products and add to the shopping cart. !

5. Create a user account and login to start checkout!

6. Enter shipping address and submit form!

7. Enter billing address and payment and complete order!

8. Verify order confirmation page

Page 48: Real World Selenium

Step 1: Environment Setup

Page 49: Real World Selenium

Step 2: Checkout Stored Variables

Page 50: Real World Selenium

Step 3: Create Test Products

Page 51: Real World Selenium

Step 4: Add Test Products to Cart

Page 52: Real World Selenium

Step 5: Create Account and Start Checkout

Page 53: Real World Selenium

Step 6a: Check Shipping Form Validations

Page 54: Real World Selenium

Step 6b: Shipping State/City Lookup

Page 55: Real World Selenium

Step 6c: Complete Shipping Form

Page 56: Real World Selenium

Step 7a: Check Billing Form Validations

Page 57: Real World Selenium

Step 7b: Submit Billing Form

Page 58: Real World Selenium

Step 8: Verify Confirmation Page


Top Related