npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@silverstripe-bespoke/cypress-bespoke-shared

v0.0.4

Published

Generic Cypress Cucumber steps

Downloads

251

Readme

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

| Step | Parameters | Description | Example | |---|---|---|---| |I am on the {string}| Page object name | This will set the current page object context | Given I am on the "HomePage"| |I navigate to the {string}| Page Object Name | This 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 Name | This will set the current page object context, useful when testing distinct features on another page| Given I am testing the "Header"| |I visit {string}| url string | This will navigate to a given url | Given I visit "/"| |I request {string}| url string | This will make a get request to the given url| Given I request "/api"| |I am on desktop| none | This will change the viewport to a desktop size || |I am on tablet| none | This will change the viewport to a tablet size || |I am on mobile| none | This will change the viewport to a mobile size ||

Then

Browser state

| Step | Parameters | Description | Example | |---|---|---|---| |I should see the title is {string} in the browser| title text | Checks the page title | Then I should see the title is "Home" in the browser | |I should see the url includes {string}| url fragment | Checks the url contains a substring | Then I should see the url includes "/home"|

Visibility

| Step | Parameters | Description | Example | |---|---|---|---| |I should see the {string} is visible | page element name | checks the given page element is visible| Then I should see the "Main navigation" is visible| |I should see the {string} of the {string} is visible | ordinal position, page element name | checks the first, second, third etc. of a given page element is visible| Then I should see the "first" of the "Main navigation items" is visible| |I should see the last of the {string} is visible | page element name | checks the last of a given page element is visible| Then I should see the last of the "Main navigation items" is visible| ||||| |I should see the {string} is not visible | page element name | checks the given page element is not visible| Then I should see the "Main navigation" is not visible| |I should see the {string} of the {string} is not visible | ordinal position, page element name | checks the first, second, third etc. of a given page element is not visible| Then I should see the "second" of the "Main navigation items" is not visible| |I should see the last of the {string} is not visible | page element name | checks the last of a given page element is not visible| Then I should see the last of the "Main navigation items" is not visible| ||||| |I should see the {string} is in the viewport | page element name | checks the given page element is in the viewport. Requires the isInViewport assertion | Then I should see the "tool tip" is in the viewport| |I should see the {string} is not in the viewport | page element name | checks the given page element is not in the viewport. Requires the isInViewport assertion | Then I should see the "tool tip" is not in the viewport| ||||| |I should see {int} {string}| number and page element name | counts how many of a page element are present| `Then I should see 5 "list items"|

Exists

| Step | Parameters | Description | Example | |---|---|---|---| |I should see the {string} exists | page element name | checks the given page element exists| Then I should see the "Main navigation" exists| |I should see the {string} of the {string} exists | ordinal position, page element name | checks the first, second, third etc. of a given page element exists| Then I should see the "first" of the "Main navigation items" exists| |I should see the last of the {string} exists | page element name | checks the last of a given page element exists| Then I should see the last of the "Main navigation items" exists| ||||| |I should see the {string} does not exist | page element name | checks the given page element does not exist| Then I should see the "Main navigation" does not exist| |I should see the {string} of the {string} does not exist | ordinal position, page element name | checks the first, second, third etc. of a given page element does not exist| Then I should see the "fourth" of the "Main navigation items" does not exist| |I should see the last of the {string} does not exist | page element name | checks the last of a given page element does not exist| Then I should see the last of the "Main navigation items" does not exist|

Content assertions

| Step | Parameters | Description | Example | |---|---|---|---| |I should see the {string} contains {string}| page element name, text | Check if an page element contains a given string | Then I should see the "button" contains "Read More"| |I should see the {string} has attribute {string}| page element name, attribute name| Checks a page element has a given attribute| Then I should see the "menu" has attribute "hidden"| |I should see the {string} does not have attribute {string}| page element name, attribute name| Checks a page element does not have a given attribute| Then 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 value | Checks a page element has a given attribute with a given value| Then I should see the "menu" has attribute "aria-expanded" with value "false"|

Forms

| Step | Parameters | Description | Example | |---|---|---|---| |I should see the {string} form field has value {string}| page element name, field value | Checks a page element has a given attribute with a given string value| Then I should see the "email" form field has value "[email protected]"|

Wait

| Step | Parameters | Description | Example | |---|---|---|---| |I wait {int} seconds| seconds | This will make the test wait for a given length of time | Given I wait 5 seconds |I wait a bit| none | Adds a 500ms wait step to the test, useful for quick animations or interactions | Then I wait a bit|

Meta states

coming soon

Content assertions

| Step | Parameters | Description | Example | |---|---|---|---| |I should see the {string} element receive focus| page element name | Checks an element is in the focus state| Then I should see the "button" element receive focus|

When

Press

| Step | Parameters | Description | Example | |---|---|---|---| |I press the {string} element| page element name | Clicks or touches a page element | When I press on the "button" element| |I press the first {string} element| page element name | Clicks or touches the first of a list of page elements | When I press the first "button" element| |I press the second {string} element| page element name | Clicks or touches the second of a list of page elements | When I press the second "button" element|

Keyboard interactions

| Step | Parameters | Description | Example | |---|---|---|---| |I press the Enter key on {string} element| page element name | Presses the <enter> key on the keyboard | When I press the Enter key on "button" element| |I press the tab key| none | Presses the <tab> key on the keyboard | When I press the tab key| |I press the tab key on {string}| page element name | Presses the <tab> key on a particular element | When I press the tab key on "link"| |I type {string} into the {string} field| field value, page text field | Types the content into the field element | When 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);