@hypercubed/cypress-gherkin
v2.1.1
Published
Gherkin syntax in Cypress
Downloads
288
Readme
cypress-gherkin
Gherkin syntax in Cypress
Overview
Enable a Gherkin-like syntax for tests in Cypress.io.
Installation
npm i --save-dev @hypercubed/cypress-gherkin
Usage
cypress-gherkin
is not a preprocessor and, therefore, doesn't support cucumber feature and step definition files (see Credits and alternatives if that is what you want). Instead cypress-gherkin
is designed to work with and alongside existing Cypress tests.
By way of example let's start with a simple existing cypress test:
describe('My First Test', () => {
it('Navigates on click', () => {
cy.visit('https://example.cypress.io');
cy.contains('type').click();
cy.url().should('include', '/commands/actions')
});
it('Types and asserts', () => {
cy.visit('https://example.cypress.io/commands/actions');
cy.get('.action-email').type('[email protected]');
cy.get('.action-email').should('have.value', '[email protected]');
});
});
We can import feature
and scenario
from cypress-gherkin
. feature
and scenario
are aliases for describe
and it
respectively.
import { feature, scenario } from '@hypercubed/cypress-gherkin';
feature('My First Test', () => {
scenario('Navigates on click', () => {
cy.visit('https://example.cypress.io');
cy.contains('type').click();
cy.url().should('include', '/commands/actions')
});
scenario('Types and asserts', () => {
cy.visit('https://example.cypress.io/commands/actions');
cy.get('.action-email').type('[email protected]');
cy.get('.action-email').should('have.value', '[email protected]');
});
});
To use Gherkin syntax we need to add Given
, When
, Then
step definitions and replace the test sequences with matching given
, when
, then
steps. See Gherkin Reference for more information on the Gherkin syntax itself.
import { feature, scenario, Given, When, Then, given, when, then } from '@hypercubed/cypress-gherkin';
Given('a user visits {string}', (s: string) => {
return cy.visit(s);
});
When('they click the link labeled {string}', (s: string) => {
return cy.get('a').contains(s).click();
});
When('they type {string} into the {string} input', (e: string, s: string) => {
return cy.get(s).type(e);
});
Then('the URL should include {string}', (s: string) => {
return cy.url().should('include', s);
});
Then('the {string} input has {string} as its value', (e: string, s: string) => {
return cy.get(e).should('have.value', s);
});
feature('My First Test', () => {
scenario('Navigates on click', () => {
given('a user visits "https://example.cypress.io"');
when('they click the link labeled "type"');
then('the URL should include "/commands/actions"');
});
scenario('Types and asserts', () => {
given('a user visits "https://example.cypress.io/commands/actions"');
when('they type "[email protected]" into the ".action-email" input');
then('the ".action-email" input has "[email protected]" as its value');
});
});
This cypress test, now written in Gherkin syntax, will run similar to before. In the Cypress Test Runner you can see the Gherkin steps, snapshots and additional information:
Finally, as a bonus, you can use Gherkin text directly:
import { feature, scenario, Given, When, Then, gherkin } from '@hypercubed/cypress-gherkin';
Given('a user visits {string}', (s: string) => {
return cy.visit(s);
});
When('they click the link labeled {string}', (s: string) => {
return cy.get('a').contains(s).click();
});
When('they type {string} into the {string} input', (e: string, s: string) => {
return cy.get(s).type(e);
});
Then('the URL should include {string}', (s: string) => {
return cy.url().should('include', s);
});
Then('the {string} input has {string} as its value', (e: string, s: string) => {
return cy.get(e).should('have.value', s);
});
gherkin(
`
Feature: My First Test
Scenario: Navigates on click
Given a user visits "https://example.cypress.io"
When they click the link labeled "type"
Then the URL should include '/commands/actions'
Scenario: Types and asserts
Given a user visits "https://example.cypress.io/commands/actions"
When they type "[email protected]" into the ".action-email" input
Then the '.action-email' input has "[email protected]" as its value
`
);
However, using the Gherkin syntax allows mixing Gherkin syntax and cypress commands:
describe('Gherkin syntax mixed with Cypress', () => {
before(( )=> {
given('a user visits "https://example.cypress.io"')
});
scenario('Navigates on click', () => {
cy.get('a').contains('type').click();
then('the URL should include "/commands/actions"');
});
feature('a feature', () => {
beforeEach(() => {
given('a user visits "https://example.cypress.io/commands/actions"');
and('they type "[email protected]" into the ".action-email" input');
});
it('Types and asserts', () => {
then('the ".action-email" input has "[email protected]" as its value')
.and('have.class', 'form-control');
then('the ".action-email" input should:', ($e: any) => {
expect($e).to.have.value("[email protected]");
});
});
});
});
API Details
Many of the gherkin syntax methods are aliases of Mocha’s bdd syntax:
| Gherkin Keyword | Gherkin-syntax | Mocha |
| ---------------- | ----------------- | ------------ |
| Feature | feature
| describe
|
| Rule | rule
| describe
|
| Scenario Outline | scenarioOutline
| describe
|
| Rule | rule
| describe
|
| Background | background
| beforeEach
|
| Scenario | scenario
| it
|
Step Definitions
Step definitions (Given
, When
, Then
) define the steps taken in each gherkin-step (given
, when
and then
, and
, but
). In step definitions you can use Regular Expressions or Cucumber Expressions.
For example, to use the Gherkin step:
Given a user visits {string}
first define a step definition:
import { Given } from '@hypercubed/cypress-gherkin';
Given('a user visits {string}', (s: string) => {
return cy.visit(s);
});
which is invoked with the following gherkin-step:
given('a user visits "https://example.cypress.io"');
Scenario Outline
As described above scenario
is simply an alias for it
. However, scenarioOutline
is an alias for describe
. Within an scenarioOutline
you cna define a "Scenario Template" and one more more examples using the outline
and examples
syntax methods (respectively).
For example, one my translate the following Gherkin text:
Feature: Example Tables
Scenario Outline: eating cucumbers
Given there are <start> cucumbers
When I eat <eat> cucumbers
Then I should have <left> cucumbers
Examples: These are passing
| start | eat | left |
| 12 | 5 | 7 |
| 20 | 5 | 15 |
Examples: These are also passing
| start | eat | left |
| 22 | 5 | 17 |
| 10 | 5 | 5 |
to the gherkin-syntax:
feature('Examples Tables in Gherkin syntax', () => {
scenarioOutline(`eating cucumbers`, () => {
outline(() => {
given('there are <start> cucumbers');
when('I eat <eat> cucumbers');
then('I should have <left> cucumbers');
});
examples('These are passing', [
['start', 'eat', 'left'],
[12, 5, 7],
[20, 5, 15]
]);
examples('These are also passing', [
['start', 'eat', 'left'],
[12, 5, 7],
[20, 5, 15]
]);
});
});
which is functionally equivalent to:
feature('Examples Tables in Gherkin text', () => {
describe('eating cucumbers', () => {
describe('These are passing', () => {
scenario('example #1', () => {
given('there are 12 cucumbers');
when('I eat 5 cucumbers');
then('I should have 7 cucumbers');
});
scenario('example #2', () => {
given('there are 20 cucumbers');
when('I eat 5 cucumbers');
then('I should have 15 cucumbers');
});
});
describe('These are also passing', () => {
scenario('example #1', () => {
given('there are 22 cucumbers');
when('I eat 5 cucumbers');
then('I should have 17 cucumbers');
});
scenario('example #2', () => {
given('there are 10 cucumbers');
when('I eat 5 cucumbers');
then('I should have 5 cucumbers');
});
});
});
});
CLI
gherkin-syntax
includes a simple CLI tool for converting feature files to gherkin syntax. This CLI is invoked using UNIX-like pipelines.
For example:
cat my-feature.feature | node ./node_modules/.bin/cypress-gherkin
will output a TypeScript scaffold of the feature in gherkin-syntax.
Use the >
operator to generate a file:
cat my-feature.feature | node ./node_modules/.bin/cypress-gherkin > my-feature.feature.ts
Credits and alternatives
Based on and inspired by cypress-cucumber-preprocessor and picklejs.
License
This project is licensed under the MIT License - see the LICENSE file for details