GDAP Project specific TestNG - Selenium - Java

20131120 dumped from Word Doc

GDAP Selenium Implementation  1

Selenium Locators  1

Page Objects  2

GDAPCommon utility class  3

IFrames used for TinyMCE rich text editor 3

How did I get to here re methodology: 5

Selenium IDE vs driven by a programming language  5

Issues re principles: 5

Why no PageFactory?  6

Locators mapping in page objects  6

Specific PageObject notes/oddities  7

Common: 7

PageCommon  7

PageItemGroup (Collection of classes) 7

PageItemGroup_Header 7

PageItemGroup_Items  7

PageItemGroup_Workbench  8

PageJob_List 8

PageJob_Selected  9

PageLogin  9

PageMoveEntity  9

GDAP Selenium Implementation



  • Eclipse Java EE edition
  • Selenium Java Client
  • Selenium Server Standalone

Selenium Locators

Selenium finds elements ‘by’ a locator string & type

A locator string & type can be resolved to an instance of the By class:

By elementByLocator =“username”);

By elementByLocator = By.xpath(“li[contains(@class,'selected')]/child:: a[span[.='Jobs']]”);

A By object can be passed into various Selenium functions for actions/asserts

return driver.findElement(by).getText();


Page Objects


Each application page (or logically separate functional part of a page) is a Java class modelled on the Page Object concept.

Page Objects are intended to map Application pages to make them accessible to tests

  • Each is it’s own class
  • Provide a self contained testing interface to a part of the application by providing (and abstracting):
    • locators to make elements on the application page accessible to tests
    • services as available to a user
      • services always self assert where possible, (i.e. create job action asserts job was created)
      • Where a service moves to another PageObject, returns that PageObject to model the flow between pages.  (In the event the new PageObject constructor fails this also allows us to trace where it was created from)
  • Reduces maintenance in the event a service or locator changes


Page Object layout


Within each Page Object class we have fairly consistent sections

  • Constructor:
    • Always calls own assertCommonElements method to verify are on the expected page
  • Location mapping
    • maps all elements on the page that require interaction
      • always return Selenium ‘By’ object
      • can be:
        • Static (fixed)
        • Dynamic (a method that accepts a parameter, ie Job State ‘In Draft’)
        • Named as byXxxxxx to indicate is a By object
      • *** Document SINGLEELEMENT enum mechanism here ***
      • *** Document dynamic selectors here (ie row by, pagination by page no etc) ***
  • Query state
    • Methods to query the state of the page i.e. doesTitleExist
    • Use by page Object actions (below) or directly in test cases (Violation of test encapsulation here?)
  • Asserts
    • Methods that performed canned asserts to check elements on locators
    • Can take parameters to pass through to dynamic locators
    • assertCommonElements must exist for use by the page object constructor
    • If an assert fails the test fails
  • Actions:
    • Methods that represent a user interaction (service) on the page
    • Method name should reflect the action
    • If an action results in moving to another page or opens another functional area as mapped by a different page object, returns the new page object representing the new page
    • Where possible if an action performs any type of page change (display / update / create application entity (i.e. job) where possible it should also self assert the change.


GDAPCommon utility class


Hold common functionality:

  • Constants
  • Enums for parameters, (eg Job states, user roles)
  • Enums for picklists
  • TestNG specific functionality
  • Start / Stop browser & application
  • Logging to test Output utilities
  • Assert ‘waitFor’ helpers
  • Methods for querying state of elements (e.g. isElementPresent, getElementText)
  • Element actions (eg click, clearAndEnterText)


IFrames used for TinyMCE rich text editor

  • Each richtext field exists as a hidden textarea tag (escaped from what I can see)
  • Associated with each per above is an IFrame containing TinyMCE editor, uses above as both source & target

What does the user interact with?

  • The IFrame content

So to verify the content we need to read from the IFrame & to input data, we need to type into the IFrame editor

To access elements within IFrames from Selenium requires the Selenium focus to switch to the target IFrame before performing the action

  • Use driver.switchTo.frame(locator)
  • Use driver.switchTo().defaultContent() to get back to top of DOM



How did I get to here re methodology:

Selenium IDE vs driven by a programming language

IDE initially:

Started with the IDE, spent a fair amount of time mapping locators into user-extensions.js then started building scripts before quickly running into issues:

  • Readability: scripts very difficult to just look at
  • Abstraction/encapsulation: difficult & clunky to modularise test functions & pass variables
  • Extensibility: limited
  • Maintainability: difficult for all the above
  • Conditional testing: used flow extension but just more messy scripts

WebDriver & Java:

Why Java:

  • Widest user base
  • Easy to pickup for non java programmers
  • Eclipse quick setup with Selenium / TestNG
  • Solves a lot of the issues re Selenium IDE above

Issues re principles:

Locators: private or public? says:

  • The public methods represent the services that the page offers
  • Try not to expose the internals of the page

BUT: all examples show direct use of locators for asserts, seems to invalidate the above

Page actions: self verify or not? says:

Generally don't make assertions

BUT: for encapsulation and reuse & ease of maintenance, I prefer to have every action where possible self assert

  • Pro: Cuts down on test complexity & makes them quicker to create & maintain
  • Con: means PageObject action methods must be robust & checked for completeness

Why no PageFactory?

Tried using PageFactory initially, but in the end determined that support for it is half baked.  PageFactory works well for pages where each element has a unique ID as it will then dynamically allow calling of WebElements without requiring explicit declaration. But we have complex pages with dta grids etc where ID’s are not possible.

PageFactory locators are of type WebElement / WebElements but most selenium functions accept By objects as locators.

Additionally, when Selenium resolves a WebElement to a actual page element it always expects the WebElement to exist, so custom code is required to simply determine if a WebElement exists on the page to handle the exception.

There were other issues as well…

Locators mapping in page objects

Still experimenting to find best patterns, use Enums where possible for XPath fragments to cut down on coding

Specific PageObject notes/oddities



User display names not modelled, assumes is same as userID

Need to cleanup on test fail, ie log out user

Need to take screenie on test fail & append to test log




Incomplete modelling:

  • No roles rights modelling for asserts


PageItemGroup (Collection of classes)

  • Marlena is coming to review usability.  I suggest there will be changes in this space



Xpath is more or less ok with minor annoyances not worth developer time:

  • Toolbar buttons we look at label text
  • Item counts are positional

Incomplete modelling




Xpath is complex:

  • Grid cell identifiers used in multiple ways, ie target for selecting row as well as specifying target elment but ok
  • Hoping for commonality between grid expanded item detail view & workbench view

With items scrolling out of view suggest be careful choosing between ElementIsPresent & ElementIsVisible

Item Grid issues:

  • Grid columns currently available are just a subset and is not to be built for a while (AndrewS)
  • AndrewS suggest that if we are time pressured the Grid expanded view will be dropped
  • Locators:
    • Grid detail: not all expected fields are there yet.. need to eventually compare with future use case re editing items to ensure full set of fields
    • How to manage available fields by item type?
    • Inter item relationships
  • AndrewS suggests workbench is pretty much fully populated
  • No read only view yet, no idea how much reuse of locators between edit view & read only view
  • Alternative Title is expected to be Rich text but is not
  • Rich text fields are in iFrames so need special handing
  • Need to allow for fields available by item type

Incomplete modelling




Incomplete modelling:

  • Modelling on fields as currently delivered, need to model against requirements once finalised for all 3 item types (if we still have 3 item types by then)
  • Only models the left list portion, refer PageJob_Selected for remainder
  • A job header by state only exists if there are relevant jobs for the current user
  • Job rows are always present even if job list header by state is not selected
  • Need to be careful as we can expand/collapse a job list and leave a selected job element hidden from the users view…
  • In modelling user behaviour, we must always make the list of jobs we are targeting visible before interacting with it including asserts
    • createJobAndVerify: Job type has no default and is currently not mandatory on new job creation, however, it is mandatory in UC201 Job creation during clone item..
    • Models selected job portion of Jobs page
    • Entities list locators & interaction
    • Job history entries
    • Comments
    • Create Entity allows a click on the arrow element separately from the dropdown label, only using the arrow for now



Incomplete modelling:



Incomplete modelling:




Incomplete modelling:

  • Need to login as different rights & check availability of relevant default options
  • Consider: user can have mixed roles




  • Popup

Incomplete modelling: