SlideShare a Scribd company logo
PyUIA 0.3
Jeremy Kao / KKBOX SQA / Jun 23, 2015
Agenda
● Single Keyword Library
● Current Page Tracking
● UI Mapping, Page Factory Pattern and
Caching
● Handlers Rotation and API Changes
● Q&A
Abstraction of Layers
Single Keyword Library
As of v0.3 Prior to v0.3
Less Keyword Conflicts
Multiple keywords with name 'Do Something' found.
Give the full name of the keyword you want to use.
Found: 'ThatPage.Do Something' and 'ThisPage.Do Something'
Prior to PyUIA 0.3 - Multiple Libraries
class ThisPage(MyAppLibrary):
_page_class_ios = myapp.ios.ThisPage
_page_class_android = myapp.android.ThatPage
def should_be_on_this_page(self):
self._page_object.wait_for_page_loaded()
def do_something(self):
self._page_object.do_something(target)
class ThatPage(MyAppLibrary):
_page_class_ios = myapp.ios.ThatPage
_page_class_android = myapp.android.ThatPage
def should_be_on_that_page(self):
self._page_object.wait_for_page_loaded()
def do_something(self):
self._page_object.do_something(target)
As of PyUIA 0.3 - Single Library
class MyApp(BaseAppLibrary):
_page_class_ios = ios.ThisPage
_page_class_android = android.ThisPage
def do_something(self):
# for all pages that implement this operation/protocol.
self._page_object.do_something()
return self._current_page.do_something() # return the next page
Bootstrap - Wait For <INIT> Page
class MyApp(BaseAppLibrary):
def wait_for_welcome_page(self):
context = self._current_context
if context.platform == 'android':
from myapp.android import WelcomePage
else:
from myapp.ios import WelcomePage
return get_page_object(WelcomePage, context).wait_for_page_loaded()
Current Page Tracking
● this._current_page always points
to current page (of the current
device).
● PyUIA updates the current page
when a keyword returns a page
object.
● The current page determines the
runtime behavior of a keyword.
Thanks to Chloe Chen for the idea.
Current Page == Implicit Subject
Current page is an analogue to the implied subject in an
imperative sentence.
# Keywords
Wait For Home Page
Go To Settings
Enable Synchronization
Go Back
# Page Objects (Python)
home = HomePage(driver).
wait_for_page_loaded()
settings = home.go_to_settings()
settings.enable_synchronization()
settings.go_back() # Home
PageFactory Impl. in Python?
Refer to PageFactory (Java)...
● PageFactory implementation from selenium for python - Stack Overflow
(Nov 8, 2013)
● Does Webdriver support pagefactory for Python? - Stack Overflow (Dec
12, 2012)
● PageFactory Implementation in Python - Google Groups (May 8, 2012)
● PageFactory implementation in Python? - Google Groups (Aug 11, 2011)
Unfortunately, we have to invent the wheel ~ Implementing
PageFactory Pattern in Python (June 10, 2015) (find_by,
@cacheable)
Google Search Page
from pyuia.selenium import SeleniumPageObject as PageObject, find_by, cacheable
from selenium.webdriver.common.by.By
class GoogleSearchPage(PageObject):
_search_box = find_by(how=By.NAME, using='q')
_search_button = find_by(name='btnK')
def search(self, keywords):
self._search_box().click()
self._search_box().send_keys(keywords) # look up twice?
self._search_button().click()
The following keyword arguments are supported for various locator strategies: id_ (to avoid conflict
with the built-in keyword id), name, class_name, css_selector, tag_name, xpath, link_text,
partial_link_text.
find_by
def find_by(how=None, using=None, multiple=False, cacheable=True, if_exists=False,
context=None, driver_attr='_driver', **kwargs):
● multiple – the answer to @FindBy for a list of elements.
● cacheable – the answer to @CacheLookup. (see also
@cacheable for customized lookup.)
● if_exists - for conditional UI elements.
● context – the answer to @FindBys.
● driver_attr – the attribute name for getting the
reference to WebDriver. Defaults to ’_driver’.
find_by (cont.)
# prior to v0.3
def _clickme_button(self):
return self._driver.find_element_by_name('Click Me!')
def _clickme_button(self):
return self._driver.find_element_by_id('click_me')
# as of v0.3
_clickme_button = find_by(name='Click Me!')
_clickme_button = find_by(id_='click_me')
find_by (cont.)
# prior to v0.3
def _products(self):
container = self._driver.find_element_by_id('products_list')
return container.find_elements_by_class_name('android.widget.TextView')
# as of v0.3
_products = find_by(class_name='android.widget.TextView', multiple=True,
context=find_by(id_='products_list'))
find_by (cont.)
# prior to v0.3
def _tip_if_exists(self):
try:
return self._driver_find_element_by_id('tip')
except NoSuchElementException:
return None
# as of v0.3
_tip_if_exists = find_by(id_='tip', if_exists=True)
@cacheable (for customized lookup)
@cacheable
def _categories(self):
candidates = self._driver.find_elements_by_id('list')
assert len(candidates) == 2, candidates
container = candidates[1] # the 2nd one
return container.find_elements_by_class_name('android.widget.TextView')
Handlers Rotation
def assert_on_this_page(self):
self._assert_any_present(
[self._lyrics_button, self._discovery_tutorial_view_if_exists],
handlers={
self._other_device_playing_alert: self._dismiss_devices_alert, # H1
self._storage_space_alert: self._dismiss_storage_alert, # H2
self._high_quality_prompt_message: self._dismiss_high_quality_prompt # H3
})
# ...
● Prior to v0.3 - (H1 ➔ H2 ➔ H3) ➥ (H1 ➔ H2 ➔ H3) ...
● As of v0.3 - H1 ➥ H2 ➥ H3 ➥ H1 ➥ H3 ➥ H1 ➥ H1 ...
Modeling: Page and UI Fragment
MainPage
M
e
n
u
ActionBar
class Menu(class):
def open_menu(self): pass
class ActionBar(class):
def title(self): pass
class MainPage(AppiumPO, Menu, ActionBar): pass
Page-to-page Transitions
A(WelcomePage)
_go_to(page_class)
_back_to(page_class)
B(MainPage)
● assert_on_this_page(from_page_class) - assertion, no waiting
● _get_page_entry_handlers(from_page_class) - rotation
● _on_page_entry(from_page_class) - replace _wait_for_idle.
Page-to-page Transitions (cont.)
# Page A
_clickme_button = find_by(id_='click_me')
def go_to_b(self):
self._clickme_button().click()
return self._go_to(BPage)
# Page B
_back_button = find_by(name='Back')
def go_back(self):
self._back_button().click()
# go to the previous page by default
return self._back_to()
_go_to(page_class)
_back_to(page_class=None)
Page-to-page Transitions (cont.)
# WelcomePage
def assert_on_this_page(self, from_page_class):
self._assert_present(self._start_button)
def start(self):
self._start_button().click() # look up again?
self._go_to(MainPage)
Page-to-page Transitions (cont.)
# MainPage
def assert_on_this_page(self, from_page_class):
self._assert_present(self._main_menu)
def _get_page_entry_handlers(self, from_page_class):
if from_page_class == WelcomePage:
return { self._network_error: self._retry }
Page-to-page Transitions (cont.)
# MainPage
def _on_page_entry(self, from_page_class):
if from_page_class != WelcomePage: return
self._wait_disappear(self._loading_indicator)
self._watch({
self._chromecast_ok_button: self._dismiss_chromecast_tip,
self._tutorial_ok_button: self._dismiss_tutorial,
}, 10) # max duration
return True # indicates UI changed (takes another screenshot)
Where _watch (handlers, max_duration) replaces _handle_conditional_views
(handlers, duration)
References
● PyUIA
● Page Object Pattern (Martin Fowler)
● PageFactory pattern (Python impl.)
● 利用 Appium + Robot Framework 實現跨平
台 App 互動測試 (Nov 14, 2014)
Q&A
Thanks you all for listening ~

More Related Content

What's hot

Workshop 15: Ionic framework
Workshop 15: Ionic frameworkWorkshop 15: Ionic framework
Workshop 15: Ionic framework
Visual Engineering
 
How to React Native
How to React NativeHow to React Native
How to React Native
Dmitry Ulyanov
 
Beyond Domino Designer
Beyond Domino DesignerBeyond Domino Designer
Beyond Domino Designer
Paul Withers
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4
Darwin Biler
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
Gunnar Hillert
 
Leave your jQuery behind
Leave your jQuery behindLeave your jQuery behind
Leave your jQuery behind
Fabien Doiron
 
React Native: React Meetup 3
React Native: React Meetup 3React Native: React Meetup 3
React Native: React Meetup 3
Rob Gietema
 
Test-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) serviceTest-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) service
Jeroen Reijn
 
DJango
DJangoDJango
DJango
Sunil OS
 
Android stepbystep
Android stepbystepAndroid stepbystep
Android stepbystepKrazy Koder
 
Automation Testing using Selenium Webdriver
Automation Testing using Selenium WebdriverAutomation Testing using Selenium Webdriver
Automation Testing using Selenium Webdriver
Pankaj Biswas
 
Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"
Fwdays
 
Android L01 - Warm Up
Android L01 - Warm UpAndroid L01 - Warm Up
Android L01 - Warm Up
Mohammad Shaker
 
Evolving an Application Architecture
Evolving an Application ArchitectureEvolving an Application Architecture
Evolving an Application Architecture
Garret Fick
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
Rami Sayar
 
Testing iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backendTesting iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backend
Testplus GmbH
 
An overview of selenium webdriver
An overview of selenium webdriverAn overview of selenium webdriver
An overview of selenium webdriver
Anuraj S.L
 
Tellurium At Rich Web Experience2009
Tellurium At Rich Web Experience2009Tellurium At Rich Web Experience2009
Tellurium At Rich Web Experience2009
John.Jian.Fang
 
Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React NativePieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
tlv-ios-dev
 
Javascript Best Practices and Intro to Titanium
Javascript Best Practices and Intro to TitaniumJavascript Best Practices and Intro to Titanium
Javascript Best Practices and Intro to Titanium
Techday7
 

What's hot (20)

Workshop 15: Ionic framework
Workshop 15: Ionic frameworkWorkshop 15: Ionic framework
Workshop 15: Ionic framework
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
Beyond Domino Designer
Beyond Domino DesignerBeyond Domino Designer
Beyond Domino Designer
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
Leave your jQuery behind
Leave your jQuery behindLeave your jQuery behind
Leave your jQuery behind
 
React Native: React Meetup 3
React Native: React Meetup 3React Native: React Meetup 3
React Native: React Meetup 3
 
Test-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) serviceTest-Driven Documentation for your REST(ful) service
Test-Driven Documentation for your REST(ful) service
 
DJango
DJangoDJango
DJango
 
Android stepbystep
Android stepbystepAndroid stepbystep
Android stepbystep
 
Automation Testing using Selenium Webdriver
Automation Testing using Selenium WebdriverAutomation Testing using Selenium Webdriver
Automation Testing using Selenium Webdriver
 
Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"Philip Shurpik "Architecting React Native app"
Philip Shurpik "Architecting React Native app"
 
Android L01 - Warm Up
Android L01 - Warm UpAndroid L01 - Warm Up
Android L01 - Warm Up
 
Evolving an Application Architecture
Evolving an Application ArchitectureEvolving an Application Architecture
Evolving an Application Architecture
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
 
Testing iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backendTesting iOS10 Apps with Appium and its new XCUITest backend
Testing iOS10 Apps with Appium and its new XCUITest backend
 
An overview of selenium webdriver
An overview of selenium webdriverAn overview of selenium webdriver
An overview of selenium webdriver
 
Tellurium At Rich Web Experience2009
Tellurium At Rich Web Experience2009Tellurium At Rich Web Experience2009
Tellurium At Rich Web Experience2009
 
Pieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React NativePieter De Baets - An introduction to React Native
Pieter De Baets - An introduction to React Native
 
Javascript Best Practices and Intro to Titanium
Javascript Best Practices and Intro to TitaniumJavascript Best Practices and Intro to Titanium
Javascript Best Practices and Intro to Titanium
 

Similar to PyUIA 0.3

Django class based views
Django class based viewsDjango class based views
Django class based viewsjustinvoss
 
WordPress plugin #3
WordPress plugin #3WordPress plugin #3
WordPress plugin #3
giwoolee
 
Art & music vs Google App Engine
Art & music vs Google App EngineArt & music vs Google App Engine
Art & music vs Google App Engine
thomas alisi
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010
ikailan
 
WordPress plugin #2
WordPress plugin #2WordPress plugin #2
WordPress plugin #2
giwoolee
 
End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
Jesús L. Domínguez Muriel
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Joao Lucas Santana
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2Graham Dumpleton
 
Zyncro zyncro apps & ui customization feb 2013
Zyncro zyncro apps & ui customization feb 2013Zyncro zyncro apps & ui customization feb 2013
Zyncro zyncro apps & ui customization feb 2013Zyncro
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Ivan Chepurnyi
 
Web driver training
Web driver trainingWeb driver training
Web driver training
Dipesh Bhatewara
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
Simon Willison
 
How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30fiyuer
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
dreampuf
 
Automating Django Functional Tests Using Selenium on Cloud
Automating Django Functional Tests Using Selenium on CloudAutomating Django Functional Tests Using Selenium on Cloud
Automating Django Functional Tests Using Selenium on Cloud
Jonghyun Park
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
River of Talent
 
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
Iakiv Kramarenko
 
Angular Intermediate
Angular IntermediateAngular Intermediate
Angular Intermediate
LinkMe Srl
 

Similar to PyUIA 0.3 (20)

Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
Django class based views
Django class based viewsDjango class based views
Django class based views
 
WordPress plugin #3
WordPress plugin #3WordPress plugin #3
WordPress plugin #3
 
Art & music vs Google App Engine
Art & music vs Google App EngineArt & music vs Google App Engine
Art & music vs Google App Engine
 
OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010OSCON Google App Engine Codelab - July 2010
OSCON Google App Engine Codelab - July 2010
 
WordPress plugin #2
WordPress plugin #2WordPress plugin #2
WordPress plugin #2
 
End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
 
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
Um roadmap do Framework Ruby on Rails, do Rails 1 ao Rails 4 - DevDay 2013
 
PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2PyCon US 2012 - State of WSGI 2
PyCon US 2012 - State of WSGI 2
 
Zyncro zyncro apps & ui customization feb 2013
Zyncro zyncro apps & ui customization feb 2013Zyncro zyncro apps & ui customization feb 2013
Zyncro zyncro apps & ui customization feb 2013
 
Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)Making Magento flying like a rocket! (A set of valuable tips for developers)
Making Magento flying like a rocket! (A set of valuable tips for developers)
 
Web driver training
Web driver trainingWeb driver training
Web driver training
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30How to disassemble one monster app into an ecosystem of 30
How to disassemble one monster app into an ecosystem of 30
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Automating Django Functional Tests Using Selenium on Cloud
Automating Django Functional Tests Using Selenium on CloudAutomating Django Functional Tests Using Selenium on Cloud
Automating Django Functional Tests Using Selenium on Cloud
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
 
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
Selenide Alternative in Practice - Implementation & Lessons learned [Selenium...
 
Angular Intermediate
Angular IntermediateAngular Intermediate
Angular Intermediate
 

Recently uploaded

Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
vrstrong314
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
Ortus Solutions, Corp
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
Peter Caitens
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
KrzysztofKkol1
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
ayushiqss
 

Recently uploaded (20)

Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
 

PyUIA 0.3

  • 1. PyUIA 0.3 Jeremy Kao / KKBOX SQA / Jun 23, 2015
  • 2. Agenda ● Single Keyword Library ● Current Page Tracking ● UI Mapping, Page Factory Pattern and Caching ● Handlers Rotation and API Changes ● Q&A
  • 4. Single Keyword Library As of v0.3 Prior to v0.3
  • 5. Less Keyword Conflicts Multiple keywords with name 'Do Something' found. Give the full name of the keyword you want to use. Found: 'ThatPage.Do Something' and 'ThisPage.Do Something'
  • 6. Prior to PyUIA 0.3 - Multiple Libraries class ThisPage(MyAppLibrary): _page_class_ios = myapp.ios.ThisPage _page_class_android = myapp.android.ThatPage def should_be_on_this_page(self): self._page_object.wait_for_page_loaded() def do_something(self): self._page_object.do_something(target) class ThatPage(MyAppLibrary): _page_class_ios = myapp.ios.ThatPage _page_class_android = myapp.android.ThatPage def should_be_on_that_page(self): self._page_object.wait_for_page_loaded() def do_something(self): self._page_object.do_something(target)
  • 7. As of PyUIA 0.3 - Single Library class MyApp(BaseAppLibrary): _page_class_ios = ios.ThisPage _page_class_android = android.ThisPage def do_something(self): # for all pages that implement this operation/protocol. self._page_object.do_something() return self._current_page.do_something() # return the next page
  • 8. Bootstrap - Wait For <INIT> Page class MyApp(BaseAppLibrary): def wait_for_welcome_page(self): context = self._current_context if context.platform == 'android': from myapp.android import WelcomePage else: from myapp.ios import WelcomePage return get_page_object(WelcomePage, context).wait_for_page_loaded()
  • 9. Current Page Tracking ● this._current_page always points to current page (of the current device). ● PyUIA updates the current page when a keyword returns a page object. ● The current page determines the runtime behavior of a keyword. Thanks to Chloe Chen for the idea.
  • 10. Current Page == Implicit Subject Current page is an analogue to the implied subject in an imperative sentence. # Keywords Wait For Home Page Go To Settings Enable Synchronization Go Back # Page Objects (Python) home = HomePage(driver). wait_for_page_loaded() settings = home.go_to_settings() settings.enable_synchronization() settings.go_back() # Home
  • 11. PageFactory Impl. in Python? Refer to PageFactory (Java)... ● PageFactory implementation from selenium for python - Stack Overflow (Nov 8, 2013) ● Does Webdriver support pagefactory for Python? - Stack Overflow (Dec 12, 2012) ● PageFactory Implementation in Python - Google Groups (May 8, 2012) ● PageFactory implementation in Python? - Google Groups (Aug 11, 2011) Unfortunately, we have to invent the wheel ~ Implementing PageFactory Pattern in Python (June 10, 2015) (find_by, @cacheable)
  • 12. Google Search Page from pyuia.selenium import SeleniumPageObject as PageObject, find_by, cacheable from selenium.webdriver.common.by.By class GoogleSearchPage(PageObject): _search_box = find_by(how=By.NAME, using='q') _search_button = find_by(name='btnK') def search(self, keywords): self._search_box().click() self._search_box().send_keys(keywords) # look up twice? self._search_button().click() The following keyword arguments are supported for various locator strategies: id_ (to avoid conflict with the built-in keyword id), name, class_name, css_selector, tag_name, xpath, link_text, partial_link_text.
  • 13. find_by def find_by(how=None, using=None, multiple=False, cacheable=True, if_exists=False, context=None, driver_attr='_driver', **kwargs): ● multiple – the answer to @FindBy for a list of elements. ● cacheable – the answer to @CacheLookup. (see also @cacheable for customized lookup.) ● if_exists - for conditional UI elements. ● context – the answer to @FindBys. ● driver_attr – the attribute name for getting the reference to WebDriver. Defaults to ’_driver’.
  • 14. find_by (cont.) # prior to v0.3 def _clickme_button(self): return self._driver.find_element_by_name('Click Me!') def _clickme_button(self): return self._driver.find_element_by_id('click_me') # as of v0.3 _clickme_button = find_by(name='Click Me!') _clickme_button = find_by(id_='click_me')
  • 15. find_by (cont.) # prior to v0.3 def _products(self): container = self._driver.find_element_by_id('products_list') return container.find_elements_by_class_name('android.widget.TextView') # as of v0.3 _products = find_by(class_name='android.widget.TextView', multiple=True, context=find_by(id_='products_list'))
  • 16. find_by (cont.) # prior to v0.3 def _tip_if_exists(self): try: return self._driver_find_element_by_id('tip') except NoSuchElementException: return None # as of v0.3 _tip_if_exists = find_by(id_='tip', if_exists=True)
  • 17. @cacheable (for customized lookup) @cacheable def _categories(self): candidates = self._driver.find_elements_by_id('list') assert len(candidates) == 2, candidates container = candidates[1] # the 2nd one return container.find_elements_by_class_name('android.widget.TextView')
  • 18. Handlers Rotation def assert_on_this_page(self): self._assert_any_present( [self._lyrics_button, self._discovery_tutorial_view_if_exists], handlers={ self._other_device_playing_alert: self._dismiss_devices_alert, # H1 self._storage_space_alert: self._dismiss_storage_alert, # H2 self._high_quality_prompt_message: self._dismiss_high_quality_prompt # H3 }) # ... ● Prior to v0.3 - (H1 ➔ H2 ➔ H3) ➥ (H1 ➔ H2 ➔ H3) ... ● As of v0.3 - H1 ➥ H2 ➥ H3 ➥ H1 ➥ H3 ➥ H1 ➥ H1 ...
  • 19. Modeling: Page and UI Fragment MainPage M e n u ActionBar class Menu(class): def open_menu(self): pass class ActionBar(class): def title(self): pass class MainPage(AppiumPO, Menu, ActionBar): pass
  • 20. Page-to-page Transitions A(WelcomePage) _go_to(page_class) _back_to(page_class) B(MainPage) ● assert_on_this_page(from_page_class) - assertion, no waiting ● _get_page_entry_handlers(from_page_class) - rotation ● _on_page_entry(from_page_class) - replace _wait_for_idle.
  • 21. Page-to-page Transitions (cont.) # Page A _clickme_button = find_by(id_='click_me') def go_to_b(self): self._clickme_button().click() return self._go_to(BPage) # Page B _back_button = find_by(name='Back') def go_back(self): self._back_button().click() # go to the previous page by default return self._back_to() _go_to(page_class) _back_to(page_class=None)
  • 22. Page-to-page Transitions (cont.) # WelcomePage def assert_on_this_page(self, from_page_class): self._assert_present(self._start_button) def start(self): self._start_button().click() # look up again? self._go_to(MainPage)
  • 23. Page-to-page Transitions (cont.) # MainPage def assert_on_this_page(self, from_page_class): self._assert_present(self._main_menu) def _get_page_entry_handlers(self, from_page_class): if from_page_class == WelcomePage: return { self._network_error: self._retry }
  • 24. Page-to-page Transitions (cont.) # MainPage def _on_page_entry(self, from_page_class): if from_page_class != WelcomePage: return self._wait_disappear(self._loading_indicator) self._watch({ self._chromecast_ok_button: self._dismiss_chromecast_tip, self._tutorial_ok_button: self._dismiss_tutorial, }, 10) # max duration return True # indicates UI changed (takes another screenshot) Where _watch (handlers, max_duration) replaces _handle_conditional_views (handlers, duration)
  • 25. References ● PyUIA ● Page Object Pattern (Martin Fowler) ● PageFactory pattern (Python impl.) ● 利用 Appium + Robot Framework 實現跨平 台 App 互動測試 (Nov 14, 2014)
  • 26. Q&A Thanks you all for listening ~