0.0.4 • Published 10 months ago

@silverstripe-bespoke/cypress-bespoke-shared v0.0.4

Weekly downloads
-
License
ISC
Repository
-
Last release
10 months ago

Cypress Shared Module

This module contains common patterns for using Cypress with Cucumber (via @badeball/cypress-cucumber-preprocessor).

Getting started

yarn add @silverstripe-bespoke/cypress-bespoke-shared --dev

How to use this module

This module will add generic Cucumber steps to your cypress project. The steps contained in this module is designed to be used with a Page Object Model so you will nee to supply at least one Page object and call the follwing in your global.cy.js file:

import createGenericSteps from '@silverstripe-bespoke/cypress-bespoke-shared';
import pageObjects from './your-project-somewhere';

createGenericSteps(pageObjects);

you can then start using the Steps included in this module.

Page Objects

Page objects mediate between the test code and your application. Think of if as where the natural language of a Cucumbers step is translated into code.

To do this Page objects have two required properties url and elements as below:

type PageObject = {
    readonly url: string,
    elements: {
        [index: string]: string
    }
}

The url will be used by Cypress to navigate to this page (via cy.visit()).

The elements object is a map of element names as they appear in steps to a valid JavaScript selector. Eg {'Main navigation': 'nav[role="main"]'}. Test steps then only need to refer to the element name eg Then the "Main navigation" is visible.

Steps included in this module

Given

StepParametersDescriptionExample
I am on the {string}Page object nameThis will set the current page object contextGiven I am on the "HomePage"
I navigate to the {string}Page Object NameThis will set the current page object context and navigate to that page. This is normally the first step in a test.Given I navigate to the "HomePage"
I am testing the {string}Page Object NameThis will set the current page object context, useful when testing distinct features on another pageGiven I am testing the "Header"
I visit {string}url stringThis will navigate to a given urlGiven I visit "/"
I request {string}url stringThis will make a get request to the given urlGiven I request "/api"
I am on desktopnoneThis will change the viewport to a desktop size
I am on tabletnoneThis will change the viewport to a tablet size
I am on mobilenoneThis will change the viewport to a mobile size

Then

Browser state

StepParametersDescriptionExample
I should see the title is {string} in the browsertitle textChecks the page titleThen I should see the title is "Home" in the browser
I should see the url includes {string}url fragmentChecks the url contains a substringThen I should see the url includes "/home"

Visibility

StepParametersDescriptionExample
I should see the {string} is visiblepage element namechecks the given page element is visibleThen I should see the "Main navigation" is visible
I should see the {string} of the {string} is visibleordinal position, page element namechecks the first, second, third etc. of a given page element is visibleThen I should see the "first" of the "Main navigation items" is visible
I should see the last of the {string} is visiblepage element namechecks the last of a given page element is visibleThen I should see the last of the "Main navigation items" is visible
I should see the {string} is not visiblepage element namechecks the given page element is not visibleThen I should see the "Main navigation" is not visible
I should see the {string} of the {string} is not visibleordinal position, page element namechecks the first, second, third etc. of a given page element is not visibleThen I should see the "second" of the "Main navigation items" is not visible
I should see the last of the {string} is not visiblepage element namechecks the last of a given page element is not visibleThen I should see the last of the "Main navigation items" is not visible
I should see the {string} is in the viewportpage element namechecks the given page element is in the viewport. Requires the isInViewport assertionThen I should see the "tool tip" is in the viewport
I should see the {string} is not in the viewportpage element namechecks the given page element is not in the viewport. Requires the isInViewport assertionThen I should see the "tool tip" is not in the viewport
I should see {int} {string}number and page element namecounts how many of a page element are present`Then I should see 5 "list items"

Exists

StepParametersDescriptionExample
I should see the {string} existspage element namechecks the given page element existsThen I should see the "Main navigation" exists
I should see the {string} of the {string} existsordinal position, page element namechecks the first, second, third etc. of a given page element existsThen I should see the "first" of the "Main navigation items" exists
I should see the last of the {string} existspage element namechecks the last of a given page element existsThen I should see the last of the "Main navigation items" exists
I should see the {string} does not existpage element namechecks the given page element does not existThen I should see the "Main navigation" does not exist
I should see the {string} of the {string} does not existordinal position, page element namechecks the first, second, third etc. of a given page element does not existThen I should see the "fourth" of the "Main navigation items" does not exist
I should see the last of the {string} does not existpage element namechecks the last of a given page element does not existThen I should see the last of the "Main navigation items" does not exist

Content assertions

StepParametersDescriptionExample
I should see the {string} contains {string}page element name, textCheck if an page element contains a given stringThen I should see the "button" contains "Read More"
I should see the {string} has attribute {string}page element name, attribute nameChecks a page element has a given attributeThen I should see the "menu" has attribute "hidden"
I should see the {string} does not have attribute {string}page element name, attribute nameChecks a page element does not have a given attributeThen I should see the "menu" does not have attribute "hidden"
I should see the {string} has attribute {string} with value {string}page element name, attribute name, attribute valueChecks a page element has a given attribute with a given valueThen I should see the "menu" has attribute "aria-expanded" with value "false"

Forms

StepParametersDescriptionExample
I should see the {string} form field has value {string}page element name, field valueChecks a page element has a given attribute with a given string valueThen I should see the "email" form field has value "test@test.com"

Wait

StepParametersDescriptionExample
I wait {int} secondssecondsThis will make the test wait for a given length of timeGiven I wait 5 seconds
I wait a bitnoneAdds a 500ms wait step to the test, useful for quick animations or interactionsThen I wait a bit

Meta states

coming soon

Content assertions

StepParametersDescriptionExample
I should see the {string} element receive focuspage element nameChecks an element is in the focus stateThen I should see the "button" element receive focus

When

Press

StepParametersDescriptionExample
I press the {string} elementpage element nameClicks or touches a page elementWhen I press on the "button" element
I press the first {string} elementpage element nameClicks or touches the first of a list of page elementsWhen I press the first "button" element
I press the second {string} elementpage element nameClicks or touches the second of a list of page elementsWhen I press the second "button" element

Keyboard interactions

StepParametersDescriptionExample
I press the Enter key on {string} elementpage element namePresses the <enter> key on the keyboardWhen I press the Enter key on "button" element
I press the tab keynonePresses the <tab> key on the keyboardWhen I press the tab key
I press the tab key on {string}page element namePresses the <tab> key on a particular elementWhen I press the tab key on "link"
I type {string} into the {string} fieldfield value, page text fieldTypes the content into the field elementWhen I type "This is a text field" into the "input" field

Example setup

The following shows a basic cypress setup using this module:

Setup re-usable components inside cypress/page_objects/components directory:

e.g. Header.js

export default {
  'Header': '.header',
  'Header logo': '.header__logo',
}

Setup an page object as follows in your cypress/page_objects directory:

import Header from '../components/Header';

export class TestPage {
  static url = '/test-page/';

  static elements = {
    ...Header,
    'Cta Block Container': '.cta-block',
    'Cta Block Header': '.cta-block .cta-block__title',
		'Cta Block Links': '.cta-block .cta-block__links'
  }
}

Add this page to the index file cypress/page_objects/index.js:

import TestPage from './testPage';

const pages = {
  TestPage: TestPage,
};

export default pages;

Import the page objects to your cypress/common/global.cy.js file:

import Pages from '../page_objects';
import createSharedSteps from '@silverstripe-bespoke/cypress-bespoke-shared'

createSharedSteps(Pages);

You can now use these steps in a feature file e.g. cypress/e2e/TestPage.feature

Feature: Test Page feature

@desktop
Scenario: A Test page has a CTA block
  Given I am on desktop
  And I navigate to the "TestPage"
  Then I should see the "Cta Block Container" is visible
  And I should see the "Cta Block Header" is visible
  And I should see the "Cta Block Header" contains "Example title"
  And I should see the "third" of the "Cta Block Links" is visible

Is in viewport assertion

Add this to the cypress/support/assertions.js file:

const isInViewport = (_chai, utils) => {
  function assertIsInViewport(options) {
    const subject = this._obj;

    const bottom = Cypress.$(cy.state('window')).height();
    const rect = subject[0].getBoundingClientRect();

    // Keeping our "is in viewport" check simple. If the top of the element is anywhere in our viewport, and if the
    // bottom of the element is lower than the top of our viewport, then we will consider this to be "in view"
    this.assert(
      rect.top > 0 && rect.bottom > 0 && rect.top <= bottom,
      "expected #{this} to be in viewport",
      "expected #{this} to not be in viewport",
      this._obj
    )
  }

  _chai.Assertion.addMethod('inViewport', assertIsInViewport)
};

chai.use(isInViewport);
0.0.4

10 months ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

2 years ago