SlideShare a Scribd company logo
1 of 70
Download to read offline
@giltayar
You’re almost there:
turbocharge your functional tests
with visual powers
Gil Tayar (@giltayar)
August 2018
This presentation: http://bit.ly/turbocharge-webinar
Github repo: https://github.com/giltayar/realworld-frontend-testing
@giltayar@giltayar
About Me ● My developer experience goes all the way
back to the ‘80s.
● Am, was, and always will be a developer
● Testing the code I write is my passion
● Currently evangelist and architect @
Applitools
● We deliver Visual Testing tools:
If you’re serious about testing, checkout
Applitools Eyes
● Sometimes my arms bend back
● But the gum I like is coming back in style
@giltayar
@giltayar
What Are Functional
Tests?
@giltayar
So many kinds of tests...
@giltayar
Tests, Tests, Glorious Tests!
● Unit
● Integration
● E2E
● Acceptance
● Visual
● Contract
● Browser
● Automation
● Functional
● And the list goes on…
@giltayar
Not to mention the
different interpretations
@giltayar
Functional Tests
@giltayar
Functional tests are
automation tests that automate the browser
in order to test the functionality
of a web application*
* Or a mobile app
@giltayar
Functional tests are
automation tests that automate the browser
in order to test the functionality
of a web application*
* Or a mobile app
@giltayar
Let’s write a Functional Test
@giltayar
● Huge library (npm)
○ Biggest.
○ Very high quality
○ Lots of tests!
● DLL hell is gone (almost…)
● No bullshit libraries (readme-s,
not javadocs)
I love NodeJS
● Constantly improving in
performance
● Fast startup times
● ES2018 is a wonderful language
● Async programming is
wonderful
● Good FP language too
● Constantly evolving
@giltayar
● All the cool new automation frameworks are in
NodeJS/JavaScript
● It is the language of the frontend developers
○ Writing tests with the frontend developers
○ Code sharing!
I love NodeJS
@giltayar
Let’s give a look at the app we’re testing
@giltayar
Let’s write a Functional Test in JavaScript!
https://github.com/giltayar/realworld-frontend-testing, branch step1
@giltayar
All Functional Tests are Stories
@giltayar
All Functional Tests Look Like This
● Action
● Action
● Validation
● Action
● Validation
● Action
● Action
● Action
● Validation
@giltayar
Let’s do the following functional story
https://github.com/giltayar/realworld-frontend-testing, branch step2
@giltayar
async function waitFor(selector) {
await driver.wait(
until.elementLocated(By.css(selector)))
}
async function setText(selector, text) {
const field = await driver.findElement(
By.css(selector))
await field.sendKeys(text)
}
Create some utility functions
async function click(selector) {
const element = await driver.findElement(
By.css(selector))
await element.click()
}
async function getText(selector) {
const element = await driver.findElement(
By.css(selector))
return await element.getText()
}
@giltayar
Register the User
action
action
action
action
@giltayar
// action: browse to registration page
await driver.get('http://localhost:3000/register' )
// action: set username, password, email to something
await setText('input[placeholder=Username]' , 'ausername')
await setText('input[placeholder=Password]' , 'aPassword')
await setText('input[placeholder=Email]' , 'an@email.com' )
// action: submit form
await click('button[type=submit]' )
Register the User
@giltayar
// action: browse to registration page
await driver.get('http://localhost:3000/register' )
// action: set username, password, email to something
await setText('input[placeholder=Username]' , 'ausername')
await setText('input[placeholder=Password]' , 'aPassword')
await setText('input[placeholder=Email]' , 'an@email.com' )
// action: submit form
await click('button[type=submit]' )
Fragile Selector Problem
Fragile selectors
@giltayar
class RegisterPage {
async function registerUser(username, email, password) {
// ...
}
}
Example RegisterPage Object
@giltayar
Empty Home Page
validation
validation
action validation
@giltayar
await waitFor('img[alt=ausername]')
// validate username
expect(await getText('a[href="/@ausername"]')).to.equal('ausername')
// validate articles list
expect(await getText('.article-preview'))
.to.equal('No articles are here... yet.')
// validate active tab
expect(await getText('.nav-link.active')).to.equal('Your Feed')
Validate the Empty User Home Page
@giltayar
Publish an article
action
action
action
action
action
@giltayar
// action: click on new post
const newPost = await driver.findElement (By.partialLinkText ('New Post'))
await newPost.click()
await waitFor('input[placeholder="Article Title"]' )
// action: set the title, description, and article
await setText('input[placeholder="Article Title"]' , 'a title')
await setText('input[placeholder="What's this article about?"]' , 'something' )
await setText('textarea[placeholder*="Write your article"]' , 'wonderful' )
// action: set the tags
const tags = await driver.findElement (By.css('input[placeholder="Enter tags"]' ))
for (const tag of ['a', 'b', 'c']) await tags.sendKeys(tag, Key.ENTER)
// action: submit form
await click('button[type=button]' )
Publish a Post
@giltayar
See that it’s there, and add a comment
validation
validation
validation
validation
action
action
@giltayar
await waitFor('h1')
// validate title
expect(await getText('h1')).to.equal('a title')
// validate article content
expect(await getText('.article-content')).to.include('wonderful')
// validate tags
expect(await getText('.tag-list')).to.equal('abc')
Validate Post
@giltayar
// action: set comment
await setText('textarea', 'a comment')
// action: submit comment
await click('button[type=submit]')
Add Comment
@giltayar
Validate the comment
validation
validation
@giltayar
await waitFor('div.card .card-block')
// validate comment text
expect(await getText('div.card .card-block')).to.equal('a comment')
// validate comment username
expect(await getText('div.card a.comment-author:nth-child(2)'))
.to.equal('ausername')
Validate Comment
@giltayar
Logout
action
@giltayar
// action: goto settings page
await driver.get('http://localhost:3000/settings')
await waitFor('button.btn-outline-danger')
// action: click logout button
await click('button.btn-outline-danger')
Logout
@giltayar
Check Blog with anonymous user
validation
validation
validation
validation
validation
@giltayar
// goto home page
await driver.get('http://localhost:3000/')
// validate post author
expect(await getText('a.author'))
.to.equal('ausername')
// validate post title
expect(await getText('.article-preview h1'))
.to.equal('a title')
// validate post description
expect(await getText('.article-preview h1 + p'))
.to.equal('something')
// validate post tags
expect(await getText('.article-preview ul'))
.to.equal('abc')
Validate Home Page for Anonymous User
// validate popular tags
expect(await getText('.sidebar .tag-list'))
.to.equal('abc')
// action: goto post page
await click('.article-preview h1')
await waitFor('.article-page')
// validate post title
expect(await getText('h1')).to.equal('a title')
// validate article description
expect(await getText('div.article-content p'))
.to.equal('wonderful')
// validate article tags
expect(await getText('ul.tag-list')).to.equal('abc')
@giltayar
Problems with Actions
● Fragile Selectors
● Complex Code
● Solution: Page Objects
@giltayar
Problems with Validations
● Fragile Selectors
● Complex Code
● Too much to validate
● Only positive check
○ We don’t validate what we don’t know about
● Solution: Page Objects, partially
@giltayar
Actions are Focused
Validations are Holistic
@giltayar
Let’s see why validations are holistic
● Add the following to Register.js:
onSubmit: (username, email, password) => {
dispatch({ type: UPDATE_FIELD_AUTH, key: 'username', value: '' })
const payload = agent.Auth.register(username, email, password);
● This will clear the username after every submit
@giltayar
Let’s see what the effect of this bug will be
@giltayar
But does the test pass?
Yes, it does!
@giltayar
Actions are Focused
Validations are should be Holistic
@giltayar
Let’s revert the “bug”, rebuild,
and figure out how to solve the validation
problem
@giltayar
Solving the Validation Problem
@giltayar
What else is holistic?
@giltayar
Vision!
@giltayar
Replace Humans with Image Diffing!
@giltayar
Let’s do some live coding for that!
https://github.com/giltayar/realworld-frontend-testing, branch step3
@giltayar
So we’ve replace this...
expect(await getText('.error-messages' )).to.include("email can't be
blank")
With this…
expect(Buffer.from(await driver.takeScreenshot (),
'base64')).to.matchImage(
'registration-blank-email-error' ,
)
@giltayar
Why is this better?
It’s just one line replacing another
@giltayar
Solutions to problems with validations
● Fragile Selectors
○ No more selectors
● Complex Code
○ Same code for all validations
● Too much to validate
○ We validate holistically
● Only positive check
○ We validate things we didn’t even think of validating
@giltayar
Solutions to problems with validations
● Fragile Selectors
○ No more selectors
● Complex Code
○ Same code for all validations
● Too much to validate
○ We validate holistically
● Only positive check
○ We validate things we didn’t even think of validating
@giltayar
Let’s try it out...
● Run the tests without the bug
● Copy baseline image to expected-screenshots folder
● Add the following to Register.js:
onSubmit: (username, email, password) => {
dispatch({ type: UPDATE_FIELD_AUTH, key: 'username', value: '' })
const payload = agent.Auth.register(username, email, password);
● This will clear the username after every submit
@giltayar
Functional vs Visual Validations
● Let’s test it in step2: functional validations
git checkout step2 && npm run build && npm test
● The test passes! (and it shouldn’t)
● Now let’s try step3: visual validations
git checkout step2 && npm test
● The test fails! (as it should)
@giltayar
Let’s revert the “bug”, rebuild,
and continue looking at
visual vs. functional valiation
@giltayar
Functional Validations are Focused
Visual Validations are Holistic
@giltayar
async function validatePost() {
await waitFor('.validate-content')
// validate title
expect(await getText('h1')).to.equal('a title')
// validate article content
expect(await getText('.article-content')).to.include('wonderful')
// validate tags
expect(await getText('.tag-list')).to.equal('abc')
}
And we’ve change this...
@giltayar
async function validatePost() {
await waitFor('.article-content')
await checkWindow('new-post')
}
Into this...
@giltayar
// goto home page
await driver.get('http://localhost:3000/')
// validate post author
expect(await getText('a.author'))
.to.equal('ausername')
// validate post title
expect(await getText('.article-preview h1'))
.to.equal('a title')
// validate post description
expect(await getText('.article-preview h1 + p'))
.to.equal('something')
// validate post tags
expect(await getText('.article-preview ul'))
.to.equal('abc')
And this long code...
// validate popular tags
expect(await getText('.sidebar .tag-list'))
.to.equal('abc')
// action: goto post page
await click('.article-preview h1')
await waitFor('.article-page')
// validate post title
expect(await getText('h1')).to.equal('a title')
// validate article description
expect(await getText('div.article-content p'))
.to.equal('wonderful')
// validate article tags
expect(await getText('ul.tag-list')).to.equal('abc')
@giltayar
async function validateBlog() {
await driver.get('http://localhost:3000/')
await checkWindow('anonymous-home-page')
await click('.article-preview h1')
await waitFor('.article-page')
await checkWindow('anonymous-blog-post-view')
}
Into this...
@giltayar
Solutions to problems with validations
● Fragile Selectors
○ No more selectors
● Complex Code
○ Same code for all validations
● Too much to validate
○ We validate holistically
● Only positive check
○ We validate things we didn’t even think of validating
@giltayar
Problems with Naive Image Diffing
● Small anti-aliasing differences
○ Mac vs. Linux vs. Windows
○ Different GPUs
● Date/time problems
○ regions that are different from run to run
● Full screen vs. Viewport
● Comparing is a pain
● “Accepting” a new baseline is a pain
@giltayar
Problems with Naive Image Diffing
● Small anti-aliasing differences
○ Mac vs. Linux vs. Windows
○ Different GPUs
● Date/time problems
○ regions that are different from run to run
● Full screen vs. Viewport
● Comparing is a pain
● “Accepting” a new baseline is a pain
@giltayar
Cloud-Based Solutions
@giltayar
Cloud-based solution
● Visual diffing algorithms see like a human sees
○ Ignoring the small differences
○ AI-level algorithms are now involved and keep getting better
● Screenshot management tools are available, enabling you to
○ See the diffs
○ Approve new baselines
○ Open bugs on diffs that are bugs
@giltayar
Let’s Run the Demo
https://github.com/giltayar/realworld-frontend-testing, branch step4
@giltayar
Let’s change some code
to see some of the
baseline management tooling
@giltayar
Supercharging your
functional tests
@giltayar
Supercharging Your Test with Visual Validations
● Write code that issues action after action, to create a long story
○ You can use a recorder like Selenium IDE or one of the new cloud-based
ones
● Intersperse your code with visual validations
○ You can use the open-source solutions or a cloud-based option
● You get two for the price of one:
○ Much simpler functional validations
○ Visual validation of your page: catch those visual bugs that you couldn’t
catch till now!
@giltayar
Thank You
Gil Tayar (@giltayar)
This presentation: http://bit.ly/turbocharge-webinar
The Github repo: https://github.com/giltayar/realworld-frontend-testing

More Related Content

What's hot

Angular 2 - The Next Framework
Angular 2 - The Next FrameworkAngular 2 - The Next Framework
Angular 2 - The Next FrameworkCommit University
 
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
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshopNir Kaufman
 
Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Ahmed Moawad
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2Naveen Pete
 
Introduction to Google Guice
Introduction to Google GuiceIntroduction to Google Guice
Introduction to Google GuiceKnoldus Inc.
 
Angular2 with TypeScript
Angular2 with TypeScript Angular2 with TypeScript
Angular2 with TypeScript Rohit Bishnoi
 
Ruby On Rails Pitfalls
Ruby On Rails PitfallsRuby On Rails Pitfalls
Ruby On Rails PitfallsRobin Lu
 
Neoito — Design patterns and depenedency injection
Neoito — Design patterns and depenedency injectionNeoito — Design patterns and depenedency injection
Neoito — Design patterns and depenedency injectionNeoito
 
Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015Iakiv Kramarenko
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency InjectionNir Kaufman
 
Intro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSIntro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSJim Lynch
 
Easy tests with Selenide and Easyb
Easy tests with Selenide and EasybEasy tests with Selenide and Easyb
Easy tests with Selenide and EasybIakiv Kramarenko
 
Design Patterns in XCUITest
Design Patterns in XCUITestDesign Patterns in XCUITest
Design Patterns in XCUITestVivian Liu
 
Android training day 4
Android training day 4Android training day 4
Android training day 4Vivek Bhusal
 
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016Codemotion
 

What's hot (20)

Angular 2 - The Next Framework
Angular 2 - The Next FrameworkAngular 2 - The Next Framework
Angular 2 - The Next Framework
 
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
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshop
 
Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2
 
Introduction to Google Guice
Introduction to Google GuiceIntroduction to Google Guice
Introduction to Google Guice
 
Angular2 with TypeScript
Angular2 with TypeScript Angular2 with TypeScript
Angular2 with TypeScript
 
Ruby On Rails Pitfalls
Ruby On Rails PitfallsRuby On Rails Pitfalls
Ruby On Rails Pitfalls
 
Neoito — Design patterns and depenedency injection
Neoito — Design patterns and depenedency injectionNeoito — Design patterns and depenedency injection
Neoito — Design patterns and depenedency injection
 
Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015
 
Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency Injection
 
Intro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSIntro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJS
 
Easy tests with Selenide and Easyb
Easy tests with Selenide and EasybEasy tests with Selenide and Easyb
Easy tests with Selenide and Easyb
 
Google Guice
Google GuiceGoogle Guice
Google Guice
 
Design Patterns in XCUITest
Design Patterns in XCUITestDesign Patterns in XCUITest
Design Patterns in XCUITest
 
Android training day 4
Android training day 4Android training day 4
Android training day 4
 
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016
Understanding Angular 2 - Shmuela Jacobs - Codemotion Milan 2016
 
Solid angular
Solid angularSolid angular
Solid angular
 
Day 6
Day 6Day 6
Day 6
 
Angular js-crash-course
Angular js-crash-courseAngular js-crash-course
Angular js-crash-course
 

Similar to Visual Testing: Turbo-Charge Your Functional Tests with Visual Powers in Just 8 Lines of Code -- by Gil Tayar

Visual Testing: The Missing Piece of the Puzzle -- presentation by Gil Tayar
Visual Testing: The Missing Piece of the Puzzle -- presentation by Gil TayarVisual Testing: The Missing Piece of the Puzzle -- presentation by Gil Tayar
Visual Testing: The Missing Piece of the Puzzle -- presentation by Gil TayarApplitools
 
Software Testing
Software TestingSoftware Testing
Software Testingsuperphly
 
Testing C# and ASP.net using Ruby
Testing C# and ASP.net using RubyTesting C# and ASP.net using Ruby
Testing C# and ASP.net using RubyBen Hall
 
Djangocon 2014 angular + django
Djangocon 2014 angular + djangoDjangocon 2014 angular + django
Djangocon 2014 angular + djangoNina Zakharenko
 
Unit-testing and E2E testing in JS
Unit-testing and E2E testing in JSUnit-testing and E2E testing in JS
Unit-testing and E2E testing in JSMichael Haberman
 
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)Cogapp
 
Creating a flawless user experience, end to-end, functional to visual - Slide...
Creating a flawless user experience, end to-end, functional to visual - Slide...Creating a flawless user experience, end to-end, functional to visual - Slide...
Creating a flawless user experience, end to-end, functional to visual - Slide...Applitools
 
Basics of Java Script (JS)
Basics of Java Script (JS)Basics of Java Script (JS)
Basics of Java Script (JS)Ajay Khatri
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example usingIevgenii Katsan
 
jQuery Performance Tips and Tricks
jQuery Performance Tips and TricksjQuery Performance Tips and Tricks
jQuery Performance Tips and TricksValerii Iatsko
 
Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It'sJim Lynch
 
jQuery for Sharepoint Dev
jQuery for Sharepoint DevjQuery for Sharepoint Dev
jQuery for Sharepoint DevZeddy Iskandar
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile wayAshwin Raghav
 
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis LazuliGetting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis LazuliRebecca Eloise Hogg
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Seleniumelliando dias
 
Getting Answers to Your Testing Questions
Getting Answers to Your Testing QuestionsGetting Answers to Your Testing Questions
Getting Answers to Your Testing Questionsjasnow
 
Test Infected Presentation
Test Infected PresentationTest Infected Presentation
Test Infected Presentationwillmation
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF SummitOrtus Solutions, Corp
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andevMike Nakhimovich
 

Similar to Visual Testing: Turbo-Charge Your Functional Tests with Visual Powers in Just 8 Lines of Code -- by Gil Tayar (20)

Visual Testing: The Missing Piece of the Puzzle -- presentation by Gil Tayar
Visual Testing: The Missing Piece of the Puzzle -- presentation by Gil TayarVisual Testing: The Missing Piece of the Puzzle -- presentation by Gil Tayar
Visual Testing: The Missing Piece of the Puzzle -- presentation by Gil Tayar
 
Software Testing
Software TestingSoftware Testing
Software Testing
 
Testing C# and ASP.net using Ruby
Testing C# and ASP.net using RubyTesting C# and ASP.net using Ruby
Testing C# and ASP.net using Ruby
 
Djangocon 2014 angular + django
Djangocon 2014 angular + djangoDjangocon 2014 angular + django
Djangocon 2014 angular + django
 
Unit-testing and E2E testing in JS
Unit-testing and E2E testing in JSUnit-testing and E2E testing in JS
Unit-testing and E2E testing in JS
 
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
Test-driven Development with Drupal and Codeception (DrupalCamp Brighton)
 
Creating a flawless user experience, end to-end, functional to visual - Slide...
Creating a flawless user experience, end to-end, functional to visual - Slide...Creating a flawless user experience, end to-end, functional to visual - Slide...
Creating a flawless user experience, end to-end, functional to visual - Slide...
 
Basics of Java Script (JS)
Basics of Java Script (JS)Basics of Java Script (JS)
Basics of Java Script (JS)
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example using
 
jQuery Performance Tips and Tricks
jQuery Performance Tips and TricksjQuery Performance Tips and Tricks
jQuery Performance Tips and Tricks
 
Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It's
 
jQuery for Sharepoint Dev
jQuery for Sharepoint DevjQuery for Sharepoint Dev
jQuery for Sharepoint Dev
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile way
 
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis LazuliGetting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
 
jQuery
jQueryjQuery
jQuery
 
Acceptance Testing With Selenium
Acceptance Testing With SeleniumAcceptance Testing With Selenium
Acceptance Testing With Selenium
 
Getting Answers to Your Testing Questions
Getting Answers to Your Testing QuestionsGetting Answers to Your Testing Questions
Getting Answers to Your Testing Questions
 
Test Infected Presentation
Test Infected PresentationTest Infected Presentation
Test Infected Presentation
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 

More from Applitools

Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...
Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...
Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...Applitools
 
Visual AI for eCommerce: Improving Conversions with a Flawless UI
Visual AI for eCommerce: Improving Conversions with a Flawless UIVisual AI for eCommerce: Improving Conversions with a Flawless UI
Visual AI for eCommerce: Improving Conversions with a Flawless UIApplitools
 
A Test Automation Platform Designed for the Future
A Test Automation Platform Designed for the FutureA Test Automation Platform Designed for the Future
A Test Automation Platform Designed for the FutureApplitools
 
Add AI to Your SDLC, presented by Applitools and Curiosity
Add AI to Your SDLC, presented by Applitools and CuriosityAdd AI to Your SDLC, presented by Applitools and Curiosity
Add AI to Your SDLC, presented by Applitools and CuriosityApplitools
 
The Future of AI-Based Test Automation
The Future of AI-Based Test AutomationThe Future of AI-Based Test Automation
The Future of AI-Based Test AutomationApplitools
 
Test Automation at Scale: Lessons from Top-Performing Distributed Teams
Test Automation at Scale: Lessons from Top-Performing Distributed TeamsTest Automation at Scale: Lessons from Top-Performing Distributed Teams
Test Automation at Scale: Lessons from Top-Performing Distributed TeamsApplitools
 
Can AI Autogenerate and Run Automated Tests?
Can AI Autogenerate and Run Automated Tests?Can AI Autogenerate and Run Automated Tests?
Can AI Autogenerate and Run Automated Tests?Applitools
 
Triple Assurance: AI-Powered Test Automation in UI Design and Functionality
Triple Assurance: AI-Powered Test Automation in UI Design and FunctionalityTriple Assurance: AI-Powered Test Automation in UI Design and Functionality
Triple Assurance: AI-Powered Test Automation in UI Design and FunctionalityApplitools
 
Navigating the Challenges of Testing at Scale: Lessons from Top-Performing Teams
Navigating the Challenges of Testing at Scale: Lessons from Top-Performing TeamsNavigating the Challenges of Testing at Scale: Lessons from Top-Performing Teams
Navigating the Challenges of Testing at Scale: Lessons from Top-Performing TeamsApplitools
 
Introducing the Applitools Self Healing Execution Cloud.pdf
Introducing the Applitools Self Healing Execution Cloud.pdfIntroducing the Applitools Self Healing Execution Cloud.pdf
Introducing the Applitools Self Healing Execution Cloud.pdfApplitools
 
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...Applitools
 
Collaborating From Design To Experience: Introducing Centra
Collaborating From Design To Experience: Introducing CentraCollaborating From Design To Experience: Introducing Centra
Collaborating From Design To Experience: Introducing CentraApplitools
 
What the QA Position Will Look Like in the Future
What the QA Position Will Look Like in the FutureWhat the QA Position Will Look Like in the Future
What the QA Position Will Look Like in the FutureApplitools
 
Getting Started with Visual Testing
Getting Started with Visual TestingGetting Started with Visual Testing
Getting Started with Visual TestingApplitools
 
Workshop: Head-to-Head Web Testing: Part 1 with Cypress
Workshop: Head-to-Head Web Testing: Part 1 with CypressWorkshop: Head-to-Head Web Testing: Part 1 with Cypress
Workshop: Head-to-Head Web Testing: Part 1 with CypressApplitools
 
From Washing Cars To Automating Test Applications
From Washing Cars To Automating Test ApplicationsFrom Washing Cars To Automating Test Applications
From Washing Cars To Automating Test ApplicationsApplitools
 
A Holistic Approach to Testing in Continuous Delivery
A Holistic Approach to Testing in Continuous DeliveryA Holistic Approach to Testing in Continuous Delivery
A Holistic Approach to Testing in Continuous DeliveryApplitools
 
AI-Powered-Cross-Browser Testing
AI-Powered-Cross-Browser TestingAI-Powered-Cross-Browser Testing
AI-Powered-Cross-Browser TestingApplitools
 
Workshop: An Introduction to API Automation with Javascript
Workshop: An Introduction to API Automation with JavascriptWorkshop: An Introduction to API Automation with Javascript
Workshop: An Introduction to API Automation with JavascriptApplitools
 

More from Applitools (20)

Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...
Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...
Streamlining Your Tech Stack: A Blueprint for Enhanced Efficiency and Coverag...
 
Visual AI for eCommerce: Improving Conversions with a Flawless UI
Visual AI for eCommerce: Improving Conversions with a Flawless UIVisual AI for eCommerce: Improving Conversions with a Flawless UI
Visual AI for eCommerce: Improving Conversions with a Flawless UI
 
A Test Automation Platform Designed for the Future
A Test Automation Platform Designed for the FutureA Test Automation Platform Designed for the Future
A Test Automation Platform Designed for the Future
 
Add AI to Your SDLC, presented by Applitools and Curiosity
Add AI to Your SDLC, presented by Applitools and CuriosityAdd AI to Your SDLC, presented by Applitools and Curiosity
Add AI to Your SDLC, presented by Applitools and Curiosity
 
The Future of AI-Based Test Automation
The Future of AI-Based Test AutomationThe Future of AI-Based Test Automation
The Future of AI-Based Test Automation
 
Test Automation at Scale: Lessons from Top-Performing Distributed Teams
Test Automation at Scale: Lessons from Top-Performing Distributed TeamsTest Automation at Scale: Lessons from Top-Performing Distributed Teams
Test Automation at Scale: Lessons from Top-Performing Distributed Teams
 
Can AI Autogenerate and Run Automated Tests?
Can AI Autogenerate and Run Automated Tests?Can AI Autogenerate and Run Automated Tests?
Can AI Autogenerate and Run Automated Tests?
 
Triple Assurance: AI-Powered Test Automation in UI Design and Functionality
Triple Assurance: AI-Powered Test Automation in UI Design and FunctionalityTriple Assurance: AI-Powered Test Automation in UI Design and Functionality
Triple Assurance: AI-Powered Test Automation in UI Design and Functionality
 
Navigating the Challenges of Testing at Scale: Lessons from Top-Performing Teams
Navigating the Challenges of Testing at Scale: Lessons from Top-Performing TeamsNavigating the Challenges of Testing at Scale: Lessons from Top-Performing Teams
Navigating the Challenges of Testing at Scale: Lessons from Top-Performing Teams
 
Introducing the Applitools Self Healing Execution Cloud.pdf
Introducing the Applitools Self Healing Execution Cloud.pdfIntroducing the Applitools Self Healing Execution Cloud.pdf
Introducing the Applitools Self Healing Execution Cloud.pdf
 
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
 
Collaborating From Design To Experience: Introducing Centra
Collaborating From Design To Experience: Introducing CentraCollaborating From Design To Experience: Introducing Centra
Collaborating From Design To Experience: Introducing Centra
 
What the QA Position Will Look Like in the Future
What the QA Position Will Look Like in the FutureWhat the QA Position Will Look Like in the Future
What the QA Position Will Look Like in the Future
 
Getting Started with Visual Testing
Getting Started with Visual TestingGetting Started with Visual Testing
Getting Started with Visual Testing
 
Workshop: Head-to-Head Web Testing: Part 1 with Cypress
Workshop: Head-to-Head Web Testing: Part 1 with CypressWorkshop: Head-to-Head Web Testing: Part 1 with Cypress
Workshop: Head-to-Head Web Testing: Part 1 with Cypress
 
From Washing Cars To Automating Test Applications
From Washing Cars To Automating Test ApplicationsFrom Washing Cars To Automating Test Applications
From Washing Cars To Automating Test Applications
 
A Holistic Approach to Testing in Continuous Delivery
A Holistic Approach to Testing in Continuous DeliveryA Holistic Approach to Testing in Continuous Delivery
A Holistic Approach to Testing in Continuous Delivery
 
AI-Powered-Cross-Browser Testing
AI-Powered-Cross-Browser TestingAI-Powered-Cross-Browser Testing
AI-Powered-Cross-Browser Testing
 
Workshop: An Introduction to API Automation with Javascript
Workshop: An Introduction to API Automation with JavascriptWorkshop: An Introduction to API Automation with Javascript
Workshop: An Introduction to API Automation with Javascript
 

Recently uploaded

EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 

Recently uploaded (20)

EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 

Visual Testing: Turbo-Charge Your Functional Tests with Visual Powers in Just 8 Lines of Code -- by Gil Tayar

  • 1. @giltayar You’re almost there: turbocharge your functional tests with visual powers Gil Tayar (@giltayar) August 2018 This presentation: http://bit.ly/turbocharge-webinar Github repo: https://github.com/giltayar/realworld-frontend-testing
  • 2. @giltayar@giltayar About Me ● My developer experience goes all the way back to the ‘80s. ● Am, was, and always will be a developer ● Testing the code I write is my passion ● Currently evangelist and architect @ Applitools ● We deliver Visual Testing tools: If you’re serious about testing, checkout Applitools Eyes ● Sometimes my arms bend back ● But the gum I like is coming back in style @giltayar
  • 5. @giltayar Tests, Tests, Glorious Tests! ● Unit ● Integration ● E2E ● Acceptance ● Visual ● Contract ● Browser ● Automation ● Functional ● And the list goes on…
  • 6. @giltayar Not to mention the different interpretations
  • 8. @giltayar Functional tests are automation tests that automate the browser in order to test the functionality of a web application* * Or a mobile app
  • 9. @giltayar Functional tests are automation tests that automate the browser in order to test the functionality of a web application* * Or a mobile app
  • 10. @giltayar Let’s write a Functional Test
  • 11. @giltayar ● Huge library (npm) ○ Biggest. ○ Very high quality ○ Lots of tests! ● DLL hell is gone (almost…) ● No bullshit libraries (readme-s, not javadocs) I love NodeJS ● Constantly improving in performance ● Fast startup times ● ES2018 is a wonderful language ● Async programming is wonderful ● Good FP language too ● Constantly evolving
  • 12. @giltayar ● All the cool new automation frameworks are in NodeJS/JavaScript ● It is the language of the frontend developers ○ Writing tests with the frontend developers ○ Code sharing! I love NodeJS
  • 13. @giltayar Let’s give a look at the app we’re testing
  • 14. @giltayar Let’s write a Functional Test in JavaScript! https://github.com/giltayar/realworld-frontend-testing, branch step1
  • 16. @giltayar All Functional Tests Look Like This ● Action ● Action ● Validation ● Action ● Validation ● Action ● Action ● Action ● Validation
  • 17. @giltayar Let’s do the following functional story https://github.com/giltayar/realworld-frontend-testing, branch step2
  • 18. @giltayar async function waitFor(selector) { await driver.wait( until.elementLocated(By.css(selector))) } async function setText(selector, text) { const field = await driver.findElement( By.css(selector)) await field.sendKeys(text) } Create some utility functions async function click(selector) { const element = await driver.findElement( By.css(selector)) await element.click() } async function getText(selector) { const element = await driver.findElement( By.css(selector)) return await element.getText() }
  • 20. @giltayar // action: browse to registration page await driver.get('http://localhost:3000/register' ) // action: set username, password, email to something await setText('input[placeholder=Username]' , 'ausername') await setText('input[placeholder=Password]' , 'aPassword') await setText('input[placeholder=Email]' , 'an@email.com' ) // action: submit form await click('button[type=submit]' ) Register the User
  • 21. @giltayar // action: browse to registration page await driver.get('http://localhost:3000/register' ) // action: set username, password, email to something await setText('input[placeholder=Username]' , 'ausername') await setText('input[placeholder=Password]' , 'aPassword') await setText('input[placeholder=Email]' , 'an@email.com' ) // action: submit form await click('button[type=submit]' ) Fragile Selector Problem Fragile selectors
  • 22. @giltayar class RegisterPage { async function registerUser(username, email, password) { // ... } } Example RegisterPage Object
  • 24. @giltayar await waitFor('img[alt=ausername]') // validate username expect(await getText('a[href="/@ausername"]')).to.equal('ausername') // validate articles list expect(await getText('.article-preview')) .to.equal('No articles are here... yet.') // validate active tab expect(await getText('.nav-link.active')).to.equal('Your Feed') Validate the Empty User Home Page
  • 26. @giltayar // action: click on new post const newPost = await driver.findElement (By.partialLinkText ('New Post')) await newPost.click() await waitFor('input[placeholder="Article Title"]' ) // action: set the title, description, and article await setText('input[placeholder="Article Title"]' , 'a title') await setText('input[placeholder="What's this article about?"]' , 'something' ) await setText('textarea[placeholder*="Write your article"]' , 'wonderful' ) // action: set the tags const tags = await driver.findElement (By.css('input[placeholder="Enter tags"]' )) for (const tag of ['a', 'b', 'c']) await tags.sendKeys(tag, Key.ENTER) // action: submit form await click('button[type=button]' ) Publish a Post
  • 27. @giltayar See that it’s there, and add a comment validation validation validation validation action action
  • 28. @giltayar await waitFor('h1') // validate title expect(await getText('h1')).to.equal('a title') // validate article content expect(await getText('.article-content')).to.include('wonderful') // validate tags expect(await getText('.tag-list')).to.equal('abc') Validate Post
  • 29. @giltayar // action: set comment await setText('textarea', 'a comment') // action: submit comment await click('button[type=submit]') Add Comment
  • 31. @giltayar await waitFor('div.card .card-block') // validate comment text expect(await getText('div.card .card-block')).to.equal('a comment') // validate comment username expect(await getText('div.card a.comment-author:nth-child(2)')) .to.equal('ausername') Validate Comment
  • 33. @giltayar // action: goto settings page await driver.get('http://localhost:3000/settings') await waitFor('button.btn-outline-danger') // action: click logout button await click('button.btn-outline-danger') Logout
  • 34. @giltayar Check Blog with anonymous user validation validation validation validation validation
  • 35. @giltayar // goto home page await driver.get('http://localhost:3000/') // validate post author expect(await getText('a.author')) .to.equal('ausername') // validate post title expect(await getText('.article-preview h1')) .to.equal('a title') // validate post description expect(await getText('.article-preview h1 + p')) .to.equal('something') // validate post tags expect(await getText('.article-preview ul')) .to.equal('abc') Validate Home Page for Anonymous User // validate popular tags expect(await getText('.sidebar .tag-list')) .to.equal('abc') // action: goto post page await click('.article-preview h1') await waitFor('.article-page') // validate post title expect(await getText('h1')).to.equal('a title') // validate article description expect(await getText('div.article-content p')) .to.equal('wonderful') // validate article tags expect(await getText('ul.tag-list')).to.equal('abc')
  • 36. @giltayar Problems with Actions ● Fragile Selectors ● Complex Code ● Solution: Page Objects
  • 37. @giltayar Problems with Validations ● Fragile Selectors ● Complex Code ● Too much to validate ● Only positive check ○ We don’t validate what we don’t know about ● Solution: Page Objects, partially
  • 39. @giltayar Let’s see why validations are holistic ● Add the following to Register.js: onSubmit: (username, email, password) => { dispatch({ type: UPDATE_FIELD_AUTH, key: 'username', value: '' }) const payload = agent.Auth.register(username, email, password); ● This will clear the username after every submit
  • 40. @giltayar Let’s see what the effect of this bug will be
  • 41. @giltayar But does the test pass? Yes, it does!
  • 43. @giltayar Let’s revert the “bug”, rebuild, and figure out how to solve the validation problem
  • 48. @giltayar Let’s do some live coding for that! https://github.com/giltayar/realworld-frontend-testing, branch step3
  • 49. @giltayar So we’ve replace this... expect(await getText('.error-messages' )).to.include("email can't be blank") With this… expect(Buffer.from(await driver.takeScreenshot (), 'base64')).to.matchImage( 'registration-blank-email-error' , )
  • 50. @giltayar Why is this better? It’s just one line replacing another
  • 51. @giltayar Solutions to problems with validations ● Fragile Selectors ○ No more selectors ● Complex Code ○ Same code for all validations ● Too much to validate ○ We validate holistically ● Only positive check ○ We validate things we didn’t even think of validating
  • 52. @giltayar Solutions to problems with validations ● Fragile Selectors ○ No more selectors ● Complex Code ○ Same code for all validations ● Too much to validate ○ We validate holistically ● Only positive check ○ We validate things we didn’t even think of validating
  • 53. @giltayar Let’s try it out... ● Run the tests without the bug ● Copy baseline image to expected-screenshots folder ● Add the following to Register.js: onSubmit: (username, email, password) => { dispatch({ type: UPDATE_FIELD_AUTH, key: 'username', value: '' }) const payload = agent.Auth.register(username, email, password); ● This will clear the username after every submit
  • 54. @giltayar Functional vs Visual Validations ● Let’s test it in step2: functional validations git checkout step2 && npm run build && npm test ● The test passes! (and it shouldn’t) ● Now let’s try step3: visual validations git checkout step2 && npm test ● The test fails! (as it should)
  • 55. @giltayar Let’s revert the “bug”, rebuild, and continue looking at visual vs. functional valiation
  • 56. @giltayar Functional Validations are Focused Visual Validations are Holistic
  • 57. @giltayar async function validatePost() { await waitFor('.validate-content') // validate title expect(await getText('h1')).to.equal('a title') // validate article content expect(await getText('.article-content')).to.include('wonderful') // validate tags expect(await getText('.tag-list')).to.equal('abc') } And we’ve change this...
  • 58. @giltayar async function validatePost() { await waitFor('.article-content') await checkWindow('new-post') } Into this...
  • 59. @giltayar // goto home page await driver.get('http://localhost:3000/') // validate post author expect(await getText('a.author')) .to.equal('ausername') // validate post title expect(await getText('.article-preview h1')) .to.equal('a title') // validate post description expect(await getText('.article-preview h1 + p')) .to.equal('something') // validate post tags expect(await getText('.article-preview ul')) .to.equal('abc') And this long code... // validate popular tags expect(await getText('.sidebar .tag-list')) .to.equal('abc') // action: goto post page await click('.article-preview h1') await waitFor('.article-page') // validate post title expect(await getText('h1')).to.equal('a title') // validate article description expect(await getText('div.article-content p')) .to.equal('wonderful') // validate article tags expect(await getText('ul.tag-list')).to.equal('abc')
  • 60. @giltayar async function validateBlog() { await driver.get('http://localhost:3000/') await checkWindow('anonymous-home-page') await click('.article-preview h1') await waitFor('.article-page') await checkWindow('anonymous-blog-post-view') } Into this...
  • 61. @giltayar Solutions to problems with validations ● Fragile Selectors ○ No more selectors ● Complex Code ○ Same code for all validations ● Too much to validate ○ We validate holistically ● Only positive check ○ We validate things we didn’t even think of validating
  • 62. @giltayar Problems with Naive Image Diffing ● Small anti-aliasing differences ○ Mac vs. Linux vs. Windows ○ Different GPUs ● Date/time problems ○ regions that are different from run to run ● Full screen vs. Viewport ● Comparing is a pain ● “Accepting” a new baseline is a pain
  • 63. @giltayar Problems with Naive Image Diffing ● Small anti-aliasing differences ○ Mac vs. Linux vs. Windows ○ Different GPUs ● Date/time problems ○ regions that are different from run to run ● Full screen vs. Viewport ● Comparing is a pain ● “Accepting” a new baseline is a pain
  • 65. @giltayar Cloud-based solution ● Visual diffing algorithms see like a human sees ○ Ignoring the small differences ○ AI-level algorithms are now involved and keep getting better ● Screenshot management tools are available, enabling you to ○ See the diffs ○ Approve new baselines ○ Open bugs on diffs that are bugs
  • 66. @giltayar Let’s Run the Demo https://github.com/giltayar/realworld-frontend-testing, branch step4
  • 67. @giltayar Let’s change some code to see some of the baseline management tooling
  • 69. @giltayar Supercharging Your Test with Visual Validations ● Write code that issues action after action, to create a long story ○ You can use a recorder like Selenium IDE or one of the new cloud-based ones ● Intersperse your code with visual validations ○ You can use the open-source solutions or a cloud-based option ● You get two for the price of one: ○ Much simpler functional validations ○ Visual validation of your page: catch those visual bugs that you couldn’t catch till now!
  • 70. @giltayar Thank You Gil Tayar (@giltayar) This presentation: http://bit.ly/turbocharge-webinar The Github repo: https://github.com/giltayar/realworld-frontend-testing