Cecelia Martinez
When mobile development happens in a browser, why not?
Benefits
Limitations
Install Cypress in root of project directory
git clone https://github.com/ionic-team/ionic-conference-app.git
cd ionic-conference-app
npm install cypress --save-dev
Cypress folder structure
/cypress
/fixtures
- example.json
/integration
- tests.spec.js
/plugins
- index.js
/support
- commands.js
- index.js
Set baseUrl in cypress.json
/// cypress.json
{
"baseUrl": "http://localhost:8100"
}
// launch app
ionic serve
// THEN launch Cypress (separate terminal)
npx cypress open
Running the tests
/// tests.spec.js
describe("critical path", () => {
beforeEach(() => {
cy.viewport('iphone-5')
})
it('visits site', () => {
cy.visit('/')
})
})
Basic test structure
/// tests.spec.js cont.
it("swipes through tutorial", () => {
cy.enableTutorial();
cy.swipeLeft();
cy.swipeLeft();
cy.swipeLeft();
cy.contains("Continue").click();
})
it("adds a session from list to favorites", () => {
cy.disableTutorial();
cy.contains('University of Ionic').click({force: true});
cy.get('[data-cy=favorite]').click();
cy.get('[data-cy=back').click();
cy.contains('Favorites').click();
cy.contains('University of Ionic');
})
Critical path user flow
/// tests.spec.js
it("enables dark mode", () => {
cy.disableTutorial();
cy.get('[data-cy=menu]').click();
cy.get('[data-cy=dark-mode]').click();
cy.contains("Dark Mode").should('have.css', 'color', 'rgb(255, 255, 255)')
})
it("searches for a session and adds to favorites", () => {
cy.disableTutorial();
cy.get('[data-cy=search]').click();
cy.get('[data-cy=searchbar]').click().type("Angular{enter}")
cy.contains("Angular Directives").click();
cy.get('[data-cy=favorite]').click();
cy.get('[data-cy=back]').click();
cy.contains("Favorites").click();
cy.contains("Angular Directives");
})
Critical path user flow
/// cypress.json
{
"viewportHeight": 320,
"viewportWidth": 568
}
/// spec.js
cy.viewport(320, 568)
cy.viewport('iphone-5')
cy.viewport('iphone-5', 'landscape')
/// mobile-ui.spec.js
describe('mobile-tests', () => {
beforeEach(() => {
cy.viewport('iphone-5')
})
/// Tests here
})
import { Storage } from '@ionic/storage';
const storage = new Storage;
storage.set('name', 'Cecelia');
storage.get('age').then((val) => {
console.log('Your age is', val);
});
Ionic Storage is a free and open-source storage option built in to Ionic
/// cypress/support/commands.js
import { Storage } from '@ionic/storage';
const storage = new Storage;
Cypress.Commands.add('enableTutorial', () => {
cy.visit('/', {
onBeforeLoad () {
storage.set('ion_did_tutorial', false)
}
})
})
Custom Commands in Cypress
/// tests.spec.js
it("swipes through tutorial", () => {
cy.enableTutorial();
cy.swipeLeft();
cy.swipeLeft();
cy.swipeLeft();
cy.contains("Continue").click();
})
Custom Commands in Cypress
Cypress Custom Command + drag-and-drop example
/// cypress/support/commands.js
Cypress.Commands.add('swipeLeft', () => {
cy.get('.swiper-slide-active')
.trigger('mousedown', {position: "right"})
.trigger('mousemove', {clientX: 100, clientY: 275})
.trigger('mouseup', {force: true})
})
Use Custom Command in our test
/// cypress/support/commands.js
it("swipes through tutorial", () => {
cy.enableTutorial()
cy.swipeLeft()
cy.swipeLeft()
cy.swipeLeft()
cy.contains("Continue").click()
})
Installing Cypress
File structure
cypress.json baseUrl
Setting viewport
Cypress Custom Commands
Accessing app storage
simulate "swipe" functionality
The critical user path