SlideShare a Scribd company logo
1 of 50
A Cross platform mobile automation
framework
Created & Presented by,
Priti Biyani & Aroj George
ONE PAGE TO TEST THEM
ALL
U.S. AIRLINE MOBILE APP
๏ iOS, Android, iPad, Blackberry, Windows and Mobile Web
๏ Apple Appstore featured app (Travel)
2
CALATRAVA
Custom open source cross platform javascript framework - Calatrava.
https://github.com/calatrava/calatrava
‣ Pure native screens
‣ Pure HTML
‣ HTML + Native widgets
‣ Native + HTML Webviews
3
AUTOMATION
๏ Android
Calabash Android
๏ iOS
Calabash iOS
๏ Mobile Web
Watir Webdriver
4
PROBLEM STATEMENT
5
Create a generic automation framework which could support each of the
three UI automation tools and work seamlessly across both native and
hybrid UI screens
REQUIREMENTS
๏ Should make it easy to add automation. It should make life of QA easy!
๏ Allow reuse of code and help avoid duplication
๏ Promote higher level business/domain oriented thinking instead of low level UI
interactions
๏ Make changes in only one place.
๏ Once automation is done for a feature on one platform, adding the same for other
platforms should be trivial.
๏ Keep it simple, just use basic OO concepts.
6
SOLUTION ANALYSIS
๏The Page Object Model Pattern
๏Requirements satisfied
✓Domain oriented thinking
✓Code reuse/no duplication
✓ Changes in only one place.
✓ Easy to add automation.
7
PAGE OBJECT MODEL SECOND THOUGHTS
๏ ~ 60 screens on iOS and Android
๏ ~ 30 screens on Mobile Web
๏ 60 x 2 platforms + 30 = 150 page object classes!
๏ Screens have similar behavior and expose same services
‣Requirements check
✓Allows reuse of code and helps avoid duplication.
✓Changes are required to be done in only one place.
✓Makes it easy to add automation.
✓Promotes higher level business/domain oriented thinking
➡ So clearly this approach is not scalable.
8
COMMON PAGE OBJECTS PER SCREEN
๏ page objects per screen will solve the class explosion problem.
๏ Requirements satisfied
✓ Should make it easy to add automation. It should make life of QA easy!
✓ Allow reuse of code and help avoid duplication!
✓ Promote higher level business/domain oriented thinking instead of low level UI interactions!
✓ Make change in only one place.
✓ Once automation is done for a feature on one platform, adding the same for other
platforms should be trivial.
9
COMMON PAGE OBJECTS - CONCERNS?
๏ Different automation tool APIs
Element query syntax (xpath/css vs custom calabash syntax)
๏ Different UI actions
click/tap on web/mobile
๏ Different platform implementations for same screen
locator values can vary
๏ UX interactions patterns
for e.g Nav Drawer in Android, the Tab Bar in iOS and the Nav bar in web.
10
COMMON PAGE OBJECTS - MORE CONCERNS ?
๏ No online example of this approach.
๏ Calabash reference uses a different Page Object class for iOS and Android.
11
➡ So is it really possible to have common page objects?
OBJECT MODELING
Lets try and do a Object Modeling exercise!
Single page object class
➡ What are the key fields?
➡ What’s the key behavior?
12
PAGE NAME
13
Page
Name : String
To Refer from feature file
Login Page
Name :“Login”
PAGE IDENTIFIER
14
Page
Name : String
Id : Map
Identify each page uniquely on the
device
{
:web => "//div[@id='payment_info']",
:ios => "all webView css:'#payment_info'",
:droid => "all webView css:'#payment_info'"
}
PAGE ID CLASS
15
PageId
Id : Map
exists? ()
Check if locator specified by id exists on the UI
Calabash Android and IOS:
not query(locator).empty?
Mobile Web (Watir):
Browser.element(:css => locator).present?
ID EXISTS CHECK
16
def exists?
case platform
when ANDROID
query(ui_query).empty?
when IOS
query(ui_query).empty?
when WEB
Browser.element(:css => locator).present?
end
end
DRIVER ABSTRACTION
17
Pag
e
Name : String
Id : PageId
PageId
Field : Map
exists? ()
PageId
Driver
Platform : droid
exists? ()
Driver
Platform : ios
exists? ()
Driver
Platform : web
exists? ()
def exists?(id_map)
locator = id_map[:droid]
begin
opts.merge!(:screenshot_on_error => false)
wait_for_elements_exist([locator],opts)
rescue WaitError
false
end
end
def exists?(id_map)
locator = id_map[:ios]
begin
opts.merge!(:screenshot_on_error => false)
wait_for_elements_exist([locator], opts)
element_exists locator
rescue WaitError
false
end
end
def exists?(id_map, wait=true)
locator = id_map[:web]
begin
Browser.element(:css => locator).wait_until_present if wait
Browser.element(:css => locator).present?
rescue TimeoutError
puts "exists error #{locator}"
false
end
end
ELEMENTS
18
Pag
e
Name : String
Id : PageId
Elements
Element.new({
:web => ‘#save_and_continue_button’,
:ios => "navigationButton marked:'DONE'",
:droid => "* marked:'Done'"
}
Element
Id: Map
click ()
def click
case platform
when ANDROID
touch(query(locator))
when IOS
touch(query(locator))
when WEB
Browser.element(:css => locator).click()
end
end
ELEMENTS DELEGATE TO DRIVER
19
Pag
e
Name : String
Id : Map
Elements
Element
Id : Map
Driver : Driver
click()
Driver
Platform : droid
exists?
click()
Driver
Platform : ios
exists?
click()
Driver
Platform : web
exists?
click()
def click(id_map)
locator = id_map[:droid]
begin
scroll_to locator
rescue RuntimeError
end
touch(query(locator))
wait_for_loader_to_disappear
end
def click(id_map)
locator = id_map[:ios]
begin
scroll_to locator
rescue RuntimeError
end
touch(query(locator))
wait_for_loader_to_disappear
end
def click(id_map)
locator = id_map[:web]
B.element(:css => locator).wait_until_present
B.element(:css => locator).click
wait_for_loader_to_disappear
end
MORE ELEMENTS
20
Pag
e
Name : String
Id : PageId
Element 1: Element
Element 2: Element
….
Element
Driver
Platform : droid
exists?
click()
setText()
getText()
checked()
Textbox
setText()
getText()
id : map
Checkbox
checked?()
check(item)
id : map
Dropdown
select(item)
id : map
Id : Map
Driver : Driver
Driver
Platform : ios
exists?
click()
setText()
getText()
checked()
Driver
Platform : web
exists?
click()
setText()
getText()
checked()
exists? ()
PAGE TRANSITION
21
Login Home Page
def login
click_login_button
wait_for_home_page_to_load
return HomePage.new
end
[ success ]
def <action>
click_button
wait_for_<next_page>_to_load
return <NextPage.new>
end
TRANSITION MODELING
1. driver.click
✓ Driver should be responsible only for UI interaction.
✓ Driver should not know about higher level abstraction Page.
2. element.click
✓ It will not be applicable to all elements.
3. Transition Aware Element
➡ An element that understands page transitions.
22
TRANSITION ELEMENT
23
Pag
e
Name : String
Id : PageId
Elements
Element
Driver
Platform : droid
exists?
click()
setText()
getText()
checked()
Textbox
setText()
getText()
id : map
Checkbox
checked?()
check(item)
id : map
Dropdown
select(item)
id : map
Id : Map
Driver : Driver
Driver
Platform : ios
exists?
click()
setText()
getText()
checked()
Driver
Platform : web
exists?
click()
setText()
getText()
checked()
exists? ()
TransitionElement
click(item)
id : map
TRANSITION ELEMENT
24
@login_button = TransitionElement.new(
{
:web => '#continue_button',
:ios => "* marked:'Login'",
:droid => "* marked:'Login'"
},
{
:to => HomePage,
}
)
Next Page Class
TRANSITION ELEMENT - MULTIPLE TRANSITION
25
Login
Admin
Home Page
Member
Home Page
userType?
[success]
TRANSITION ELEMENT - MULTIPLE TRANSITION
@login_button = TransitionElement.new(
{
:web => '#continue_button',
:ios => "* marked:'Login'",
:droid => "* marked:'Login'"
},
{
:to => [AdminPage, UserPage],
}
) Multiple Transition
TRANSITION ELEMENT - ERROR TRANSITION
Login
Admin Home Page
Member Home Page
userType?
[ SUCCESS ]
[ FAIL ]
TRANSITION ELEMENT - ERROR TRANSITION
@login_button = TransitionElement.new(
{
:web => '#continue_button',
:ios => "* marked:'Login'",
:droid => "* marked:'Login'"
},
{
:to => [AdminPage, UserPage],
:error => Login
}
)
Error Representation
MULTIPLE TRANSITIONS - WRONG TRANSITION
‣ Scenario: If there is a bug in code, app transitions to wrong page from
list of multiple transitions.
‣ Should transition element detect this bug?
✓ but this is application logic
✓ will increase complexity
➡ Tests should take care for assertions of correct page, not the
framework.
TRANSITION ELEMENT
30
def wait_till_next_page_loads(next_pages, error_page)
has_error, found_next_page = false, false
begin
wait_for_element(timeout: 30) do
found_next_page = next_pages.any? { |page| page.current_page?}
has_error = error_page.has_error? if error_page
found_next_page or has_error
end
has_error ? error_page : next_pages.find { |page| page.current_page?}
rescue WaitTimeoutError
raise WaitTimeoutError, "None of the next page transitions were found. Checked for: =>
#{next_page_transitions.join(' ,')}"
end
end
PAGE OBJECT EXAMPLE - SEAT MAP
31
Native Implementation
Common code across platform
Iphone Mobile Web Android
SEAT MAP FEATURE STEP
32
And I select following seat
| origin | destination | flight_number | pax_name | seat_number |
| ORD | JFK | DL3723 | Rami Ron | 9C |
| ORD | JFK | DL3723 | John Black | 10C |
| JFK | ATL | DL3725 | Rami Ron | 12C |
| JFK | ATL | DL3725 | John Black | 13C |
SEATMAP PAGE
33
SeatMap
Name :“Seat map”
Id : {… }
select_seat(pax, flight, seat_number)
SEAT MAP FEATURE STEP
34
And(/^I select following seat$/) do |table|
table.hashes.each do |row|
flight = Flight.new(row['origin'], row['destination'], row[‘flight_number’])
seat_map_page = SeatMap.new
seat_map_page.select_seat row['pax_name'], flight, row['seat_number']
end
end
And I select following seat
| origin | destination | flight_number | pax_name | seat_number |
| ORD | JFK | DL3723 | Rami Ron | 9C |
| ORD | JFK | DL3723 | John Black | 10C |
| JFK | ATL | DL3725 | Rami Ron | 12C |
| JFK | ATL | DL3725 | John Black | 13C |
PAGE OBJECT EXAMPLE
35
class SeatMap < Page
def initialize
@id = PageId.new({
:web => "//div[@id='ism']//div[@id='sb_seat_map_container']",
:ios => "webView css:'#seat_map_container'",
:droid => "webView css:'#seat_map_container'"
})
@leg = Field.element({
:web => "label[@class='dd-option-text'][text()='%s: %s to %s']",
:ios => "label marked:'%s: %s to %s'",
:droid => "* marked:'%s: %s to %s'"
})
@passenger = Field.element({
:web => "//label[@class='dd-option-text'][text()='%s']",
:ios => "label marked:'%s'",
:droid => "* marked:'%s'"
})
@passenger_seat_number_text = Field.element({
:web => "//label[@class='dd-selected-sec-text'][text()='%s']",
:ios => "label {text CONTAINS '%s'}",
:droid => "* marked:'%s'"
})
@seat_button = Field.element({
:web => “//div[@id='seat_%s']",
:ios => "webView css:'#seat_%s'",
:droid => "webView css:'#seat_%s'"
})
PAGE OBJECT EXAMPLE
36
class SeatMap < Page
def select_seat_for_pax_for_leg(flight_leg, pax_name, seat_number)
select_leg flight_leg
select_passenger pax_name
select_seat seat_number
end
def select_leg(flight_leg)
@leg_header.click
@leg.click(flight_leg.flight_number, flight_leg.origin, flight_leg.destination)
end
def select_passenger(pax_name)
@passenger_name_header.click
@passenger.click(pax_name)
end
def select_seat(seat_no)
@seat_button.click(seat_no)
@passenger_seat_number_text.await(seat_no)
end
end
"label marked:'%s: %s to %s'"
"label marked:'%s'"
"webView css:'#seat_%s'"
TRANSITION TO NEXT PAGE
37
class SeatMap < Page
def initialize
@done_button = Field.transition_element({
:web => "#save_and_continue_button",
:ios => "navigationButton marked:'DONE'",
:droid => "* marked:'Done'"
},
{
:to => [SeatsDetails],
})
super(‘Seat Map')
end
def close
@done_button.click
end
end
TRANSITION TO SEATS DETAILS PAGE
38
def verify_seat_details seat_details_page, table
table.hashes.each do |row|
flight = Flight.new(row['origin'], row['destination'], row['flight_number'])
actual_seat_number = seat_details_page.get_seat_number(row[‘pax_name'], flight)
expected_seat_number = row['seat_number']
expect(actual_seat_number).to eq(expected_seat_number)
end
end
And(/^I select following seat$/) do |table|
table.hashes.each do |row|
flight = Flight.new(row['origin'], row['destination'], row[‘flight_number’])
seat_map_page = SeatMap.new
seat_map_page.select_seat row['pax_name'], flight, row['seat_number']
end
seat_details_page = seat_map_page.close
verify_seat_details seat_details_page, table
end
COMMON PAGE OBJECTS - SOLUTION
๏ Different automation tool APIs/ Different UI actions
➡ Driver abstraction
๏ Different platform implementations for same screen
➡ Element locator map.
๏ UX interactions patterns (Nav Drawer / Tab bar /Menu)
➡ How?
39
PRIMARY AND SECONDARY NAVIGATION
40
Iphone Mobile Web Android
MENU/MENU ITEM
41
Menu
Name : String
Id : Map
MenuItems
MenuItem
Name : String
TargetPage : Page
Type : MenuType
MenuButton:TransitionElement
show()
show_secondary_menu(
)
launch (item_name)
def launch(item_name)
show
menu_item = @menu_items[item_name]
show_secondary if menu_item.is_secondary?
menu_item.click
end
click ()
is_secondary? ()
MENU IMPLEMENTATION
42
class Menu
SHOP_AND_BOOK = 'Book'
MY_TRIPS = 'My Trips'
FLIGHT_STATUS = 'Flight Status’
def initialize()
@id = PageId.new({
:web => "//div[@id='home']//ul[@id='home_options']",
:ios => "tabBarButtonLabel marked:'Book'",
:droid => "* id:'drawer_items_list'"
})
@primary_menu_button = Field.element ({ web: ‘#menu', :ios => '', :droid => "* id:'home'" }),
@secondary_menu_button = Field.element ({ web: '', :droid => '', :ios => "* marked:'More'" }),
@menu_items = {
SHOP_AND_BOOK => MenuItem.new(SHOP_AND_BOOK, FlightSearch),
MY_TRIPS => MenuItem.new(MY_TRIPS, MyTrips),
FLIGHT_STATUS => MenuItem.new(FLIGHT_STATUS, FlightStatus, ios: MenuItem::SECONDARY)}
end
def show
@primary_menu_button.click
end
def show_secondary
@secondary_menu_button.click
end
def launch(item_name) . . . end
end
MENU ITEM IMPLEMENTATION
43
class MenuItem
PRIMARY = 1
SECONDARY = 2
attr_accessor :name, :page, :type
def initialize(name, page, type = PRIMARY)
@name = name
@page = page
@type = type
@menu_button = Field.transition_element(
{
:web => "//li[@class='#{@name.downcase}']",
:ios => "label marked:'#{@name}'",
:droid => "WhitneyDefaultTextView id:'drawer_item_text' text:'#{@name}'"
},
{
:to => @page
})
end
def click
@menu_button.click
end
def is_secondary?
@type[Driver.platform] == SECONDARY
end
end
#
MenuItem.new(FLIGHT_STATUS, FlightStatus, ios: MenuItem::SECONDARY)
COMMON PAGE OBJECTS - SOLUTION
✓ Different automation tool APIs
➡ Driver abstraction
✓ Different UI actions
➡ Driver abstraction
✓ Different platform implementations for same screen
➡ Element locator map.
✓ UX interactions patterns (Nav Drawer / Tab bar /Menu)
➡ Menu and Menu Item Abstraction
44
IMPLEMENTATION NOTES
‣ We "require" specific driver class during test execution.
‣ Page registry, can be queried for page object instances.
‣ PageRegistry.get "Login Page”
‣ Rspec Unit Tests
‣ Rake task to create new page classes.
45
FUTURE DIRECTION
‣ Debug Mode
‣ Log debug info like element id, clicks etc…
‣ Slow element locator finder
46
LEARNINGS
‣ QA/Dev Pairing
‣ Use case driven development
‣ Evolution
47
SUMMARY
๏ Good OO design is the key
๏ Good abstractions can help solve hard problems
48
CONCLUSION
49
utomation to support new feature development across the three different platforms requ
just one place.
Reach out to us at
Aroj George @arojp
Priti Biyani @pritibiyani
http://arojgeorge.ghost.io/
http://pritibiyani.github.io/
THANK YOU

More Related Content

What's hot

Being Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentBeing Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentReto Meier
 
Developing AIR for Android with Flash Professional CS5
Developing AIR for Android with Flash Professional CS5Developing AIR for Android with Flash Professional CS5
Developing AIR for Android with Flash Professional CS5Chris Griffith
 
Sample APK Analysis 4 - 55688
Sample APK Analysis 4 - 55688Sample APK Analysis 4 - 55688
Sample APK Analysis 4 - 55688Lin BH
 
10 Golden Rules For Outstanding Titanium Apps
 10 Golden Rules For Outstanding Titanium Apps 10 Golden Rules For Outstanding Titanium Apps
10 Golden Rules For Outstanding Titanium Appsjamessugrue
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentanistar sung
 
Sample APK Analysis 5 - 55688 (Driver Version)
Sample APK Analysis 5 - 55688 (Driver Version)Sample APK Analysis 5 - 55688 (Driver Version)
Sample APK Analysis 5 - 55688 (Driver Version)Lin BH
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material DesignYasin Yildirim
 
Making Money with Adobe AIR
Making Money with Adobe AIRMaking Money with Adobe AIR
Making Money with Adobe AIRAlmog Koren
 
YUI + Accessibility: Welcome the whole world
YUI + Accessibility: Welcome the whole worldYUI + Accessibility: Welcome the whole world
YUI + Accessibility: Welcome the whole worldTed Drake
 
Introduction aux progressive web apps
Introduction aux progressive web appsIntroduction aux progressive web apps
Introduction aux progressive web apps✅ William Pinaud
 
Developing AIR for Mobile with Flash Professional CS5.5
Developing AIR for Mobile with Flash Professional CS5.5Developing AIR for Mobile with Flash Professional CS5.5
Developing AIR for Mobile with Flash Professional CS5.5Chris Griffith
 
Native i os, android, and windows development in c# with xamarin 4
Native i os, android, and windows development in c# with xamarin 4Native i os, android, and windows development in c# with xamarin 4
Native i os, android, and windows development in c# with xamarin 4Xamarin
 
Visual Automation Framework via Screenshot Comparison
Visual Automation Framework via Screenshot ComparisonVisual Automation Framework via Screenshot Comparison
Visual Automation Framework via Screenshot ComparisonMek Srunyu Stittri
 
Refactor Large applications with Backbone
Refactor Large applications with BackboneRefactor Large applications with Backbone
Refactor Large applications with BackboneColdFusionConference
 
Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011
Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011
Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011Max Katz
 
Getting started with Google Android - OSCON 2008
Getting started with Google Android - OSCON 2008Getting started with Google Android - OSCON 2008
Getting started with Google Android - OSCON 2008sullis
 
Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Antonio Peric-Mazar
 
Mobile Cross-Platform App Development in C# with Xamarin
Mobile Cross-Platform App Development in C# with XamarinMobile Cross-Platform App Development in C# with Xamarin
Mobile Cross-Platform App Development in C# with XamarinNick Landry
 

What's hot (19)

Being Epic: Best Practices for Android Development
Being Epic: Best Practices for Android DevelopmentBeing Epic: Best Practices for Android Development
Being Epic: Best Practices for Android Development
 
Developing AIR for Android with Flash Professional CS5
Developing AIR for Android with Flash Professional CS5Developing AIR for Android with Flash Professional CS5
Developing AIR for Android with Flash Professional CS5
 
Sample APK Analysis 4 - 55688
Sample APK Analysis 4 - 55688Sample APK Analysis 4 - 55688
Sample APK Analysis 4 - 55688
 
10 Golden Rules For Outstanding Titanium Apps
 10 Golden Rules For Outstanding Titanium Apps 10 Golden Rules For Outstanding Titanium Apps
10 Golden Rules For Outstanding Titanium Apps
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 
Sample APK Analysis 5 - 55688 (Driver Version)
Sample APK Analysis 5 - 55688 (Driver Version)Sample APK Analysis 5 - 55688 (Driver Version)
Sample APK Analysis 5 - 55688 (Driver Version)
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material Design
 
Making Money with Adobe AIR
Making Money with Adobe AIRMaking Money with Adobe AIR
Making Money with Adobe AIR
 
YUI + Accessibility: Welcome the whole world
YUI + Accessibility: Welcome the whole worldYUI + Accessibility: Welcome the whole world
YUI + Accessibility: Welcome the whole world
 
Introduction aux progressive web apps
Introduction aux progressive web appsIntroduction aux progressive web apps
Introduction aux progressive web apps
 
Developing AIR for Mobile with Flash Professional CS5.5
Developing AIR for Mobile with Flash Professional CS5.5Developing AIR for Mobile with Flash Professional CS5.5
Developing AIR for Mobile with Flash Professional CS5.5
 
Native i os, android, and windows development in c# with xamarin 4
Native i os, android, and windows development in c# with xamarin 4Native i os, android, and windows development in c# with xamarin 4
Native i os, android, and windows development in c# with xamarin 4
 
Visual Automation Framework via Screenshot Comparison
Visual Automation Framework via Screenshot ComparisonVisual Automation Framework via Screenshot Comparison
Visual Automation Framework via Screenshot Comparison
 
Refactor Large applications with Backbone
Refactor Large applications with BackboneRefactor Large applications with Backbone
Refactor Large applications with Backbone
 
Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011
Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011
Mobile Development Choices: Native Apps vs. Web Apps at JAX 2011
 
Getting started with Google Android - OSCON 2008
Getting started with Google Android - OSCON 2008Getting started with Google Android - OSCON 2008
Getting started with Google Android - OSCON 2008
 
Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...Using API platform to build ticketing system (translations, time zones, ...) ...
Using API platform to build ticketing system (translations, time zones, ...) ...
 
Mobile Cross-Platform App Development in C# with Xamarin
Mobile Cross-Platform App Development in C# with XamarinMobile Cross-Platform App Development in C# with Xamarin
Mobile Cross-Platform App Development in C# with Xamarin
 
20150319 testotipsio
20150319 testotipsio20150319 testotipsio
20150319 testotipsio
 

Similar to One Page to Test Them All!

Skill Session - Web Multi Device
Skill Session - Web Multi DeviceSkill Session - Web Multi Device
Skill Session - Web Multi Devicefilirom1
 
Responsive web design & mobile web development - a technical and business app...
Responsive web design & mobile web development - a technical and business app...Responsive web design & mobile web development - a technical and business app...
Responsive web design & mobile web development - a technical and business app...Atos_Worldline
 
Puppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolPuppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolMiki Lombardi
 
Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...
Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...
Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...olrandir
 
Mobile Web on Touch Event and YUI
Mobile Web on Touch Event and YUIMobile Web on Touch Event and YUI
Mobile Web on Touch Event and YUIMorgan Cheng
 
Empowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris MillsEmpowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris MillsFITC
 
Empowering the Mobile Web - Mills
Empowering the Mobile Web - MillsEmpowering the Mobile Web - Mills
Empowering the Mobile Web - MillsCodemotion
 
Empowering the "mobile web"
Empowering the "mobile web"Empowering the "mobile web"
Empowering the "mobile web"Chris Mills
 
Cross platform mobile app development with Xamarin
Cross platform mobile app development with XamarinCross platform mobile app development with Xamarin
Cross platform mobile app development with XamarinPranav Ainavolu
 
Developing Applications for WebOS
Developing Applications for WebOSDeveloping Applications for WebOS
Developing Applications for WebOSChuq Von Rospach
 
App innovationcircles xamarin
App innovationcircles xamarinApp innovationcircles xamarin
App innovationcircles xamarinMohit Chhabra
 
Xamarin Test Cloud - from zero to hero in automated ui testing
Xamarin Test Cloud - from zero to hero in automated ui testingXamarin Test Cloud - from zero to hero in automated ui testing
Xamarin Test Cloud - from zero to hero in automated ui testingGeert van der Cruijsen
 
Desktop Developer’s Guide to Mobile with Visual Studio Tools for Xamarin
Desktop Developer’s Guide to Mobile with Visual Studio Tools for XamarinDesktop Developer’s Guide to Mobile with Visual Studio Tools for Xamarin
Desktop Developer’s Guide to Mobile with Visual Studio Tools for XamarinXamarin
 
Android 3.0 Portland Java User Group 2011-03-15
Android 3.0 Portland Java User Group 2011-03-15Android 3.0 Portland Java User Group 2011-03-15
Android 3.0 Portland Java User Group 2011-03-15sullis
 
Telerik Kendo UI Overview
Telerik Kendo UI OverviewTelerik Kendo UI Overview
Telerik Kendo UI OverviewEd Musters
 
Android - Open Source Bridge 2011
Android - Open Source Bridge 2011Android - Open Source Bridge 2011
Android - Open Source Bridge 2011sullis
 
openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010Patrick Lauke
 
IBDesignable - CocoaConf Seattle 2014
IBDesignable - CocoaConf Seattle 2014IBDesignable - CocoaConf Seattle 2014
IBDesignable - CocoaConf Seattle 2014Martin Nash
 
Making your site mobile-friendly - DevCSI Reading 21.07.2010
Making your site mobile-friendly - DevCSI Reading 21.07.2010Making your site mobile-friendly - DevCSI Reading 21.07.2010
Making your site mobile-friendly - DevCSI Reading 21.07.2010Patrick Lauke
 

Similar to One Page to Test Them All! (20)

Skill Session - Web Multi Device
Skill Session - Web Multi DeviceSkill Session - Web Multi Device
Skill Session - Web Multi Device
 
Responsive web design & mobile web development - a technical and business app...
Responsive web design & mobile web development - a technical and business app...Responsive web design & mobile web development - a technical and business app...
Responsive web design & mobile web development - a technical and business app...
 
Puppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing ToolPuppeteer - A web scraping & UI Testing Tool
Puppeteer - A web scraping & UI Testing Tool
 
Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...
Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...
Android: the Single Activity, Multiple Fragments pattern | One Activity to ru...
 
Mobile Web on Touch Event and YUI
Mobile Web on Touch Event and YUIMobile Web on Touch Event and YUI
Mobile Web on Touch Event and YUI
 
Empowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris MillsEmpowering the “Mobile Web” with Chris Mills
Empowering the “Mobile Web” with Chris Mills
 
Empowering the Mobile Web - Mills
Empowering the Mobile Web - MillsEmpowering the Mobile Web - Mills
Empowering the Mobile Web - Mills
 
Empowering the "mobile web"
Empowering the "mobile web"Empowering the "mobile web"
Empowering the "mobile web"
 
Cross platform mobile app development with Xamarin
Cross platform mobile app development with XamarinCross platform mobile app development with Xamarin
Cross platform mobile app development with Xamarin
 
Developing Applications for WebOS
Developing Applications for WebOSDeveloping Applications for WebOS
Developing Applications for WebOS
 
App innovationcircles xamarin
App innovationcircles xamarinApp innovationcircles xamarin
App innovationcircles xamarin
 
Xamarin Test Cloud - from zero to hero in automated ui testing
Xamarin Test Cloud - from zero to hero in automated ui testingXamarin Test Cloud - from zero to hero in automated ui testing
Xamarin Test Cloud - from zero to hero in automated ui testing
 
Desktop Developer’s Guide to Mobile with Visual Studio Tools for Xamarin
Desktop Developer’s Guide to Mobile with Visual Studio Tools for XamarinDesktop Developer’s Guide to Mobile with Visual Studio Tools for Xamarin
Desktop Developer’s Guide to Mobile with Visual Studio Tools for Xamarin
 
Swift
SwiftSwift
Swift
 
Android 3.0 Portland Java User Group 2011-03-15
Android 3.0 Portland Java User Group 2011-03-15Android 3.0 Portland Java User Group 2011-03-15
Android 3.0 Portland Java User Group 2011-03-15
 
Telerik Kendo UI Overview
Telerik Kendo UI OverviewTelerik Kendo UI Overview
Telerik Kendo UI Overview
 
Android - Open Source Bridge 2011
Android - Open Source Bridge 2011Android - Open Source Bridge 2011
Android - Open Source Bridge 2011
 
openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010openMIC barcamp 11.02.2010
openMIC barcamp 11.02.2010
 
IBDesignable - CocoaConf Seattle 2014
IBDesignable - CocoaConf Seattle 2014IBDesignable - CocoaConf Seattle 2014
IBDesignable - CocoaConf Seattle 2014
 
Making your site mobile-friendly - DevCSI Reading 21.07.2010
Making your site mobile-friendly - DevCSI Reading 21.07.2010Making your site mobile-friendly - DevCSI Reading 21.07.2010
Making your site mobile-friendly - DevCSI Reading 21.07.2010
 

More from Thoughtworks

Design System as a Product
Design System as a ProductDesign System as a Product
Design System as a ProductThoughtworks
 
Designers, Developers & Dogs
Designers, Developers & DogsDesigners, Developers & Dogs
Designers, Developers & DogsThoughtworks
 
Cloud-first for fast innovation
Cloud-first for fast innovationCloud-first for fast innovation
Cloud-first for fast innovationThoughtworks
 
More impact with flexible teams
More impact with flexible teamsMore impact with flexible teams
More impact with flexible teamsThoughtworks
 
Culture of Innovation
Culture of InnovationCulture of Innovation
Culture of InnovationThoughtworks
 
Developer Experience
Developer ExperienceDeveloper Experience
Developer ExperienceThoughtworks
 
When we design together
When we design togetherWhen we design together
When we design togetherThoughtworks
 
Hardware is hard(er)
Hardware is hard(er)Hardware is hard(er)
Hardware is hard(er)Thoughtworks
 
Customer-centric innovation enabled by cloud
 Customer-centric innovation enabled by cloud Customer-centric innovation enabled by cloud
Customer-centric innovation enabled by cloudThoughtworks
 
Amazon's Culture of Innovation
Amazon's Culture of InnovationAmazon's Culture of Innovation
Amazon's Culture of InnovationThoughtworks
 
When in doubt, go live
When in doubt, go liveWhen in doubt, go live
When in doubt, go liveThoughtworks
 
Don't cross the Rubicon
Don't cross the RubiconDon't cross the Rubicon
Don't cross the RubiconThoughtworks
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!Thoughtworks
 
Docker container security
Docker container securityDocker container security
Docker container securityThoughtworks
 
Redefining the unit
Redefining the unitRedefining the unit
Redefining the unitThoughtworks
 
Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Thoughtworks
 
A Tribute to Turing
A Tribute to TuringA Tribute to Turing
A Tribute to TuringThoughtworks
 
Rsa maths worked out
Rsa maths worked outRsa maths worked out
Rsa maths worked outThoughtworks
 

More from Thoughtworks (20)

Design System as a Product
Design System as a ProductDesign System as a Product
Design System as a Product
 
Designers, Developers & Dogs
Designers, Developers & DogsDesigners, Developers & Dogs
Designers, Developers & Dogs
 
Cloud-first for fast innovation
Cloud-first for fast innovationCloud-first for fast innovation
Cloud-first for fast innovation
 
More impact with flexible teams
More impact with flexible teamsMore impact with flexible teams
More impact with flexible teams
 
Culture of Innovation
Culture of InnovationCulture of Innovation
Culture of Innovation
 
Dual-Track Agile
Dual-Track AgileDual-Track Agile
Dual-Track Agile
 
Developer Experience
Developer ExperienceDeveloper Experience
Developer Experience
 
When we design together
When we design togetherWhen we design together
When we design together
 
Hardware is hard(er)
Hardware is hard(er)Hardware is hard(er)
Hardware is hard(er)
 
Customer-centric innovation enabled by cloud
 Customer-centric innovation enabled by cloud Customer-centric innovation enabled by cloud
Customer-centric innovation enabled by cloud
 
Amazon's Culture of Innovation
Amazon's Culture of InnovationAmazon's Culture of Innovation
Amazon's Culture of Innovation
 
When in doubt, go live
When in doubt, go liveWhen in doubt, go live
When in doubt, go live
 
Don't cross the Rubicon
Don't cross the RubiconDon't cross the Rubicon
Don't cross the Rubicon
 
Error handling
Error handlingError handling
Error handling
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!
 
Docker container security
Docker container securityDocker container security
Docker container security
 
Redefining the unit
Redefining the unitRedefining the unit
Redefining the unit
 
Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22
 
A Tribute to Turing
A Tribute to TuringA Tribute to Turing
A Tribute to Turing
 
Rsa maths worked out
Rsa maths worked outRsa maths worked out
Rsa maths worked out
 

Recently uploaded

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 

Recently uploaded (20)

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 

One Page to Test Them All!

  • 1. A Cross platform mobile automation framework Created & Presented by, Priti Biyani & Aroj George ONE PAGE TO TEST THEM ALL
  • 2. U.S. AIRLINE MOBILE APP ๏ iOS, Android, iPad, Blackberry, Windows and Mobile Web ๏ Apple Appstore featured app (Travel) 2
  • 3. CALATRAVA Custom open source cross platform javascript framework - Calatrava. https://github.com/calatrava/calatrava ‣ Pure native screens ‣ Pure HTML ‣ HTML + Native widgets ‣ Native + HTML Webviews 3
  • 4. AUTOMATION ๏ Android Calabash Android ๏ iOS Calabash iOS ๏ Mobile Web Watir Webdriver 4
  • 5. PROBLEM STATEMENT 5 Create a generic automation framework which could support each of the three UI automation tools and work seamlessly across both native and hybrid UI screens
  • 6. REQUIREMENTS ๏ Should make it easy to add automation. It should make life of QA easy! ๏ Allow reuse of code and help avoid duplication ๏ Promote higher level business/domain oriented thinking instead of low level UI interactions ๏ Make changes in only one place. ๏ Once automation is done for a feature on one platform, adding the same for other platforms should be trivial. ๏ Keep it simple, just use basic OO concepts. 6
  • 7. SOLUTION ANALYSIS ๏The Page Object Model Pattern ๏Requirements satisfied ✓Domain oriented thinking ✓Code reuse/no duplication ✓ Changes in only one place. ✓ Easy to add automation. 7
  • 8. PAGE OBJECT MODEL SECOND THOUGHTS ๏ ~ 60 screens on iOS and Android ๏ ~ 30 screens on Mobile Web ๏ 60 x 2 platforms + 30 = 150 page object classes! ๏ Screens have similar behavior and expose same services ‣Requirements check ✓Allows reuse of code and helps avoid duplication. ✓Changes are required to be done in only one place. ✓Makes it easy to add automation. ✓Promotes higher level business/domain oriented thinking ➡ So clearly this approach is not scalable. 8
  • 9. COMMON PAGE OBJECTS PER SCREEN ๏ page objects per screen will solve the class explosion problem. ๏ Requirements satisfied ✓ Should make it easy to add automation. It should make life of QA easy! ✓ Allow reuse of code and help avoid duplication! ✓ Promote higher level business/domain oriented thinking instead of low level UI interactions! ✓ Make change in only one place. ✓ Once automation is done for a feature on one platform, adding the same for other platforms should be trivial. 9
  • 10. COMMON PAGE OBJECTS - CONCERNS? ๏ Different automation tool APIs Element query syntax (xpath/css vs custom calabash syntax) ๏ Different UI actions click/tap on web/mobile ๏ Different platform implementations for same screen locator values can vary ๏ UX interactions patterns for e.g Nav Drawer in Android, the Tab Bar in iOS and the Nav bar in web. 10
  • 11. COMMON PAGE OBJECTS - MORE CONCERNS ? ๏ No online example of this approach. ๏ Calabash reference uses a different Page Object class for iOS and Android. 11 ➡ So is it really possible to have common page objects?
  • 12. OBJECT MODELING Lets try and do a Object Modeling exercise! Single page object class ➡ What are the key fields? ➡ What’s the key behavior? 12
  • 13. PAGE NAME 13 Page Name : String To Refer from feature file Login Page Name :“Login”
  • 14. PAGE IDENTIFIER 14 Page Name : String Id : Map Identify each page uniquely on the device { :web => "//div[@id='payment_info']", :ios => "all webView css:'#payment_info'", :droid => "all webView css:'#payment_info'" }
  • 15. PAGE ID CLASS 15 PageId Id : Map exists? () Check if locator specified by id exists on the UI Calabash Android and IOS: not query(locator).empty? Mobile Web (Watir): Browser.element(:css => locator).present?
  • 16. ID EXISTS CHECK 16 def exists? case platform when ANDROID query(ui_query).empty? when IOS query(ui_query).empty? when WEB Browser.element(:css => locator).present? end end
  • 17. DRIVER ABSTRACTION 17 Pag e Name : String Id : PageId PageId Field : Map exists? () PageId Driver Platform : droid exists? () Driver Platform : ios exists? () Driver Platform : web exists? () def exists?(id_map) locator = id_map[:droid] begin opts.merge!(:screenshot_on_error => false) wait_for_elements_exist([locator],opts) rescue WaitError false end end def exists?(id_map) locator = id_map[:ios] begin opts.merge!(:screenshot_on_error => false) wait_for_elements_exist([locator], opts) element_exists locator rescue WaitError false end end def exists?(id_map, wait=true) locator = id_map[:web] begin Browser.element(:css => locator).wait_until_present if wait Browser.element(:css => locator).present? rescue TimeoutError puts "exists error #{locator}" false end end
  • 18. ELEMENTS 18 Pag e Name : String Id : PageId Elements Element.new({ :web => ‘#save_and_continue_button’, :ios => "navigationButton marked:'DONE'", :droid => "* marked:'Done'" } Element Id: Map click () def click case platform when ANDROID touch(query(locator)) when IOS touch(query(locator)) when WEB Browser.element(:css => locator).click() end end
  • 19. ELEMENTS DELEGATE TO DRIVER 19 Pag e Name : String Id : Map Elements Element Id : Map Driver : Driver click() Driver Platform : droid exists? click() Driver Platform : ios exists? click() Driver Platform : web exists? click() def click(id_map) locator = id_map[:droid] begin scroll_to locator rescue RuntimeError end touch(query(locator)) wait_for_loader_to_disappear end def click(id_map) locator = id_map[:ios] begin scroll_to locator rescue RuntimeError end touch(query(locator)) wait_for_loader_to_disappear end def click(id_map) locator = id_map[:web] B.element(:css => locator).wait_until_present B.element(:css => locator).click wait_for_loader_to_disappear end
  • 20. MORE ELEMENTS 20 Pag e Name : String Id : PageId Element 1: Element Element 2: Element …. Element Driver Platform : droid exists? click() setText() getText() checked() Textbox setText() getText() id : map Checkbox checked?() check(item) id : map Dropdown select(item) id : map Id : Map Driver : Driver Driver Platform : ios exists? click() setText() getText() checked() Driver Platform : web exists? click() setText() getText() checked() exists? ()
  • 21. PAGE TRANSITION 21 Login Home Page def login click_login_button wait_for_home_page_to_load return HomePage.new end [ success ] def <action> click_button wait_for_<next_page>_to_load return <NextPage.new> end
  • 22. TRANSITION MODELING 1. driver.click ✓ Driver should be responsible only for UI interaction. ✓ Driver should not know about higher level abstraction Page. 2. element.click ✓ It will not be applicable to all elements. 3. Transition Aware Element ➡ An element that understands page transitions. 22
  • 23. TRANSITION ELEMENT 23 Pag e Name : String Id : PageId Elements Element Driver Platform : droid exists? click() setText() getText() checked() Textbox setText() getText() id : map Checkbox checked?() check(item) id : map Dropdown select(item) id : map Id : Map Driver : Driver Driver Platform : ios exists? click() setText() getText() checked() Driver Platform : web exists? click() setText() getText() checked() exists? () TransitionElement click(item) id : map
  • 24. TRANSITION ELEMENT 24 @login_button = TransitionElement.new( { :web => '#continue_button', :ios => "* marked:'Login'", :droid => "* marked:'Login'" }, { :to => HomePage, } ) Next Page Class
  • 25. TRANSITION ELEMENT - MULTIPLE TRANSITION 25 Login Admin Home Page Member Home Page userType? [success]
  • 26. TRANSITION ELEMENT - MULTIPLE TRANSITION @login_button = TransitionElement.new( { :web => '#continue_button', :ios => "* marked:'Login'", :droid => "* marked:'Login'" }, { :to => [AdminPage, UserPage], } ) Multiple Transition
  • 27. TRANSITION ELEMENT - ERROR TRANSITION Login Admin Home Page Member Home Page userType? [ SUCCESS ] [ FAIL ]
  • 28. TRANSITION ELEMENT - ERROR TRANSITION @login_button = TransitionElement.new( { :web => '#continue_button', :ios => "* marked:'Login'", :droid => "* marked:'Login'" }, { :to => [AdminPage, UserPage], :error => Login } ) Error Representation
  • 29. MULTIPLE TRANSITIONS - WRONG TRANSITION ‣ Scenario: If there is a bug in code, app transitions to wrong page from list of multiple transitions. ‣ Should transition element detect this bug? ✓ but this is application logic ✓ will increase complexity ➡ Tests should take care for assertions of correct page, not the framework.
  • 30. TRANSITION ELEMENT 30 def wait_till_next_page_loads(next_pages, error_page) has_error, found_next_page = false, false begin wait_for_element(timeout: 30) do found_next_page = next_pages.any? { |page| page.current_page?} has_error = error_page.has_error? if error_page found_next_page or has_error end has_error ? error_page : next_pages.find { |page| page.current_page?} rescue WaitTimeoutError raise WaitTimeoutError, "None of the next page transitions were found. Checked for: => #{next_page_transitions.join(' ,')}" end end
  • 31. PAGE OBJECT EXAMPLE - SEAT MAP 31 Native Implementation Common code across platform Iphone Mobile Web Android
  • 32. SEAT MAP FEATURE STEP 32 And I select following seat | origin | destination | flight_number | pax_name | seat_number | | ORD | JFK | DL3723 | Rami Ron | 9C | | ORD | JFK | DL3723 | John Black | 10C | | JFK | ATL | DL3725 | Rami Ron | 12C | | JFK | ATL | DL3725 | John Black | 13C |
  • 33. SEATMAP PAGE 33 SeatMap Name :“Seat map” Id : {… } select_seat(pax, flight, seat_number)
  • 34. SEAT MAP FEATURE STEP 34 And(/^I select following seat$/) do |table| table.hashes.each do |row| flight = Flight.new(row['origin'], row['destination'], row[‘flight_number’]) seat_map_page = SeatMap.new seat_map_page.select_seat row['pax_name'], flight, row['seat_number'] end end And I select following seat | origin | destination | flight_number | pax_name | seat_number | | ORD | JFK | DL3723 | Rami Ron | 9C | | ORD | JFK | DL3723 | John Black | 10C | | JFK | ATL | DL3725 | Rami Ron | 12C | | JFK | ATL | DL3725 | John Black | 13C |
  • 35. PAGE OBJECT EXAMPLE 35 class SeatMap < Page def initialize @id = PageId.new({ :web => "//div[@id='ism']//div[@id='sb_seat_map_container']", :ios => "webView css:'#seat_map_container'", :droid => "webView css:'#seat_map_container'" }) @leg = Field.element({ :web => "label[@class='dd-option-text'][text()='%s: %s to %s']", :ios => "label marked:'%s: %s to %s'", :droid => "* marked:'%s: %s to %s'" }) @passenger = Field.element({ :web => "//label[@class='dd-option-text'][text()='%s']", :ios => "label marked:'%s'", :droid => "* marked:'%s'" }) @passenger_seat_number_text = Field.element({ :web => "//label[@class='dd-selected-sec-text'][text()='%s']", :ios => "label {text CONTAINS '%s'}", :droid => "* marked:'%s'" }) @seat_button = Field.element({ :web => “//div[@id='seat_%s']", :ios => "webView css:'#seat_%s'", :droid => "webView css:'#seat_%s'" })
  • 36. PAGE OBJECT EXAMPLE 36 class SeatMap < Page def select_seat_for_pax_for_leg(flight_leg, pax_name, seat_number) select_leg flight_leg select_passenger pax_name select_seat seat_number end def select_leg(flight_leg) @leg_header.click @leg.click(flight_leg.flight_number, flight_leg.origin, flight_leg.destination) end def select_passenger(pax_name) @passenger_name_header.click @passenger.click(pax_name) end def select_seat(seat_no) @seat_button.click(seat_no) @passenger_seat_number_text.await(seat_no) end end "label marked:'%s: %s to %s'" "label marked:'%s'" "webView css:'#seat_%s'"
  • 37. TRANSITION TO NEXT PAGE 37 class SeatMap < Page def initialize @done_button = Field.transition_element({ :web => "#save_and_continue_button", :ios => "navigationButton marked:'DONE'", :droid => "* marked:'Done'" }, { :to => [SeatsDetails], }) super(‘Seat Map') end def close @done_button.click end end
  • 38. TRANSITION TO SEATS DETAILS PAGE 38 def verify_seat_details seat_details_page, table table.hashes.each do |row| flight = Flight.new(row['origin'], row['destination'], row['flight_number']) actual_seat_number = seat_details_page.get_seat_number(row[‘pax_name'], flight) expected_seat_number = row['seat_number'] expect(actual_seat_number).to eq(expected_seat_number) end end And(/^I select following seat$/) do |table| table.hashes.each do |row| flight = Flight.new(row['origin'], row['destination'], row[‘flight_number’]) seat_map_page = SeatMap.new seat_map_page.select_seat row['pax_name'], flight, row['seat_number'] end seat_details_page = seat_map_page.close verify_seat_details seat_details_page, table end
  • 39. COMMON PAGE OBJECTS - SOLUTION ๏ Different automation tool APIs/ Different UI actions ➡ Driver abstraction ๏ Different platform implementations for same screen ➡ Element locator map. ๏ UX interactions patterns (Nav Drawer / Tab bar /Menu) ➡ How? 39
  • 40. PRIMARY AND SECONDARY NAVIGATION 40 Iphone Mobile Web Android
  • 41. MENU/MENU ITEM 41 Menu Name : String Id : Map MenuItems MenuItem Name : String TargetPage : Page Type : MenuType MenuButton:TransitionElement show() show_secondary_menu( ) launch (item_name) def launch(item_name) show menu_item = @menu_items[item_name] show_secondary if menu_item.is_secondary? menu_item.click end click () is_secondary? ()
  • 42. MENU IMPLEMENTATION 42 class Menu SHOP_AND_BOOK = 'Book' MY_TRIPS = 'My Trips' FLIGHT_STATUS = 'Flight Status’ def initialize() @id = PageId.new({ :web => "//div[@id='home']//ul[@id='home_options']", :ios => "tabBarButtonLabel marked:'Book'", :droid => "* id:'drawer_items_list'" }) @primary_menu_button = Field.element ({ web: ‘#menu', :ios => '', :droid => "* id:'home'" }), @secondary_menu_button = Field.element ({ web: '', :droid => '', :ios => "* marked:'More'" }), @menu_items = { SHOP_AND_BOOK => MenuItem.new(SHOP_AND_BOOK, FlightSearch), MY_TRIPS => MenuItem.new(MY_TRIPS, MyTrips), FLIGHT_STATUS => MenuItem.new(FLIGHT_STATUS, FlightStatus, ios: MenuItem::SECONDARY)} end def show @primary_menu_button.click end def show_secondary @secondary_menu_button.click end def launch(item_name) . . . end end
  • 43. MENU ITEM IMPLEMENTATION 43 class MenuItem PRIMARY = 1 SECONDARY = 2 attr_accessor :name, :page, :type def initialize(name, page, type = PRIMARY) @name = name @page = page @type = type @menu_button = Field.transition_element( { :web => "//li[@class='#{@name.downcase}']", :ios => "label marked:'#{@name}'", :droid => "WhitneyDefaultTextView id:'drawer_item_text' text:'#{@name}'" }, { :to => @page }) end def click @menu_button.click end def is_secondary? @type[Driver.platform] == SECONDARY end end # MenuItem.new(FLIGHT_STATUS, FlightStatus, ios: MenuItem::SECONDARY)
  • 44. COMMON PAGE OBJECTS - SOLUTION ✓ Different automation tool APIs ➡ Driver abstraction ✓ Different UI actions ➡ Driver abstraction ✓ Different platform implementations for same screen ➡ Element locator map. ✓ UX interactions patterns (Nav Drawer / Tab bar /Menu) ➡ Menu and Menu Item Abstraction 44
  • 45. IMPLEMENTATION NOTES ‣ We "require" specific driver class during test execution. ‣ Page registry, can be queried for page object instances. ‣ PageRegistry.get "Login Page” ‣ Rspec Unit Tests ‣ Rake task to create new page classes. 45
  • 46. FUTURE DIRECTION ‣ Debug Mode ‣ Log debug info like element id, clicks etc… ‣ Slow element locator finder 46
  • 47. LEARNINGS ‣ QA/Dev Pairing ‣ Use case driven development ‣ Evolution 47
  • 48. SUMMARY ๏ Good OO design is the key ๏ Good abstractions can help solve hard problems 48
  • 49. CONCLUSION 49 utomation to support new feature development across the three different platforms requ just one place.
  • 50. Reach out to us at Aroj George @arojp Priti Biyani @pritibiyani http://arojgeorge.ghost.io/ http://pritibiyani.github.io/ THANK YOU

Editor's Notes

  1. This is bug and f/w did not catch it!
  2. Animation Pending!
  3. can we highlight better..formatting fix