310 likes | 574 Views
Selenium – Beyond the Page Object Pattern. By: Sam Woods - Webtrends. Who Am I?. Senior SDET at Webtrends for over a year. Heading up automation efforts including infrastructure, frameworks, processes, continuous integration, logging and reporting, etc . QA/SDET at Microsoft for 13 years.
E N D
Selenium – Beyond the Page Object Pattern By: Sam Woods - Webtrends
Who Am I? • Senior SDET at Webtrends for over a year. • Heading up automation efforts including infrastructure, frameworks, processes, continuous integration, logging and reporting, etc. • QA/SDET at Microsoft for 13 years. • Evolved from manual testing and test planning to automation and finally development of automation infrastructure for the Windows Live organization. • Primary developer of a web UI automation framework for 5+ years that was used by all of Windows Live and throughout the company.
Who is Webtrends? • Webtrends powers digital marketing success. Webtrends is at the forefront of real-time digital marketing relevance and customer experience management through unified customer intelligence. Our industry-leading analytics across mobile, social and web enables marketers to optimize campaigns, maximize customer lifetime value and deliver highly relevant digital brand experiences in real time. • Webtrends dramatically improves digital marketing results for more than 3,500 global brands including: The New York Times, Microsoft, BMW, RIM, China Telecom, China Mobile, CCTV, Tencent QQ, Hitachi, The Associated Press, HSBC, Barclays, Vivo Cellular and Petrobras.
How Does Webtrends Use Selenium? • Selenium is currently used to test 2 distinct products. • Analytics – reporting web site with a number of different report types for different content types (web, mobile, social, etc). • Segments – web application used to create user “segments” and perform queries based on those segments and attributes. • This is truly a “web app”. It is a single dynamic page with thousands of elements and a “canvas” to create visual representations of data that heavily relies on drag and drop.
History of the Page Object Pattern • Created a base class called “PageObject” to programmatically enforce some best practices I had been using in my own automation. Also documented some rules and processes to follow when creating UI automation. • Presented the concept to a number of audiences including to over 300 Microsoft Employees at an Engineering Excellence and Trustworthy Computing Forum. • After leaving Microsoft, found that the Selenium community had begun standardizing on a “Page Object Pattern” that was strikingly similar.
The Evolution of (my) UI Automation • Test Scripts > • Remove Sleeps > • Add Logging and Comments > • Move retries and logging to abstraction > • Move common startup code to xUnit startup class > • Move elements to Page classes > • Create logical helper functions in the page classes > • Create common data classes to drive tests
UI Automation Rules • Never EVER sleep. • Test cases should only access page class members, Page Class should only access abstraction layer, abstraction layer should only access selenium. • Identify elements by ID if possible. • Avoid identifying elements by text. • Avoid identifying elements by xpath (or other means) that include parent or ancestor elements. • Unless including a parent or ancestor can speed up searching for the element. • Validation functions should return bool and the test case should assert.
Exists in POP and not in my Solution • Methods return other PageObjects. • I don’t like this since depending on the data I enter into a form I may be taken to any number of pages including staying on the same page. • Different results for the same action are modeled as different methods. • I prefer a single method that I can execute and then call a validation method depending on the data I passed into the helper. • PageFactory • This is unnecessary since my abstraction uses lazy initialization for all elements.
Exists in my Solution and not in POP • Static class containing all pages and helper functions that can span multiple pages. • Base page class with Navigate function and ValidateLocation function
Lazy Initialization • Create an instance of an element object but doesn’t search for the element on the page until first use (execute a method or access a property) • No need for PageFactory. • No need using POP to create a new function for one simple action such as a click to a single element. • Takes care of ensuring an element exists and is visible upon initialization. • Mostly avoids StaleElementException.
Strongly Typed Element Objects • Rather than a single IWebElement class, there is a Button, Link, Textbox, etc class. • Finds elements faster (based on tag name) • Avoids conflicts if multiple elements with different tag names match the element identifier. • Able to trust intellisense since only methods/properties available for the specific element type show up. • Easy to tell from the code what type of element you’re working with.
Get(related) functions • GetParent, GetChild, GetChildren, GetDescendant, GetDescendants. • Simplifies getting related elements • Want to add GetSibling, GetSiblings, GetAncestor • Speeds up finding elements on large pages if you set an AncestorElement as a property of any element. • One caveat, this can only be executed after already navigating to the page containing the elements, no lazy initialization (can’t call it in your page object constructor)
Automatic Polling • Searches to ensure an element exists and is visible before performing each action. • MaxRetries and WaitBetweenRetries can be set globally or for a specific element, or use the defaults. • Avoids most timing related issues due to pages not finished loading. • Mostly makes logic to wait until a page is displayed unnecessary.
Miscellaneous Goodness • Built in logging • Built in creation of “ElementIdentifier” for logging. • Find elements by any attribute or combination of attributes with exact match or partial match. • DragAndDrop functions (using Actions class). • Get innertext that is not visible (Selenium “feature”). • Automatically switch to most recently opened window (handle links with “target” defined). • Easily define iframe name or index to look for element in, or search in all iframes recursively. • Click with offset
What’s Next? • Releasing abstraction layer as an open source project to the community.
Info/Resources • http://sqa.stackexchange.com • I participate here and there are a number of other people who can answer Selenium questions as well. • E-mail: samwoo111@hotmail.com
Jobs at Webtrends • http://jobvite.com/m?3lH1mfw9