A Beginner‘s Guide to Mobile Test Automation with Cypress

As a quality assurance engineer who has worked on over 350 mobile apps and responsive sites during my 12 year career, one consistent challenge I see teams face is validating functionality and UI across the ever-growing array of mobile browsers.

Manually testing on real smartphones and tablets takes substantial effort. Even with a small suite of 10 physical devices, attempting to cover multiple OS versions and viewport sizes is incredibly slow and error-prone. This constant fragmentation is precisely why automated mobile browser testing is so critical.

Cypress provides a robust set of tools for tackling responsive web and mobile app testing. Its native viewport handling and device presets enable setup in mere minutes. And capabilities like gesture commands, customized flows, and parallelization allow for advanced automation at scale.

This guide will take you from zero all the way through scripting robust mobile browser tests with Cypress, giving actionable code examples and recommendations every step of the way.

Why Mobile Matters More Than Ever

As phones and tablets continue proliferating, mobile usage grows exponentially year over year. To put things in perspective:

  • Average US adults spend 4 hours per day on their mobile device
  • 60% of website traffic now comes from mobile browsers

  • Unique mobile users surpassed 5 billion globally in 2019

With the shift towards mobility, delivering quality web experiences across different devices has become a make-or-break for many online businesses.

A major UK retailer saw conversions drop over 50% when its checkout flow was unusable on iPhones. Similar mobile website bugs account for millions in lost revenue annually.

The Rise of Responsive Design

In response to multi-device usage surging, responsive web design (RWD) emerged as an alternative to separate mobile apps.

RWD allows a single website to adapt its content and layout to look great on any screen size. As viewports change, elements will seamlessly resize, reorder, hide and show based on applied CSS breakpoint rules.

Example of a responsive site adjusting across desktop and mobile views

This fluidity enables optimal viewing but also creates significant QA challenges. Thorough testing is imperative to catch any viewport-specific defects.

Why Automated Testing is Essential

Attempting to validate every device manually is enormously expensive. Just acquiring all combinations of phones, tablets and screens quickly becomes cost-prohibitive:

Devices Avg Cost Total Cost
10 iPhones $899 $8,990
5 Samsung Phones $849 $4,245
3 iPads $479 $1,437
4 Android Tablets $299 $1,196
Total $15,868

When you factor in paying a QA team to hand test flows on every variation, costs grow exponentially.

Automated testing helps by tackling the repetitive validation checks programmatically. Cypress enables running cross-browser tests in parallel to cover more ground. And its Dashboard centralizes reporting to simplify analysis.

Just those facets alone drive dramatic productivity gains over manual testing. But Cypress offers many other benefits tailored to the unique constraints of mobile automation…

Emulating Mobile Devices with Cypress Viewports

Out of the box, Cypress leverages viewport handling to model dimensions and parameters of real world devices.

Using .viewport() you can pass any specific height/width values to simulate a given phone or tablet:

//iPhone 5S
cy.viewport(320, 568)  

//iPad Pro 
cy.viewport(1024, 1366)   

I recommend creating a separate describe block for each target viewport:

describe(‘Header Logo‘, () => {

  context(‘iPhone 5S‘, () => {
    beforeEach(() => {
       cy.viewport(320, 568) 
    })

    it(‘displays at small size‘, () => {
      // Test logic
    }) 
  })  

  context(‘iPad Pro‘, () => {
    beforeEach(() => {
      cy.viewport(1024, 1366)
    })

    it(‘displays at large size‘, () => {
     // Test logic
   })
 })

})

This isolates each test run and encapsulates setup code into reusable blocks.

Now let‘s explore some faster ways to start testing popular devices…

Leveraging Preset Device Profiles

Manually looking up viewport dimensions and plugging them becomes tedious. Luckily, Cypress has you covered with over a dozen preset profiles:

Phones

  • iphone-3
  • iphone-6
  • iphone-x
  • iphone-xr

Tablets

  • ipad-2
  • ipad-mini
  • samsung-s10

You can swap device names directly into .viewport():

cy.viewport(‘iphone-x‘)

Some of my go-to configurations I test against in nearly every project:

  • iPhone 7/8 – Popular iOS phone size
  • iPhone 12 Mini – Extra small widescreen display
  • iPad Air – Midsize 10-inch tablet
  • iPad Pro – Larger 12.9 inch tablet

Covering these gives me decent breadth to catch styling issues.

Later we‘ll look at extending with other mobile test helpers…

But first, let‘s tackle a common challenge around dynamic content and responsiveness.

Dealing with Dynamic Viewport-Dependent Content

Responsiveness often involves showing/hiding certain page elements based on available space.

For example, a mega menu may switch to a mobile hamburger menu on smaller widths. Or modal overlays could stack differently across device orientations.

Key Strategy: Don‘t make assertions based on exact element counts.

Instead focus validation checks on what should be visible for the active display size.

Here‘s an example:

// Testing mega menu on desktop  

cy.viewport(1280, 800)

cy.get(‘.mega-menu‘).should(‘be.visible‘)  

// Testing hamburger toggle on mobile

cy.viewport(‘iphone-x‘)

cy.get(‘.hamburger-toggle‘).should(‘be.visible‘)   

This ignores how many underlying nav items there may be and simply confirms the expected UI control appears given the viewport.

Some additional tips when dealing with dynamically adjusted content:

Use Conditional Testing

const width = Cypress.config(‘viewportWidth‘)

if (width < 768) {
  // Validate mobile menu
} else {
  // Validate mega menu
}

Watch for Hidden Elements

Elements may still be in DOM but display: none. Ensure .should(‘be.visible‘)

Leverage Helper Libraries

Cypress Real Events facilitates triggering events like resize to force content updates after viewport changes.

Native Mobile Simulation with Cypress Ionic

So far we focused on visual testing by changing viewport dimensions. But for web apps that adapt to touch devices, users interact via taps, swipes and gestures vs. mouse clicks.

Simulating these native mobile inputs takes additional work. This is where add-ons like Cypress Ionic Framework comes in handy.

Ionic extends Cypress‘ API with commands for triggering actions like:

Gestures

cy.ionSwipeLeft() // Swipe screen left
cy.ionSwipeRight() // Swipe screen right  

cy.ionDrag() // Drag element across screen

cy.ionPINCH() // Pinch screen 
cy.ionSpread() // Spread fingers on screen

Device

cy.ionShake() // Shake device 
cy.ionLockOrientation() 
cy.ionUnlockOrientation()

App Elements

cy.ionRouteNav() // Nav through app history
cy.ionBackButton() // Simulate back button

cy.ionKeyboardOpen() // Open mobile keyboard
cy.ionKeyboardClose() // Close keyboard 

cy.ionAlert() // Interact with native alerts
cy.ionToast() // Interact with toasts 

This adds tremendous value on top of Cypress for catching issues around tap targets, gesture support, orientation changes and more.

Step-By-Step Guide For Building A Mobile Test Suite

We‘ve explored techniques like viewport manipulation, using real device presets, simulating events, etc. Now let‘s walk through putting together an automated test suite:

1. Install Cypress and Dependencies

Make sure Cypress is installed locally and you have any device libraries imported:

npm install cypress --save-dev
npm install cypress-ionic --save-dev
npm install cypress-real-events --save-dev

2. Configure test runner

In cypress/plugins/index.js:

module.exports = (on) => {
  on(‘before:browser:launch‘, (browser = {}, launchOptions) => {
    if (browser.family === ‘chromium‘) {
      launchOptions.args.push(‘--disable-dev-shm-usage‘)  
    }

    return launchOptions  
  })
}

3. Add folder structure

Under /cypress/integration add mobile-tests folder with individual spec files per component.

Keep device contexts isolated.

4. Begin writing test scripts

Start with sample file: mobile-tests/viewport-spec.js

Import commands needed:

import ‘cypress-ionic‘
import ‘cypress-real-events‘

Add base device setup:

beforeEach(() => {
  cy.viewport(‘iphone-x‘)
})

Author validation checks:

it(‘displays mobile menu on tap‘, () => {

  cy.get(‘.hamburger-btn‘).as(‘menuBtn‘) 

  cy.ionTap(@menuBtn)

  cy.get(‘.mobile-menu‘).should(‘be.visible‘) 

})

5. Extend test cases

Build out robust validation per component:

  • Header
  • Navigation
  • Buttons
  • Forms

etc across various devices.

6. Run test suite

cypress open

or

cypress run

7. Generate reports

Install plugin to export results:

npm install -D cypress-multi-reporters mocha-junit-reporter

Configure mochawesome reporting in cypress.json file.

Key Strategies for Smooth Mobile Test Automation

Streamlining and scaling a mobile test pipeline requires some thoughtful design decisions early on. Through many projects I‘ve found several guidelines help tame the moving pieces:

Isolate Test Suite by Device Family

Maintain separate folders for web vs native app testing needs:

cypress/
  - integrations
     - web
        - iphone
        - samsung
        - huawei 
     - native
        - ios
        - android

Centralize Viewport Controls

Avoid duplicate viewport code with Cypress commands:

/cypress/commands.js

Cypress.Commands.add(‘setMobilePhone‘, size => {
  if (size === ‘small‘) { 
    cy.viewport(‘iphone-5‘)
  } else if  {
    cy.viewport(‘iphone-x‘) 
  }
})

Cypress.Commands.add(‘setTablet‘, size => {
 // Tablet sizes
})

Then test scripts simply call:

cy.setMobilePhone(‘small‘)

Configure CI Pipeline Early

Determine hosting needs, scheduling, grouping, parallelization, reporting integrations, etc.

Review Failures in Dashboard

Visual diffing makes it easier to catch layout mishaps.

Add Wait-Fors

Mobile connections can be flaky. Use wait commands for stability:

cy.wait(‘@getUserData‘) // Wait for API response

cy.get(‘.page-loader‘, {timeout: 10000}) // Wait on DOM element

Simplify Debugging with Videos

Records test runs to pinpoint flakiness easier.

Ready to Start Building?

Hopefully this gives you a comprehensive blueprint for tackling test automation across the growing landscape of mobile browsers with Cypress.

As devices continue proliferating, having a scalable way to catch visual and functional defects becomes increasingly important. Cypress delivers the right tools and cloud infrastructure to make continuous testing achievable at scale.

The key comes in establishing the right workflows early on. Separate mobile from web tests. Break devices into contexts. Follow coding patterns promoting reuse across projects. Model real world usage with gestures and native bridge commands. Then leverage parallelization and analytics through the Dashboard to reach coverage goals faster.

To quickly ramp up your real device cloud testing, I highly recommend checking out Cypress Test Cloud which automates test distribution and maintenance of a private device lab pool. Saving you tons of overhead.

Let me know if any other mobile testing questions come up! With over a decade of hands-on device experience, I‘m always happy to help others shortcut common mobile QA pitfalls I‘ve encountered along the way.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.