Automating the Web - An Intro to Selenium

3a34d2b629afdd07f0a84ad333688d8d?s=47 jclarkin
October 10, 2014

Automating the Web - An Intro to Selenium

Automation is a valuable tool that can assist with testing activities. It cannot learn and evaluate the state of software, but it can gather data and reduce effort on repetitive or time intensive tasks.

In this workshop, participants will learn how to create automation for navigating the web. We will cover:
* Setting up your environment with Java, Eclipse, JUnit, and Selenium WebDriver
* Using basic WebDriver commands
* Applying WebDriver Selectors
* Exposing web pages via modern browser dev tools
* Authoring syntax of JUnit scripts
* Implementing the Page Object pattern

Sample code available at: https://github.com/jclarkin/intro2selenium

3a34d2b629afdd07f0a84ad333688d8d?s=128

jclarkin

October 10, 2014
Tweet

Transcript

  1. 2.

    THE FOLLOWING PRESENTATION HAS BEEN RATED TESTERS STRONGLY CAUTIONED PG-13

    SOME MATERIAL MAY BE INAPPROPRIATE FOR CHILDREN UNDER 13 CODING SKILLS WEB AUTOMATION LEARNING & GROWTH Twitter @_jrwc http://about.me/jclarkin
  2. 4.

    - Name - Current Job Role - Previous Job Experience

    - Experience with Test Automation - Favorite TV Show Introductions Jonathan Clarkin | @_jrwc | #KWSQA
  3. 5.

    - Software Engineer - Team Leader - Visual Designer -

    Mobile Developer - Software Architect Introductions: Me Jonathan Clarkin | @_jrwc | #KWSQA - Test Engineer - Automation Tools Researcher - …
  4. 7.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more ! Jonathan Clarkin | @_jrwc | #KWSQA Objectives
  5. 8.

    - Objectives at the beginning - Ask Questions - Ask

    for Help - Answer Questions - Slides will be available after the workshop Workshop Fundamentals Jonathan Clarkin | @_jrwc | #KWSQA
  6. 9.

    - Coding Experience Level: Beginner - Automation Experience Level: Beginner

    - It’s OK to leave (and come back) Minimize disruptions Setting Expectations Jonathan Clarkin | @_jrwc | #KWSQA
  7. 10.
  8. 12.

    To facilitate testing by ... - detecting changes in a

    product (via checks) - reducing effort on repetitive activities - eliminating human error setting up data - minimizing time intensive tasks Why Automate? Jonathan Clarkin | @_jrwc | #KWSQA
  9. 13.

    It only does what we tell it to do Automation

    Is not Smart Jonathan Clarkin | @_jrwc | #KWSQA
  10. 16.

    Nope But it is another useful skill in our tool-belts

    :) Why Automate? Testers Need To Code? Jonathan Clarkin | @_jrwc | #KWSQA
  11. 17.

    Why Automate? Areas of Testing Jonathan Clarkin | @_jrwc |

    #KWSQA (credit: Brian Marick, Lisa Crispin)
  12. 19.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more: Looping, Windows, Page Objects ... Testers Need To Code? Objectives Jonathan Clarkin | @_jrwc | #KWSQA
  13. 20.

    A fancy application, like Notepad/TextEdit… but Designed to make coding

    in Java easier (thank you content assist) What is Eclipse Jonathan Clarkin | @_jrwc | #KWSQA
  14. 21.

    A Java framework designed for creating and reporting on checks

    - Test runner to execute checks - Collection of assertion rules - Results formatter What is JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  15. 22.

    An automation framework for interacting with browsers and the web

    - Created in 2004 by ThoughtWorks - Open Source and Popular - Cross browser and cross platform What is Selenium WebDriver Jonathan Clarkin | @_jrwc | #KWSQA
  16. 23.
  17. 24.

    - Firefox - Chrome - Safari - Internet Explorer 10+

    Modern Browser Jonathan Clarkin | @_jrwc | #KWSQA
  18. 30.

    Get a copy of Selenium WebDriver for Java (Zip contains

    JUnit) Download URL: http://docs.seleniumhq.org/download/ Selenium & JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  19. 31.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  20. 32.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  21. 34.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  22. 35.

    1. Unzip Selenium 2. Launch Eclipse Setup Eclipse + Selenium

    + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  23. 36.

    1. Unzip Selenium 2. Launch Eclipse Setup Eclipse + Selenium

    + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  24. 37.

    1. Unzip Selenium 2. Launch Eclipse Setup Eclipse + Selenium

    + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  25. 38.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  26. 39.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  27. 40.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  28. 41.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  29. 42.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  30. 43.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  31. 44.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  32. 45.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Add all Selenium Jars • The two JARs in the root folder • All in the JARs in the /libs/ subfolder Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  33. 46.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  34. 47.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  35. 48.

    1. Unzip Selenium 2. Launch Eclipse 3. Create a new

    Project 4. Add External JARs Done! Setup Eclipse + Selenium + JUnit Jonathan Clarkin | @_jrwc | #KWSQA
  36. 49.
  37. 51.

    Right-Click on the file and select Run As > JUnit

    Test (detailed explanation on running tests will be covered later) TEST IT
  38. 52.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more: Looping, Windows, Page Objects ... Jonathan Clarkin | @_jrwc | #KWSQA Objectives
  39. 55.
  40. 56.

    A class is a block of code used to encapsulate

    a bunch of: - Variables - Structures - Methods Classes Jonathan Clarkin | @_jrwc | #KWSQA
  41. 61.

    Classes Example Matches the folder structure Matches the filename Everything

    else is part of the Java language conventions Jonathan Clarkin | @_jrwc | #KWSQA
  42. 62.

    Classes Example Matches the folder structure Matches the filename Everything

    else is part of the Java language conventions Purple signifies special reserved words Jonathan Clarkin | @_jrwc | #KWSQA
  43. 63.

    Classes Example Matches the folder structure Matches the filename Everything

    else is part of the Java language conventions Purple signifies special reserved words If there is a // in front of a line, it is a comment zone Jonathan Clarkin | @_jrwc | #KWSQA
  44. 65.
  45. 66.

    A method is a function: a small chunk of executable

    instructions Methods Jonathan Clarkin | @_jrwc | #KWSQA
  46. 69.

    Methods A method ! It should have a memorable unique

    name Jonathan Clarkin | @_jrwc | #KWSQA
  47. 70.

    Methods It should have a memorable unique name This specifies

    whether other classes can see the logic public vs. private (for us: always public) A method ! Jonathan Clarkin | @_jrwc | #KWSQA
  48. 71.

    Methods This specifies whether other classes can see the logic

    public vs. private (for us: always public) This specifies whether the logic gives back an answer (for our tests, they will all be void) A method ! It should have a memorable unique name Jonathan Clarkin | @_jrwc | #KWSQA
  49. 72.

    Methods A method ! It should have a memorable unique

    name This specifies whether other classes can see the logic public vs. private (for us: always public) This specifies whether the logic gives back an answer (for our tests, they will all be void) All logic goes here Jonathan Clarkin | @_jrwc | #KWSQA
  50. 76.

    Test Methods Only real difference is this: @Test import is

    a way to get access to code in other files. In this case, we’re using the magic of the Test class Jonathan Clarkin | @_jrwc | #KWSQA
  51. 77.

    Test Methods Only real difference is this: @Test import is

    a way to get access to code in other files. In this case, we’re using the magic of the Test class You can have multiple tests in the same file Jonathan Clarkin | @_jrwc | #KWSQA
  52. 81.

    Assertions This import gets us access to Asserts This is

    an assert. In this example we are checking that two things are equal. The value on the left is our expected value, the one of the right is the calculated. Jonathan Clarkin | @_jrwc | #KWSQA
  53. 82.

    Assertions This import gets us access to Asserts This is

    an assert. In this example we are checking that two things are equal. The value on the left is our expected value, the one of the right is the calculated. It’s ok if the expected and actual values don’t match. This is when our automation will report to us something is not right. Jonathan Clarkin | @_jrwc | #KWSQA
  54. 87.

    Runs all tests in the Class file Three possible results

    • Pass • Fail • Error Running Tests Jonathan Clarkin | @_jrwc | #KWSQA
  55. 88.

    Three possible results • Pass No problems found • Fail

    Expectation did not happen • Error Something unexpected occurred Running Tests Jonathan Clarkin | @_jrwc | #KWSQA
  56. 89.

    State of the set of tests clearly highlighted by a

    large colourful bar Running Tests Jonathan Clarkin | @_jrwc | #KWSQA
  57. 90.

    What do you predict will be the result of our

    assertion? Try running it. Did the results match your expectations? TEST IT
  58. 91.
  59. 92.

    A String is a bit of text, that can be

    stored for later reference. E.g. Store some data, as type String, using an id name of ‘person’ String person = “Jonathan”; Strings Jonathan Clarkin | @_jrwc | #KWSQA
  60. 93.

    A String is a bit of text, that can be

    stored for later reference. E.g. Store some data, as type String, using an id name of ‘person’ String person = “Jonathan”; Strings Store some data Using an id name of person as type String Jonathan Clarkin | @_jrwc | #KWSQA
  61. 96.

    Other than @Test, the key ones are: @Before @After @BeforeClass

    @AfterClass JUnit Methods Jonathan Clarkin | @_jrwc | #KWSQA
  62. 97.

    Other than @Test, the key ones are: @Before Method to

    run before each test @After Method to run after each test @BeforeClass @AfterClass JUnit Methods Jonathan Clarkin | @_jrwc | #KWSQA
  63. 98.

    Other than @Test, the key ones are: @Before Method to

    run before each test @After Method to run after each test @BeforeClass @AfterClass JUnit Methods Run Class Before commands Test A After commands Before commands Test B After commands End running Class Jonathan Clarkin | @_jrwc | #KWSQA
  64. 99.

    Other than @Test, the key ones are: @Before Method to

    run before each test @After Method to run after each test @BeforeClass @AfterClass JUnit Methods Why ? To create common commands once A Selenium Example might be.. - to login a user before each test - to logout the user after each test Jonathan Clarkin | @_jrwc | #KWSQA
  65. 100.

    Other than @Test, the key ones are: @Before Method to

    run before each test @After Method to run after each test @BeforeClass Method to run once before all tests @AfterClass Method to run once after all tests JUnit Methods Jonathan Clarkin | @_jrwc | #KWSQA
  66. 101.

    Other than @Test, the key ones are: @Before Method to

    run before each test @After Method to run after each test @BeforeClass Method to run once before all tests @AfterClass Method to run once after all tests JUnit Methods Run Class Before Class commands Test A Test B After Class commands End running Class Jonathan Clarkin | @_jrwc | #KWSQA
  67. 102.

    Other than @Test, the key ones are: @Before Method to

    run before each test @After Method to run after each test @BeforeClass Method to run once before all tests @AfterClass Method to run once after all tests JUnit Methods Why ? To create common commands once A Selenium Example might be.. - to open up a browser window once - to close the browser once complete Jonathan Clarkin | @_jrwc | #KWSQA
  68. 103.

    Add @before and @after methods to your class Have them

    print to the console System.out.println(“Something”); TEST IT
  69. 104.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more: Looping, Windows, Page Objects ... Jonathan Clarkin | @_jrwc | #KWSQA Objectives
  70. 106.

    Open a browser Go somewhere nice (url) Fill in form

    fields Click some things Assert that our expectations match reality Close the browser Our mission... Jonathan Clarkin | @_jrwc | #KWSQA
  71. 107.

    Commands differ based on choice of browser. Firefox is the

    Selenium default choice WebDriver driver = new FirefoxDriver(); After this command executes, Firefox should open Mission: Open the Browser Jonathan Clarkin | @_jrwc | #KWSQA
  72. 108.
  73. 109.

    Tell the driver which URL to visit driver.get( “http://en.wikipedia.org” );

    After which, the browser will load to requested page Mission: Go Somewhere Nice Jonathan Clarkin | @_jrwc | #KWSQA
  74. 110.
  75. 111.

    Find a form field on the page WebElement searchfield =

    driver.findElement( By.id(“searchInput”) ); We now have access to this bit of the page. We can interact with it (click, type, etc). Mission: Fill in Form Fields Jonathan Clarkin | @_jrwc | #KWSQA
  76. 112.

    Find the get button and click it searchfield.sendKeys( “The Matrix\n”

    ); Mission: Fill in Form Fields Jonathan Clarkin | @_jrwc | #KWSQA
  77. 113.
  78. 114.

    Assert the page title is what we expect String title

    = driver.getTitle(); assertEquals( title, “The Matrix” ); Mission: Assert Expectations Jonathan Clarkin | @_jrwc | #KWSQA
  79. 115.
  80. 117.
  81. 118.

    ☑ Open a browser ☑ Go somewhere nice ☑ Fill

    in form fields ☑ Click some things ☑ Assert that our expectations match reality ☑ Close the browser Our mission... Jonathan Clarkin | @_jrwc | #KWSQA
  82. 120.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more: Looping, Windows, Page Objects ... Jonathan Clarkin | @_jrwc | #KWSQA Objectives
  83. 122.

    The browser dev-tools are your friend to finding out how

    to uniquely identify the elements on a web page. Dev Tools Jonathan Clarkin | @_jrwc | #KWSQA
  84. 123.

    Accessing the Dev Tools Exact menu option depends on the

    browser Jonathan Clarkin | @_jrwc | #KWSQA
  85. 125.

    Element Selector Click on an element of the page to

    select it Jonathan Clarkin | @_jrwc | #KWSQA
  86. 126.

    With the HTML shown, we can pick how best to

    identify our element: id class xpath Finding Ids, Class Names, and more Jonathan Clarkin | @_jrwc | #KWSQA
  87. 127.
  88. 128.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more: Looping, Windows, Page Objects ... Jonathan Clarkin | @_jrwc | #KWSQA Objectives
  89. 129.
  90. 130.

    There are many ways to grab parts of the web

    page: - Id - Class - Name - Link Text - XPath Selectors Jonathan Clarkin | @_jrwc | #KWSQA
  91. 131.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> Sample DOM Jonathan Clarkin | @_jrwc | #KWSQA
  92. 132.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.id( “eric_h_jung” )); Select By Id Jonathan Clarkin | @_jrwc | #KWSQA
  93. 133.

    On Wikipedia Using Dev Tools Go to Console tab and

    type... $(‘#<someId>’) (replace <someId> with the search field id) TEST IT
  94. 134.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.className( “human” )); Select By Class Jonathan Clarkin | @_jrwc | #KWSQA
  95. 135.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.className( “youth” )); Select By Class Jonathan Clarkin | @_jrwc | #KWSQA
  96. 137.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.name( “address” )); Select By Name Jonathan Clarkin | @_jrwc | #KWSQA
  97. 139.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.partialLinkText( “321 South” )); Select By Partial Link Text Jonathan Clarkin | @_jrwc | #KWSQA
  98. 140.

    Select By Link Text <people> <person id="eric_h_jung" class="human adult"> <href

    name="address" street="321 south st" city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.linkText( “321 South Ave” )); Jonathan Clarkin | @_jrwc | #KWSQA
  99. 141.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.xpath( “/people” )); Means <people> element Means top level Select By XPath Jonathan Clarkin | @_jrwc | #KWSQA
  100. 142.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.xpath( “/people/person” )); Means second level Select By XPath Jonathan Clarkin | @_jrwc | #KWSQA
  101. 143.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.xpath( “/people/person[1]” )); Means first match Select By XPath Jonathan Clarkin | @_jrwc | #KWSQA
  102. 144.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.xpath( “/people/person[2]” )); Means second match Select By XPath Jonathan Clarkin | @_jrwc | #KWSQA
  103. 145.

    Select By XPath <people> <person id="eric_h_jung" class="human adult"> <href name="address"

    street="321 south st" city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.xpath( “//person[2]” )); Means any depth Jonathan Clarkin | @_jrwc | #KWSQA
  104. 147.

    <people> <person id="eric_h_jung" class="human adult"> <href name="address" street="321 south st"

    city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.xpath( “//href[@city=’denver’]” )); @ means attribute Select By XPath Jonathan Clarkin | @_jrwc | #KWSQA
  105. 148.

    Select By XPath <people> <person id="eric_h_jung" class="human adult"> <href name="address"

    street="321 south st" city="denver" state="co" country="usa">321 South St</href> <href name="work_address" street="123 main st" city="arlington" state="ma" country="usa">123 Main St</href> </person> <person id="jed_brown" class="human youth"> <href name"address" street="321 north st" city="atlanta" state="ga" country="usa">321 North St</href> <href name="home_address" street="123 west st" city="seattle" state="wa" country="usa">123 West St</href> <href name="work_address" street="321 south avenue" city="denver" state="co" country="usa">321 South Ave</href> </person> </people> driver.findElements(By.xpath( “//href[@city=’denver’]/..” )); @ means up one level Jonathan Clarkin | @_jrwc | #KWSQA
  106. 149.

    Review of ways to grab parts of the page -

    Id driver.findElement( By.id() ); - Class driver.findElement( By.className() ); - Name driver.findElement( By.name() ); - Link Text driver.findElement( By.linkText() ); driver.findElement( By.partialLinkText() ); - XPath driver.findElement( By.xpath() ); Selectors Jonathan Clarkin | @_jrwc | #KWSQA
  107. 150.

    Least to most brittle selectors (likely to be broken as

    software evolves) - Id - Class - Name - Link Text - XPath Selectors Jonathan Clarkin | @_jrwc | #KWSQA
  108. 151.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more: Looping, Windows, Page Objects ... Jonathan Clarkin | @_jrwc | #KWSQA Objectives
  109. 153.

    Here is a list of common asserts you can use

    to verify your expectations against the actual webpage results Asserts Jonathan Clarkin | @_jrwc | #KWSQA
  110. 154.

    Asserts Statement Description fail( message ) Cause the test to

    immediately fail, reporting the provided String as message assertTrue( message, condition ) Checks that the condition is true, and reports the message if instead it is false. assertFalse ( message, condition ) Checks that the condition is false, and reports the message if instead it is true. assertEquals( message, expected, actual ) Checks that the expected value matches the actual, or reports the message otherwise Be sure to provide a useful message for when checks fail. This will be the first source of information for diagnostics Jonathan Clarkin | @_jrwc | #KWSQA
  111. 155.
  112. 156.
  113. 157.

    Sometimes we need to perform some logic on a collections

    of possible elements driver.findElements(By.className(“div”)); This command gets more than one element Looping a little Jonathan Clarkin | @_jrwc | #KWSQA
  114. 158.

    Using a ‘for-loop’ we can investigate each one for(WebElement elem

    : driver.findElements(By.className(“div”)) ) { // Do something with the specific ‘elem’ element } Looping a little Jonathan Clarkin | @_jrwc | #KWSQA
  115. 159.

    We can check aspects of each one for(WebElement elem :

    driver.findElements(By.className(“div”)) ) { if(elem.getText().equals( “Neo” ) break; } The ‘break’ command quits the loop early Looping a little Jonathan Clarkin | @_jrwc | #KWSQA
  116. 160.
  117. 162.

    Each window has a ‘handle’ to access it String currentWindow

    = driver.getWindowHandle(); Popups - How to Swap Windows Jonathan Clarkin | @_jrwc | #KWSQA
  118. 163.

    The driver has a list of all window handles driver.getWindowHandles();

    Popups - How to Swap Windows Jonathan Clarkin | @_jrwc | #KWSQA
  119. 164.

    We can loop over all window handles and change the

    current window for( String handle : driver.getWindowHandles()) { driver.switchTo().window( handle ); } Popups - How to Swap Windows Jonathan Clarkin | @_jrwc | #KWSQA
  120. 165.

    As we loop, we can check the window title and

    stop looping once we find the right one if( driver.getTitle().equals( “The Matrix” ) ) { break; // This means stop looping immediately } Popups - How to Swap Windows Jonathan Clarkin | @_jrwc | #KWSQA
  121. 166.

    Once looping is done, it is wise to confirm that

    we are on the desired page assertTrue( driver.getTitle().equals( "The Matrix" ) ); Popups - How to Swap Windows Jonathan Clarkin | @_jrwc | #KWSQA
  122. 168.
  123. 170.

    A Page Object is pattern used to create more maintainable

    Selenium tests Page Objects Jonathan Clarkin | @_jrwc | #KWSQA
  124. 171.

    A Page Object is a model of a single page

    of a website. • It exposes the page interactions • It hides the volatile selectors Page Objects Jonathan Clarkin | @_jrwc | #KWSQA
  125. 172.

    public class LandingPage { private WebDriver driver; public LandingPage(WebDriver aDriver)

    { this.driver = aDriver; } } Page Objects Jonathan Clarkin | @_jrwc | #KWSQA - Create a class for the page - It will need a constructor (special type of method) - Let the Page Object access the WebDriver
  126. 173.

    public class LandingPage { // Top Bar private By HOME

    = By.xpath("//*[@id='gn-apple']/a"); private By STORE = By.xpath("//*[@id='gn-store']/a"); private By MAC = By.xpath("//*[@id='gn-mac']/a"); private By IPHONE = By.xpath("//*[@id='gn-iphone']/a"); …[Constructor code]… } Page Objects Jonathan Clarkin | @_jrwc | #KWSQA Define selectors for each bit of the page
  127. 174.

    public class LandingPage { …[Selectors, Constructor code]… public void goToStore()

    { driver.findElement(STORE).click(); } public void searchFor(String something) { driver.findElement(SEARCH).sendKeys(something + "\n"); } } Page Objects Jonathan Clarkin | @_jrwc | #KWSQA Add methods for each interaction Use the defined selectors
  128. 175.

    Now we have a reusable Page Object ! Page Objects

    Jonathan Clarkin | @_jrwc | #KWSQA
  129. 176.

    To use it in a test… • import LandingPage; •

    LandingPage page = new LandingPage( driver ); • page.searchFor( “Apple Juice” ); // Use it Page Objects Jonathan Clarkin | @_jrwc | #KWSQA
  130. 177.

    Creating Page Objects as a complementary activity to creating new

    web pages can be a great way to determine if it was written with testing in mind. Page Objects Jonathan Clarkin | @_jrwc | #KWSQA
  131. 178.
  132. 180.

    PageFactory is a special tool that helps further encapsulate Page

    Object patterns. LoginPage page = PageFactory.initElements(driver, LoginPage.class); PageFactory Jonathan Clarkin | @_jrwc | #KWSQA
  133. 181.

    Pros - Simplifies Selectors in the PageObject - Simplifies the

    constructors of PageObjects Cons - Does not work well with dynamic pages - Slow if PageObject has lots of selectors PageFactory Jonathan Clarkin | @_jrwc | #KWSQA
  134. 184.
  135. 186.

    What if Selenium WebDriver could drive mobile apps as well

    ? Mobile App Automation Jonathan Clarkin | @_jrwc | #KWSQA
  136. 188.

    Appium is an open source tool that helps Selenium WebDriver

    scripts talk to iOS and Android apps Mobile App Automation Jonathan Clarkin | @_jrwc | #KWSQA
  137. 190.

    We write our Selenium tests in the same style as

    before, but now they interact with our apps Mobile App Automation Jonathan Clarkin | @_jrwc | #KWSQA
  138. 191.

    WebDriver driver = new AppiumDriver( new URL("http://127.0.0.1:4723/wd/hub")); WebElement loginUsername =

    driver.findElements(By.className("UIATextField")); loginUsername.sendkeys(“jclarkin”); Mobile App Automation Jonathan Clarkin | @_jrwc | #KWSQA
  139. 192.

    You choose the level of fidelity: - Check against simulated

    app - Check against emulated app - Check against physically wired app - Robotics ! Mobile App Automation Jonathan Clarkin | @_jrwc | #KWSQA
  140. 195.

    Mobile App Automation Jonathan Clarkin | @_jrwc | #KWSQA More

    info at: - Appium: appium.io - Robots: tapsterbot.com
  141. 196.
  142. 197.

    - Setting up Java, Eclipse, JUnit, and Selenium - Authoring

    syntax of JUnit scripts - Using basic Selenium commands - Peeking under the web via browser tools - Applying Selenium Selectors - And more: Looping, Windows, Page Objects ... Review Jonathan Clarkin | @_jrwc | #KWSQA
  143. 198.

    - Grab a pen & some sticky notes - Write

    down : - What new insights have you gained ? - How you feel about the workshop ? - Which questions do you still have ? - How did someone on your team help you? - Place them on the communal wall Activity: Feedback Jonathan Clarkin | @_jrwc | #KWSQA
  144. 199.

    THANK YOU This is not a work of fiction. Names,

    characters, places and incidents are products of the author’s memory. Any resemblance to actual events or locales or persons, living or dead, is not entirely coincidental. All copyright belong to their respective owners. Images and text owned by other copyright holders are used here under the guidelines of the Fair Use provisions of Copyright Law. Special thanks to the Wachoskis and 20th Century Fox for creating The Matrix
  145. 200.