Real World Selenium


Published on

Published in: Software, Technology, Business
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Real World Selenium

  1. 1. Real World Selenium Testing Mary Jo Sminkey! CF Webtools
  2. 2. 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!
  3. 3. 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.
  4. 4. Installing Selenium • Includes IDE (Firefox Plugin) and Web Driver (runs tests on Selenium Server)! •! • 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)
  5. 5. 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.
  6. 6. Useful Plugins • Download at! ! • 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! ! !
  7. 7. 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?
  8. 8. 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
  9. 9. 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>
  10. 10. 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
  11. 11. 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
  12. 12. 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)
  13. 13. 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! !
  14. 14. 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
  15. 15. 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
  16. 16. 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.
  17. 17. Locator Examples id=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
  18. 18. Locator Examples: CSS Selectors This Selector: Finds css=p first paragraph tag in the document css=a first link in the document css=a#id3 link with the matching id element css=#linkTest :link link inside the element with the id of linkTest css=a[name^="foo"] link with a name attribute beginning with ‘foo’ css=span#firstChild + span span that follows the span with the id of firstChild css=div#childTest :last-child last child element of the childTest div css=div#nthTest :nth-child(2n) 2nd child element of the nthTest div css=div#linkTest a first link inside the linkTest element css=a[class~="class2"] the link that has a class containing the word ‘class2’ css=input[type="text"]:disabled first text input element that is disabled css=input[type="checkbox"]:checked first checkbox element that is checked css=a:contains("foobar") link that contains the text foobar css=a[name*="foo"][alt] link with a name attribute that contains foo and has an alt attribute
  19. 19. 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
  20. 20. So let’s look at some tests! Selenium Source:! !! ! ! Tests located in:! ! /java/server/test/org/openqa/selenium/tests
  21. 21. 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
  22. 22. 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
  23. 23. 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.
  24. 24. 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
  25. 25. 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.
  26. 26. 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.
  27. 27. 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
  28. 28. 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
  29. 29. 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
  30. 30. 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>
  31. 31. 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
  32. 32. 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.
  33. 33. 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
  34. 34. 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!
  35. 35. 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
  36. 36. 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>
  37. 37. 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
  38. 38. 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.
  39. 39. 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
  40. 40. Demo of Test Data Creation Form
  41. 41. Demo of Test Data Creation Form, cont.
  42. 42. 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 “” and add a random string of characters and use that for a unique email address on the website
  43. 43. 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'] + "";}</td>! ! <td>email</td>! </tr>
  44. 44. 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
  45. 45. 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']
  46. 46. 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)
  47. 47. Building a Complete Test: Checkout Test 1. 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
  48. 48. Step 1: Environment Setup
  49. 49. Step 2: Checkout Stored Variables
  50. 50. Step 3: Create Test Products
  51. 51. Step 4: Add Test Products to Cart
  52. 52. Step 5: Create Account and Start Checkout
  53. 53. Step 6a: Check Shipping Form Validations
  54. 54. Step 6b: Shipping State/City Lookup
  55. 55. Step 6c: Complete Shipping Form
  56. 56. Step 7a: Check Billing Form Validations
  57. 57. Step 7b: Submit Billing Form
  58. 58. Step 8: Verify Confirmation Page