jest-runner-pekel

a jest runner for writing cucumber tests

Usage no npm install needed!

<script type="module">
  import jestRunnerPekel from 'https://cdn.skypack.dev/jest-runner-pekel';
</script>

README

< jest-runner-pekel >

Build Passing Build Passing

Jest Test Runner for the Cucumber Framework

npm i jest-runner-pekel

Table of Contents

Gherkin Features

Supported Feature Notes
:white_check_mark: And
:white_check_mark: Background
:white_check_mark: But
:white_check_mark: Comments
:white_check_mark: Data Table
:white_check_mark: DocString if pekel finds the docString is JSON, it will parse it for you
Rule haven't seen examples of this; not sure if it's worth it
:white_check_mark: Scenario
:white_check_mark: Scenario Outline

Cucumber Features

Supported Feature Notes
:white_check_mark: After called after each scenario in a feature file
:white_check_mark: AfterAll called after the feature file is completed; unlike Cucumber, you will have access to "this" context here.
Attachments
:white_check_mark: Before called before each scenario per feature file
:white_check_mark: BeforeAll called before the feature file is started; unlike Cucumber, you will have access to "this" context here.
:white_check_mark: Given
setDefaultTimeout use jest.setTimeout or set the timeout property in your jest config
:white_check_mark: setDefinitionFunctionWrapper
:white_check_mark: setWorldConstructor
Tags need to identify a way to pass tags through jest
:white_check_mark: Then
:white_check_mark: When

Getting Started

Jest Config

If you have existing jest test cases that do not use Cucumber, create a separate configuration. You can use the Jest CLI to run against specific configurations: jest --config=path/to/your/config.json

moduleFileExtensions:

 "moduleFileExtensions": [
    "feature",
    "js",
    "jsx",
    "ts",
    "tsx"
 ]

* If you are not using typescript, remove "ts" and "tsx"

runner:

"runner": "jest-runner-pekel"

setupFiles (optional):

 "setupFiles": [
    "<rootDir>/path/to/your/window-polyfill.ts"
 ]

* Add your polyfills here, and it is recommended that for integration testing to add your app entry component here.

setupFilesAfterEnv:

 "setupFilesAfterEnv": [
    "<rootDir>/path/to/your/world.ts",
    "<rootDir>/path/to/your/hooks.tsx",
    "<rootDir>/path/to/your/steps.ts"
 ]

testMatch:

 "testMatch": [
    "<rootDir>/path/to/your/features/*.feature"
 ]

transform:

"transform": {
    "^.+\\.(js|jsx|ts|tsx)quot;: "babel-jest"
}

* If you are not using typescript, remove "ts" and "tsx"

restoreMocks (optional):

"restoreMocks": true

If you are planning on writing integration tests, I highly recommend that you set this to true. There is an open bug for jest to fix an issue where it does not unset manual mocks that are defined using __mock__ folders. However, if this is set true, pekel will perform a scan of all __mock__ folders and files and manually unmock them for you.

Cucumber

Feature

path/to/your/features/button.feature

Feature: Button

Given I go to home
When I click the login button
Then the login button is not visible

Hooks

path/to/your/hooks.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import { AfterAll, BeforeAll } from 'cucumber';

import SignUp from './path/to/your/app';

BeforeAll(function () {
    ReactDOM.render(
        <SignUp/>,
        document.body
    )
});

AfterAll(function () {
    ReactDOM.unmountComponentAtNode(
        document.body
    )
});

You can choose to use the hooks to render/unmount your component before/after each feature file like above, or you can add a path to your application entry point to your jest configuration's setupFiles property. The latter is more performant.

Steps

path/to/your/steps.ts

import { Given, When, Then } from 'cucumber';
import expect from 'expect';

Given(/I go to (.*)$/, function(link) {
    window.location.hash = `#/${link}`;
});

When(/I click the (\S+) button$/, function(name) {
    document.querySelector(`[data-test-id="${name}"]`).click();
});

Then(/the (\S+) button is (visible|not visible)$/, function(name, state) {
    expect(!!document.querySelector(`[data-test-id="${name}"]`))
        .toEqual(state === 'visible')
});

World

setWorldConstuctor allows you to set the context of "this" for your steps/hooks definitions. This can be helpful when you want to maintain state between steps/hooks or want your steps/hooks to have access to some predefined data

path/to/your/world.ts

import { setWorldConstructor } from 'cucumber';

setWorldConstructor(
    class MyWorld {
        pages = [];
    }
);