extensible selenium framework
DESCRIPTION
The Strategies and Concepts of Building a Flexible and Extensible Test Framework Around SeleniumTRANSCRIPT
![Page 1: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/1.jpg)
Building a Flexible & E t ibl F kExtensible Framework Around Selenium
Apple Chow
Santiago Etchebehere
![Page 2: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/2.jpg)
Outline
• Our Challengesg
• Our Design Decisions
• Framework ArchitectureFramework Architecture
• Framework Features
• Our ExperienceOur Experience
• Q & A
![Page 3: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/3.jpg)
Our Challenges
• Frequent Requirement Changesq q g
• Complex Web UI
• Multiple Projects to Testp j
• Limited Resources
• Browsers, PlatformsBrowsers, Platforms
![Page 4: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/4.jpg)
Design Decisions
• Simplicity– Isolating application actions – Utilities for filling forms– Utilities for interacting with tables– AJAX handling utilities– Uniform way to access UI elements– Uniform way to access UI elements
• Flexibility– Grouping of test cases p g– Custom place holders (configuration & data)– Ability to support non-standard UI elements
![Page 5: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/5.jpg)
Design Decisions
• Maintainability/Configurabilityy g y– Externalized configuration
– Reduce data duplication
• Data driven tests– Execute same test against multiple datasets
R d l t t t d d t– Randomly generate structured data
![Page 6: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/6.jpg)
Selected Tools
• Selenium RC (http://www.openqa.org/selenium/)( p p q g )
– Locators
– WaitForCondition xpath://img[@alt=“Google”]
– getEval Name: qDOM: document.f.q
When page first loads Now readyWhen page first loads… Now ready…
Name: btnGselenium.waitForCondition("
selenium.isElementPresent('orderBtn')
&& selenium.isEditable('orderBtn')“,
timeout);
![Page 7: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/7.jpg)
Selected Tools
• TestNG (http://testng.org/doc/index.html)
@DataProvider(name ="customerDataProvider")public Object[][] customerProvider() {...
}
( p g g )
– @Test configurations
– Data providers}
@Test(dataProvider = "customerDataProvider")
public void test(String id String name) {
• Firebug
public void test(String id, String name) {...
}
![Page 8: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/8.jpg)
Framework Architecture
Application Configuration GUI Map Data Map
UI Objects SeleniumHelper Util DataGenerator
Base TestBase Client
Application-Specific Client
Application-Specific Test ClassUses
![Page 9: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/9.jpg)
Application Config
<appconfig><parameters>< t l>htt </ t l><protocol>http</protocol><host>www.google.com</host><port></port>
<pagesXml>googlesearch/uimap.xml</pagesXml>j tX l l h/d t l / j tX l<projectXml>googlesearch/datamap.xml</projectXml>
<browserType>FIREFOX</browserType><browserVersion>2.0</browserVersion><timeout>300000</timeout>/</parameters>
</appconfig>
![Page 10: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/10.jpg)
UI Object
• UI Element Abstraction
• read/write interface
public class TextUIObject implements UIObject{
public String read() {
return helper.getText(getLocator())
}}
public void write(String value) {
helper.type(getLocator(), value);
}
}
![Page 11: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/11.jpg)
UI Map
<page name="searchForm"> < i l t ><uielements>
<uiobject name="search.query" type="text"><locator>q</locator>
</uiobject><uiobject name="search.button“ type="button">
<locator>btnG</locator></uiobject>
</uielements></page>
![Page 12: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/12.jpg)
Common vs. Test-case Data
<category name="search"><data name="defaultSearch"><properties><prop name="search.query">United States</prop><prop name="search.button"/>
</properties></data>
references and o errides</category> references and overrides
<testcase id="googleSearch001"><dataset name="searchSet001"><dataref name="search001Query" ref="search.defaultSearch">
<prop name="search query">Argentina</prop><prop name="search.query">Argentina</prop></dataref>
</dataset></testcase>
![Page 13: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/13.jpg)
UI Object and Data Mapping
<page name="searchForm"><data name=“searchData"><properties>
<prop name="search.query">United States</prop>
<prop name="search.button"/>
<page name= searchForm > <uielements><uiobject name="search.query"type="text"><locator>q</locator>
</uiobject> p p /</properties></data>
</uiobject>
<uiobject name="search.button"type="button”><locator>btnG</locator>
</ i bj t></uiobject></uielements>
</page>
…seleniumHelper.fillForm(“searchForm”, “searchData”);…
![Page 14: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/14.jpg)
Application Client
• Contains methods to abstract interaction with your application.
• Uses Selenium (SeleniumHelper) to emulate the user action with the browser, using information from configuration files.
• Simplifies test case writing.
![Page 15: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/15.jpg)
Application Test
• Implements the test cases by feeding the client methods with test case specific data.
• Uses Client's high level• Uses Client s high level method to implement the tests.
V ifi th t t t h• Verifies the output matches the expected result.
![Page 16: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/16.jpg)
Test Case flow
![Page 17: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/17.jpg)
Test Case flow
![Page 18: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/18.jpg)
Test Case flow
![Page 19: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/19.jpg)
Test Case flow
![Page 20: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/20.jpg)
GoogleSearch Example
• Clients (GoogleSearchClient)
• Tests: hierarchy (e.g. GoogleSearchTest)
BaseClient BaseTest
G l S hCli t
BaseClient
Uses
BaseTest
G l S hT tGoogleSearchClient Uses GoogleSearchTest
... public void basicSearchTest(DataSet dataset){assertNotEmpty(client.basicSearch(
dataSet.getDataObject("searchData"));...
...
public TableObject basicSearch(data);
public TableObject advancedSearch(data);
...
![Page 21: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/21.jpg)
Advanced Features
• AJAX Handling Utilities
• Custom UI Objects & Decorators
• Table Objects j
• Placeholders
• Data Generator
• Database Support
![Page 22: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/22.jpg)
AJAX Handling (Loaded Condition)
<page name="iGoogle"><page name="search"><loaded-condition><loaded-condition> selenium.isElementPresent("q") &&selenium.isElementPresent("btnG")
</loaded-condition>…
100100
…seleniumHelper.waitForPageToLoad(“iGoogle.search”);…
![Page 23: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/23.jpg)
AJAX Handling (Reload Trigger)
<page name="searchResults"><loaded-condition> ... </loaded-condition><uiobject name="nextLink" type="anchor" reloadTrigger="searchResults">
<locator>//a[text()='Next']</locator>ocato //a[te t() e t ] / ocato...
![Page 24: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/24.jpg)
Custom UI Object
<uiobject name="elapsedTime"
type="SuggestTextBox">gg<locator>q</locator>
...
public class SuggestTextBox extends AbstractUIObject {public class SuggestTextBox extends AbstractUIObject {
...
public void write(SeleniumHelper helper, String value) {
for (char c : value.toCharArray()) {for (char c : value.toCharArray()) {
helper.type(this.getLocator(), c);
helper.wait(1000);
}
}
...
![Page 25: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/25.jpg)
UI Object Decorators
<uiobject name="creditCardNumber" type="text"><locator>...</locator>
bli l BlurDecorator t d UIObj tD t {
<decorator>BlurDecorator</decorator>
...
public class BlurDecorator extends UIObjectDecorator {
...
public void write(String value) {
decoratedObject.write(value);
selenium.fireEvent(decoratedObject.getLocator(),"blur");
}
![Page 26: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/26.jpg)
Table Object
<table name="questionsTable" ><locator>//table[@id='questions']</locator>
<uiobject name="unreadQuestions" type="img"><locator>tr[${rownum}]/td[2]/img</locator>
</uiobject>
<uiobject name=“subject" type="anchor"><l t >t [${ }]/td[3]/ </l t ><locator>tr[${rownum}]/td[3]/a</locator>
...
...
TableObject questions = new TableObject("questionsTable");
Map<String, String> firstRow = questions.getRow(1);String subject = questions.readCell(1,3);questions writeCell(1 "subject");questions.writeCell(1, subject );...
![Page 27: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/27.jpg)
Placeholders
<appconfig>...• Configuration ...
<host>${sys.testHost}</host><user>${env.USER_NAME}<user>
...</appconfig>
• UI Object
• Data
...<locator>//div[@id='results']/span[${paginationResultNum}]</locator>
......
<data name=“userProfile"><properties>
< “ “> ${ti t }</ ><prop name=“username“>user_${timestamp}</prop> <prop name="name">${dataGenerator.string(10)}</prop><prop name="email">${dataGenerator.email}</prop><prop name="age">${dataGenerator.regex([1..9][0..9])}</prop>
</properties>/</data>
![Page 28: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/28.jpg)
Automation Process
1. Define application specific settings (e.g. application URL, browser)
2. Define UI elements map
3. Implement an application client to abstract application actions
4. Define common and test case specific data
5. Implement TestNG test cases that map to test case repository
![Page 29: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/29.jpg)
Our Experience
• UI Changes
Location:L ti
Before After
UI Changes
Location:Location:
<uiobject name="location" type="text"><locator>location</locator>
<uiobject name="location" type="select"><locator>location</locator><locator>location</locator>
...<locator>location</locator>
...
UIObject location = page.getUIObject("location");
helper.write(location, countryName);}
![Page 30: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/30.jpg)
Our Experience
• Custom UI ObjectCustom UI Object
public class RandomMultiSelectionUIObject extends SelectableUIObject {public String write(String count) {// Generate a list of random values from the possible options. String[] posibleOptions = helper.getSelectOptions(locator);List<String> values = dataGenerator.takeFromList(
A Li t( ibl O ti ) t)Arrays.asList(posibleOptions),count);
...super.write(selectedOptions.toString());
} ...
![Page 31: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/31.jpg)
Our Experience
• i18n Test Data
<testcase id="test_001"><dataset name="usData"><dataref name="criteria" ref="contact.defaultSearch"/>
</d t t>
i18n Test Data
</dataset><dataset name="chineseData"> <dataref name="criteria" ref="contact.defaultSearch"/>
<prop name="keyword">廣告服務</prop></dataref>
</dataset></testcase>
@Test(dataProvider="searchDataProvider")
@Testcase(id="test_001")
void testSearch(DataSet set) {
TableObject resutlsTableObject resutls =
getClient().search(set.getDataObject("criteria"));
![Page 32: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/32.jpg)
Our Team
• Special thanks to:Special thanks to:– Albert Chen
– Alejandro Bolognaj g
– Ariel Rodriguez
– Nicolas Frontini
– Raul Bajales
– Andrew Salamatov
![Page 33: Extensible Selenium Framework](https://reader034.vdocuments.mx/reader034/viewer/2022042507/552838224a7959e23d8b46a0/html5/thumbnails/33.jpg)
Q & A