SlideShare a Scribd company logo
1 of 31
Download to read offline
SCREENPLAY

A Journey Beyond The PageObject Pattern

Antony Marcano

Jan Molak

Kostas Mamalis
CONTACT
•

Kostas Mamalis
@agiletestinguk

kostas@masterthought.net
•

Antony Marcano
@AntonyMarcano

antony@riverglide.com
•

Jan Molak
@JanMolak

jan.molak@smartcodeltd.co.uk
CONTEXT
IN THE BEGINNING
•

Long established financial institution

•

Used Scrum with 2 week Sprints

•

Outsourced development to large consultancy

•

No automated acceptance tests (few unit tests)
ALONG THE JOURNEY
•

Realised that automated tests were essential

•

Wrote lots of Cucumber tests

•

Backed by Selenium/WebDriver

•

Used the PageObject Pattern
SELENIUM
AND
THE PAGE OBJECT PATTERN
Illustrated with the Pet Clinic
A journey beyond the page object pattern
TESTING THE PET CLINIC
WEBDRIVER EXAMPLE
DesiredCapabilities capabilities = new DesiredCapabilities();
WebDriver driver = new PhantomJSDriver(desiredCapabilities());
driver.get(baseUrl+"owners/find.html");
driver.findElement(By.cssSelector("#search-owner-form button")).click();
assertThat(
driver.findElements(By.cssSelector("owners tbody tr")).size(),
is(10)
);
FINDING ALL OWNERS - WEBDRIVER EXAMPLE
DesiredCapabilities capabilities = new DesiredCapabilities();
WebDriver driver = new PhantomJSDriver(desiredCapabilities());
driver.get(baseUrl+"owners/find.html");
driver.findElement(By.cssSelector("#search-owner-form button")).click();
assertThat(
driver.findElements(By.cssSelector("owners tbody tr")).size(),
is(10)
);
FINDING ALL OWNERS - PAGEOBJECT EXAMPLE
DesiredCapabilities capabilities = new DesiredCapabilities();
WebDriver driver = new PhantomJSDriver(desiredCapabilities());
driver.get(baseUrl+"owners/find.html");
FindOwnersPage findOwners =
PageFactory.initElements(driver, FindOwnersPage.class);
OwnersPage owners = findOwners.findWith(EMPTY_SEARCH_TERMS);
assertThat(owners.numberOfOwners(), is(10));
PROBLEMS AROSE
•

Large PageObject classes

•

Brittle test-code (less than raw Selenium)

•

Duplication across PageObjects for each of the
‘portals’
THEY TRIED THE FOLLOWING
•

Separate behaviour into Navigation Classes

•

Reduce duplication with inheritance

Causing ...
•

Large Navigation classes

•

Deep inheritance hierarchy
EFFECTS ON THE TEAM
•

Took longer and longer to add new tests

•

Got harder to diagnose problems

•

Low trust in the ‘test framework’ and Cucumber

•

Reduced faith
in automated testing

•

Impacted morale
WHAT WAS THE ANSWER?
Antony Marcano at first AAFTT in 2007
THE INSIGHT
Roles
← Who
➥ Goals
← Why
➥ Tasks
← What
➥ Actions ← How
Inspired by Kevin Lawrence’s talk at the first AAFTT in 2007
More of his thinking here: http://www.developertesting.com/archives/month200710/20071013-In%20Praise%20of
%20Abstraction.html
2008 - JNARRATE
@Test
public void should_be_able_to_edit_a_page() {
Given.thatThe(wiki).wasAbleTo(beAtThe(PointWhereItHasBeen.JUST_INSTALLED));
And.thatThe(user).wasAbleTo(navigateToTheHomePage());
And.thatThe(user).wasAbleTo(navigateToTheHomePage());
When.the(user).attemptsTo(

tas
k

changeTheContent().to("Welcome to Acceptance Test Driven Development")

tas
k

);

Then.the(textOnTheScreen().ofThe(user)).

tas
k
shouldBe("Welcome to Acceptance Test Driven Development");
}
Playing with fluent APIs and started to explore the model of Tasks & Actions
(although back then the labels I used more like Kevin’s labels).
2009 - SCREENPLAY - A TASK
public void perform() {
you.need(To.doTheFollowing( // actions
Click.onThe(OptionsMenu.EDIT_BUTTON),
ClearTheContent.ofThe(Editor.CONTENT_PANEL),
Type.theText(newContent).
intoThe(Editor.CONTENT_PANEL),
Click.onThe(Editor.SAVE_BUTTON)
));
}
2012 - THE JOURNEY PATTERN
Actor

performs

Tasks

has

Abilities

composed of

enable

Actions

interact with

Screen
contains

Elements
JOURNEY PATTERN APPLIED
JUNIT
Roles
➥ Goals

➥ Tasks

← Who
← Why

← What

➥ Actions ← How

Actor theReceptionist =
new Actor().with(WebBrowsing.ability());
@Test public void
should_find_all_owners_by_default

theReceptionist.attemptsTo(
Go.to(findOwnersScreen.url()),
Search.forOwnersWith(EMPTY_SEARCH_TERMS),
Count.theNumberOfOwners()
);
Enter.the(searchTerms).
into(findOwnersScreen.searchTerms),
Click.onThe(findOwnersScreen.searchButton)
JOURNEY PATTERN APPLIED
CUCUMBER
Roles

← Who

As a Pet Clinic Receptionist

➥ Goals

← Why

Scenario: Find all owners by default

← What

When I search for owners with BLANK search terms
@When
(“^I search for owners with BLANK search terms$”)

➥ Tasks

theReceptionist.attemptsTo(
Search.forOwnersWith(EMPTY_SEARCH_TERMS)
);

➥ Actions ← How

Enter.the(searchTerms).
into(findOwnersScreen.searchTerms),
PUTTING IT ALL TOGETHER
Actor theReceptionist = new Actor().with(WebBrowsing.ability());
theReceptionist.attemptsTo(
Go.to(findOwnersScreen.url()),
Search.forOwnersWith(EMPTY_SEARCH_TERMS),
Count.theNumberOfOwners()
);
assertThat(
theReceptionist.sawThatThe(numberOfOwners()),
was(theExpectedNumberOfOwners)
);
A TASK
…
private static String searchTerms;
@Override
public void performAs(Actor asAReceptionist) {
asAReceptionist.attemptTo(
Enter.the(searchTerms).into(findOwnersScreen.searchTerms),
Click.onThe(findOwnersScreen.searchButton)
);
}
public SearchForOwnersWith(String searchTerms) {
this.searchTerms = searchTerms;
}
…
A SCREEN

@Url("owners/find.html")
public class FindOwnersScreen extends WebScreen {
@LocateBy(css="#search-owner-form input")
public ScreenElement searchTerms;
@LocateBy(css="#search-owner-form button")
public ScreenElement searchButton;
}
AN ACTION
public class Enter extends WebDriverInteraction implements Perform {
private String text;
private ScreenElement field;
public void performAs(Actor actor) {
web(actor).findElement(field.locator()).sendKeys(text);
}
public Enter(String text) { this.text = text; }
public static Enter the(String text) {return new Enter(text);}
public Perform into(ScreenElement field) {
this.field = field;
return this;
}
}
PROBLEMS SOLVED
•

Smaller “Screen” classes

•

Small, focused “Task” classes

•

Readable code

•

Consistent metaphor

•

Minimal inheritance

•

Removed need for duplication across behaviours previously in
PageObjects or “Navigation” classes
DESIGN PRINCIPLES
•

DRY - navigational steps in one place

•

Separation of Concerns - Page Structure and Actions separate

•

Small Classes - easy to comprehend

•

Single Responsibility - classes focused on one thing
and one thing only

•

Minimise conditional logic - navigational if-thens replaced
with composable sequences
SCREENPLAY REVIVED
Under development for everyone to use
Watch This Space!
CONTACT
•

Kostas Mamalis
@agiletestinguk

kostas@masterthought.net
•

Antony Marcano
@AntonyMarcano

antony@riverglide.com
•

Jan Molak
@JanMolak

jan.molak@smartcodeltd.co.uk
THANK YOU!

More Related Content

What's hot

React-JS Component Life-cycle Methods
React-JS Component Life-cycle MethodsReact-JS Component Life-cycle Methods
React-JS Component Life-cycle MethodsANKUSH CHAVAN
 
Basics of React Hooks.pptx.pdf
Basics of React Hooks.pptx.pdfBasics of React Hooks.pptx.pdf
Basics of React Hooks.pptx.pdfKnoldus Inc.
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsVikash Singh
 
Katalon: Mobile and Browser-Based Automation | Quality Jam 2018
Katalon: Mobile and Browser-Based Automation | Quality Jam 2018Katalon: Mobile and Browser-Based Automation | Quality Jam 2018
Katalon: Mobile and Browser-Based Automation | Quality Jam 2018Katalon Studio
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooksMaulik Shah
 
Apache JMeter - A brief introduction
Apache JMeter - A brief introductionApache JMeter - A brief introduction
Apache JMeter - A brief introductionsilenceIT Inc.
 
Performance testing using jmeter
Performance testing using jmeterPerformance testing using jmeter
Performance testing using jmeterRachappa Bandi
 
(애자일) 테스트 계획서 샘플
(애자일) 테스트 계획서 샘플(애자일) 테스트 계획서 샘플
(애자일) 테스트 계획서 샘플SangIn Choung
 
API Testing following the Test Pyramid
API Testing following the Test PyramidAPI Testing following the Test Pyramid
API Testing following the Test PyramidElias Nogueira
 
Spring Framework
Spring FrameworkSpring Framework
Spring FrameworkNaLUG
 
Cypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfCypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfbacancytechnology
 

What's hot (20)

React-JS Component Life-cycle Methods
React-JS Component Life-cycle MethodsReact-JS Component Life-cycle Methods
React-JS Component Life-cycle Methods
 
Browser_Stack_Intro
Browser_Stack_IntroBrowser_Stack_Intro
Browser_Stack_Intro
 
Basics of React Hooks.pptx.pdf
Basics of React Hooks.pptx.pdfBasics of React Hooks.pptx.pdf
Basics of React Hooks.pptx.pdf
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Java 8 features
Java 8 featuresJava 8 features
Java 8 features
 
Katalon: Mobile and Browser-Based Automation | Quality Jam 2018
Katalon: Mobile and Browser-Based Automation | Quality Jam 2018Katalon: Mobile and Browser-Based Automation | Quality Jam 2018
Katalon: Mobile and Browser-Based Automation | Quality Jam 2018
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
 
Event handling
Event handlingEvent handling
Event handling
 
Apache JMeter - A brief introduction
Apache JMeter - A brief introductionApache JMeter - A brief introduction
Apache JMeter - A brief introduction
 
Performance testing using jmeter
Performance testing using jmeterPerformance testing using jmeter
Performance testing using jmeter
 
(애자일) 테스트 계획서 샘플
(애자일) 테스트 계획서 샘플(애자일) 테스트 계획서 샘플
(애자일) 테스트 계획서 샘플
 
Unit Testing in Java
Unit Testing in JavaUnit Testing in Java
Unit Testing in Java
 
Selenium ppt
Selenium pptSelenium ppt
Selenium ppt
 
API Testing following the Test Pyramid
API Testing following the Test PyramidAPI Testing following the Test Pyramid
API Testing following the Test Pyramid
 
Introduction to Robot Framework
Introduction to Robot FrameworkIntroduction to Robot Framework
Introduction to Robot Framework
 
Java Unit Testing
Java Unit TestingJava Unit Testing
Java Unit Testing
 
Spring Framework
Spring FrameworkSpring Framework
Spring Framework
 
Cypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfCypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdf
 
Appium ppt
Appium pptAppium ppt
Appium ppt
 
Python unit testing
Python unit testingPython unit testing
Python unit testing
 

Viewers also liked

Refactoring page objects The Screenplay Pattern
Refactoring page objects   The Screenplay Pattern Refactoring page objects   The Screenplay Pattern
Refactoring page objects The Screenplay Pattern RiverGlide
 
ScreenPlay Design Patterns for QA Automation
ScreenPlay Design Patterns for QA AutomationScreenPlay Design Patterns for QA Automation
ScreenPlay Design Patterns for QA AutomationCOMAQA.BY
 
Using The Page Object Pattern
Using The Page Object PatternUsing The Page Object Pattern
Using The Page Object PatternDante Briones
 
Page Objects Done Right - selenium conference 2014
Page Objects Done Right - selenium conference 2014Page Objects Done Right - selenium conference 2014
Page Objects Done Right - selenium conference 2014Oren Rubin
 
Perils of Page-Object Pattern
Perils of Page-Object PatternPerils of Page-Object Pattern
Perils of Page-Object PatternAnand Bagmar
 
APIs: A Better Alternative to Page Objects
APIs: A Better Alternative to Page ObjectsAPIs: A Better Alternative to Page Objects
APIs: A Better Alternative to Page ObjectsSauce Labs
 
Advanced visual testing of web and mobile applications
Advanced visual testing of web and mobile applicationsAdvanced visual testing of web and mobile applications
Advanced visual testing of web and mobile applicationsDenys Zaiats
 
DSL, Page Object and WebDriver – the path to reliable functional tests.pptx
DSL, Page Object and WebDriver – the path to reliable functional tests.pptxDSL, Page Object and WebDriver – the path to reliable functional tests.pptx
DSL, Page Object and WebDriver – the path to reliable functional tests.pptxMikalai Alimenkou
 
Out of box page object design pattern, java
Out of box page object design pattern, javaOut of box page object design pattern, java
Out of box page object design pattern, javaCOMAQA.BY
 
Better Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component PatternBetter Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component PatternSargis Sargsyan
 
Webium: Page Objects In Python (Eng)
Webium: Page Objects In Python (Eng)Webium: Page Objects In Python (Eng)
Webium: Page Objects In Python (Eng)Uladzimir Franskevich
 
DSL, Page Object and Selenium – a way to reliable functional tests
DSL, Page Object and Selenium – a way to reliable functional testsDSL, Page Object and Selenium – a way to reliable functional tests
DSL, Page Object and Selenium – a way to reliable functional testsMikalai Alimenkou
 
Node.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideMek Srunyu Stittri
 
User Story Mapping, Discover the whole story
User Story Mapping, Discover the whole storyUser Story Mapping, Discover the whole story
User Story Mapping, Discover the whole storyJeff Patton
 

Viewers also liked (18)

Serenity and the Journey Pattern
Serenity and the Journey PatternSerenity and the Journey Pattern
Serenity and the Journey Pattern
 
Refactoring page objects The Screenplay Pattern
Refactoring page objects   The Screenplay Pattern Refactoring page objects   The Screenplay Pattern
Refactoring page objects The Screenplay Pattern
 
ScreenPlay Design Patterns for QA Automation
ScreenPlay Design Patterns for QA AutomationScreenPlay Design Patterns for QA Automation
ScreenPlay Design Patterns for QA Automation
 
Beyond Page Objects
Beyond Page ObjectsBeyond Page Objects
Beyond Page Objects
 
Using The Page Object Pattern
Using The Page Object PatternUsing The Page Object Pattern
Using The Page Object Pattern
 
Page Objects Done Right - selenium conference 2014
Page Objects Done Right - selenium conference 2014Page Objects Done Right - selenium conference 2014
Page Objects Done Right - selenium conference 2014
 
Perils of Page-Object Pattern
Perils of Page-Object PatternPerils of Page-Object Pattern
Perils of Page-Object Pattern
 
APIs: A Better Alternative to Page Objects
APIs: A Better Alternative to Page ObjectsAPIs: A Better Alternative to Page Objects
APIs: A Better Alternative to Page Objects
 
Advanced visual testing of web and mobile applications
Advanced visual testing of web and mobile applicationsAdvanced visual testing of web and mobile applications
Advanced visual testing of web and mobile applications
 
CukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning WorkshopCukeUp 2016 Agile Product Planning Workshop
CukeUp 2016 Agile Product Planning Workshop
 
DSL, Page Object and WebDriver – the path to reliable functional tests.pptx
DSL, Page Object and WebDriver – the path to reliable functional tests.pptxDSL, Page Object and WebDriver – the path to reliable functional tests.pptx
DSL, Page Object and WebDriver – the path to reliable functional tests.pptx
 
Out of box page object design pattern, java
Out of box page object design pattern, javaOut of box page object design pattern, java
Out of box page object design pattern, java
 
Better Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component PatternBetter Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component Pattern
 
BDD Anti-patterns
BDD Anti-patternsBDD Anti-patterns
BDD Anti-patterns
 
Webium: Page Objects In Python (Eng)
Webium: Page Objects In Python (Eng)Webium: Page Objects In Python (Eng)
Webium: Page Objects In Python (Eng)
 
DSL, Page Object and Selenium – a way to reliable functional tests
DSL, Page Object and Selenium – a way to reliable functional testsDSL, Page Object and Selenium – a way to reliable functional tests
DSL, Page Object and Selenium – a way to reliable functional tests
 
Node.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java sideNode.js and Selenium Webdriver, a journey from the Java side
Node.js and Selenium Webdriver, a journey from the Java side
 
User Story Mapping, Discover the whole story
User Story Mapping, Discover the whole storyUser Story Mapping, Discover the whole story
User Story Mapping, Discover the whole story
 

Similar to A journey beyond the page object pattern

Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD CombinationLotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD CombinationSean Burgess
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETBen Hall
 
Automation Abstraction Layers: Page Objects and Beyond
Automation Abstraction Layers: Page Objects and BeyondAutomation Abstraction Layers: Page Objects and Beyond
Automation Abstraction Layers: Page Objects and BeyondAlan Richardson
 
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016Roy de Kleijn
 
Top100summit 谷歌-scott-improve your automated web application testing
Top100summit  谷歌-scott-improve your automated web application testingTop100summit  谷歌-scott-improve your automated web application testing
Top100summit 谷歌-scott-improve your automated web application testingdrewz lin
 
Protractor Tutorial Quality in Agile 2015
Protractor Tutorial Quality in Agile 2015Protractor Tutorial Quality in Agile 2015
Protractor Tutorial Quality in Agile 2015Andrew Eisenberg
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJSJacopo Nardiello
 
UI Testing Automation
UI Testing AutomationUI Testing Automation
UI Testing AutomationAgileEngine
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e bigAndy Peterson
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript FrameworkAll Things Open
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJSPeter Drinnan
 
Selenium withnet
Selenium withnetSelenium withnet
Selenium withnetVlad Maniak
 
Kakunin E2E framework showcase
Kakunin E2E framework showcaseKakunin E2E framework showcase
Kakunin E2E framework showcaseThe Software House
 
An Introduction to AngularJS End to End Testing using Protractor
An Introduction to AngularJS End to End Testing using ProtractorAn Introduction to AngularJS End to End Testing using Protractor
An Introduction to AngularJS End to End Testing using ProtractorCubet Techno Labs
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingJohn Ferguson Smart Limited
 
UI Testing Automation - Alex Kalinovsky - CreamTec LLC
UI Testing Automation - Alex Kalinovsky - CreamTec LLCUI Testing Automation - Alex Kalinovsky - CreamTec LLC
UI Testing Automation - Alex Kalinovsky - CreamTec LLCJim Lane
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with ReduxFITC
 
Wix Automation - Core
Wix Automation - CoreWix Automation - Core
Wix Automation - CoreEfrat Attas
 

Similar to A journey beyond the page object pattern (20)

Gems Of Selenium
Gems Of SeleniumGems Of Selenium
Gems Of Selenium
 
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD CombinationLotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
Lotusphere 2012 Speedgeeking - jQuery & Domino, a RAD Combination
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NET
 
Automation Abstraction Layers: Page Objects and Beyond
Automation Abstraction Layers: Page Objects and BeyondAutomation Abstraction Layers: Page Objects and Beyond
Automation Abstraction Layers: Page Objects and Beyond
 
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
 
Top100summit 谷歌-scott-improve your automated web application testing
Top100summit  谷歌-scott-improve your automated web application testingTop100summit  谷歌-scott-improve your automated web application testing
Top100summit 谷歌-scott-improve your automated web application testing
 
Protractor Tutorial Quality in Agile 2015
Protractor Tutorial Quality in Agile 2015Protractor Tutorial Quality in Agile 2015
Protractor Tutorial Quality in Agile 2015
 
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJS
 
UI Testing Automation
UI Testing AutomationUI Testing Automation
UI Testing Automation
 
Javascript unit testing, yes we can e big
Javascript unit testing, yes we can   e bigJavascript unit testing, yes we can   e big
Javascript unit testing, yes we can e big
 
Choosing a Javascript Framework
Choosing a Javascript FrameworkChoosing a Javascript Framework
Choosing a Javascript Framework
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJS
 
Selenium withnet
Selenium withnetSelenium withnet
Selenium withnet
 
Kakunin E2E framework showcase
Kakunin E2E framework showcaseKakunin E2E framework showcase
Kakunin E2E framework showcase
 
An Introduction to AngularJS End to End Testing using Protractor
An Introduction to AngularJS End to End Testing using ProtractorAn Introduction to AngularJS End to End Testing using Protractor
An Introduction to AngularJS End to End Testing using Protractor
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
 
UI Testing Automation - Alex Kalinovsky - CreamTec LLC
UI Testing Automation - Alex Kalinovsky - CreamTec LLCUI Testing Automation - Alex Kalinovsky - CreamTec LLC
UI Testing Automation - Alex Kalinovsky - CreamTec LLC
 
Building React Applications with Redux
Building React Applications with ReduxBuilding React Applications with Redux
Building React Applications with Redux
 
Wix Automation - Core
Wix Automation - CoreWix Automation - Core
Wix Automation - Core
 

Recently uploaded

Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Brian Pichman
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024SkyPlanner
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1DianaGray10
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 

Recently uploaded (20)

Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024Salesforce Miami User Group Event - 1st Quarter 2024
Salesforce Miami User Group Event - 1st Quarter 2024
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1Secure your environment with UiPath and CyberArk technologies - Session 1
Secure your environment with UiPath and CyberArk technologies - Session 1
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 

A journey beyond the page object pattern

  • 1. SCREENPLAY A Journey Beyond The PageObject Pattern Antony Marcano Jan Molak Kostas Mamalis
  • 4. IN THE BEGINNING • Long established financial institution • Used Scrum with 2 week Sprints • Outsourced development to large consultancy • No automated acceptance tests (few unit tests)
  • 5. ALONG THE JOURNEY • Realised that automated tests were essential • Wrote lots of Cucumber tests • Backed by Selenium/WebDriver • Used the PageObject Pattern
  • 6. SELENIUM AND THE PAGE OBJECT PATTERN Illustrated with the Pet Clinic
  • 9. WEBDRIVER EXAMPLE DesiredCapabilities capabilities = new DesiredCapabilities(); WebDriver driver = new PhantomJSDriver(desiredCapabilities()); driver.get(baseUrl+"owners/find.html"); driver.findElement(By.cssSelector("#search-owner-form button")).click(); assertThat( driver.findElements(By.cssSelector("owners tbody tr")).size(), is(10) );
  • 10. FINDING ALL OWNERS - WEBDRIVER EXAMPLE DesiredCapabilities capabilities = new DesiredCapabilities(); WebDriver driver = new PhantomJSDriver(desiredCapabilities()); driver.get(baseUrl+"owners/find.html"); driver.findElement(By.cssSelector("#search-owner-form button")).click(); assertThat( driver.findElements(By.cssSelector("owners tbody tr")).size(), is(10) );
  • 11. FINDING ALL OWNERS - PAGEOBJECT EXAMPLE DesiredCapabilities capabilities = new DesiredCapabilities(); WebDriver driver = new PhantomJSDriver(desiredCapabilities()); driver.get(baseUrl+"owners/find.html"); FindOwnersPage findOwners = PageFactory.initElements(driver, FindOwnersPage.class); OwnersPage owners = findOwners.findWith(EMPTY_SEARCH_TERMS); assertThat(owners.numberOfOwners(), is(10));
  • 12. PROBLEMS AROSE • Large PageObject classes • Brittle test-code (less than raw Selenium) • Duplication across PageObjects for each of the ‘portals’
  • 13. THEY TRIED THE FOLLOWING • Separate behaviour into Navigation Classes • Reduce duplication with inheritance Causing ... • Large Navigation classes • Deep inheritance hierarchy
  • 14. EFFECTS ON THE TEAM • Took longer and longer to add new tests • Got harder to diagnose problems • Low trust in the ‘test framework’ and Cucumber • Reduced faith in automated testing • Impacted morale
  • 15. WHAT WAS THE ANSWER?
  • 16. Antony Marcano at first AAFTT in 2007
  • 17. THE INSIGHT Roles ← Who ➥ Goals ← Why ➥ Tasks ← What ➥ Actions ← How Inspired by Kevin Lawrence’s talk at the first AAFTT in 2007 More of his thinking here: http://www.developertesting.com/archives/month200710/20071013-In%20Praise%20of %20Abstraction.html
  • 18. 2008 - JNARRATE @Test public void should_be_able_to_edit_a_page() { Given.thatThe(wiki).wasAbleTo(beAtThe(PointWhereItHasBeen.JUST_INSTALLED)); And.thatThe(user).wasAbleTo(navigateToTheHomePage()); And.thatThe(user).wasAbleTo(navigateToTheHomePage()); When.the(user).attemptsTo( tas k changeTheContent().to("Welcome to Acceptance Test Driven Development") tas k ); Then.the(textOnTheScreen().ofThe(user)). tas k shouldBe("Welcome to Acceptance Test Driven Development"); } Playing with fluent APIs and started to explore the model of Tasks & Actions (although back then the labels I used more like Kevin’s labels).
  • 19. 2009 - SCREENPLAY - A TASK public void perform() { you.need(To.doTheFollowing( // actions Click.onThe(OptionsMenu.EDIT_BUTTON), ClearTheContent.ofThe(Editor.CONTENT_PANEL), Type.theText(newContent). intoThe(Editor.CONTENT_PANEL), Click.onThe(Editor.SAVE_BUTTON) )); }
  • 20. 2012 - THE JOURNEY PATTERN Actor performs Tasks has Abilities composed of enable Actions interact with Screen contains Elements
  • 21. JOURNEY PATTERN APPLIED JUNIT Roles ➥ Goals ➥ Tasks ← Who ← Why ← What ➥ Actions ← How Actor theReceptionist = new Actor().with(WebBrowsing.ability()); @Test public void should_find_all_owners_by_default theReceptionist.attemptsTo( Go.to(findOwnersScreen.url()), Search.forOwnersWith(EMPTY_SEARCH_TERMS), Count.theNumberOfOwners() ); Enter.the(searchTerms). into(findOwnersScreen.searchTerms), Click.onThe(findOwnersScreen.searchButton)
  • 22. JOURNEY PATTERN APPLIED CUCUMBER Roles ← Who As a Pet Clinic Receptionist ➥ Goals ← Why Scenario: Find all owners by default ← What When I search for owners with BLANK search terms @When (“^I search for owners with BLANK search terms$”) ➥ Tasks theReceptionist.attemptsTo( Search.forOwnersWith(EMPTY_SEARCH_TERMS) ); ➥ Actions ← How Enter.the(searchTerms). into(findOwnersScreen.searchTerms),
  • 23. PUTTING IT ALL TOGETHER Actor theReceptionist = new Actor().with(WebBrowsing.ability()); theReceptionist.attemptsTo( Go.to(findOwnersScreen.url()), Search.forOwnersWith(EMPTY_SEARCH_TERMS), Count.theNumberOfOwners() ); assertThat( theReceptionist.sawThatThe(numberOfOwners()), was(theExpectedNumberOfOwners) );
  • 24. A TASK … private static String searchTerms; @Override public void performAs(Actor asAReceptionist) { asAReceptionist.attemptTo( Enter.the(searchTerms).into(findOwnersScreen.searchTerms), Click.onThe(findOwnersScreen.searchButton) ); } public SearchForOwnersWith(String searchTerms) { this.searchTerms = searchTerms; } …
  • 25. A SCREEN @Url("owners/find.html") public class FindOwnersScreen extends WebScreen { @LocateBy(css="#search-owner-form input") public ScreenElement searchTerms; @LocateBy(css="#search-owner-form button") public ScreenElement searchButton; }
  • 26. AN ACTION public class Enter extends WebDriverInteraction implements Perform { private String text; private ScreenElement field; public void performAs(Actor actor) { web(actor).findElement(field.locator()).sendKeys(text); } public Enter(String text) { this.text = text; } public static Enter the(String text) {return new Enter(text);} public Perform into(ScreenElement field) { this.field = field; return this; } }
  • 27. PROBLEMS SOLVED • Smaller “Screen” classes • Small, focused “Task” classes • Readable code • Consistent metaphor • Minimal inheritance • Removed need for duplication across behaviours previously in PageObjects or “Navigation” classes
  • 28. DESIGN PRINCIPLES • DRY - navigational steps in one place • Separation of Concerns - Page Structure and Actions separate • Small Classes - easy to comprehend • Single Responsibility - classes focused on one thing and one thing only • Minimise conditional logic - navigational if-thens replaced with composable sequences
  • 29. SCREENPLAY REVIVED Under development for everyone to use Watch This Space!

Editor's Notes

  1. New requirement for automated testing -> tests focused on UI -> inverted test pyramid
  2. 1. Let’s refresh our memory what the Page Object pattern is all about 2. AUDIENCE: Can we have a show of hands; how many of you work with Selenium? Webdriver? Selenium IDE?  3. OK, so let's see how functional testing of the UI can be addressed using an example of a serious, financial application ...
  3. Because of confidentiality reasons we can't present our client's applications, but I believe that even a much simpler project will be enough to demonstrate the limitations of two common approaches to UI testing. I'll leave re-scaling the problem to the size of your typical projects to your imagination.
  4. Let's talk about testing the PetClinic, a sample Spring application that demonstrates the basic of using the Spring framework.
  5. We have some people with WebDriver experience here. So guys, what is this test trying to prove?
  6. So the scenario we have here: a PetClinic Receptionist wants to use the default behaviour of the Search form, which allows them to see all the data stored in the database if no search terms are specified. Now, how clear is this scenario based on this code?It’s difficult to tell what the test is trying to prove with all the css selector noise
  7. PageObjects introduce a basic abstraction that encapsulates page elements and actions that can be performed on a given page in a PageObject; Actions return other PageObjects -> maintenance overhead should the flow change They might encourage code duplication -> what if you can log in on different pages?