Pickle JS

Cucumber with Brine

Written By: @tolicodes at @hoverinc

Writing Tests Sucks...

  • So many frameworks
  • Different syntax and APIs to remember
  • Monotonous
  • Time Intensive
  • Lots of debugging
  • Drivers don't work
  • Difficult to set up
  • Way too slow

Enter Cypress

  • What Selenium should've been
  • Simple, beautiful, and works immediately
  • No extensions needed
  • Simple jQuery-like selectors
  • Super fast - no Selenium wrapper needed
  • Features: parallelization, recording, reporting


Time travel

Debug in Chrome DevTools

Live reload

Auto wait/sleep

Class-A stubbing

Recording test runs

Stable, complete and built from scratch





Scenario: I should be able to search for a doc
    # An AJAX Search Happens Here
    When I type "recommended" into the "Search Input" in the "Header"
    Then I should see "Recommended Cypress Setup" in the "Search Result" in the "Header"
    # A redirect happens here
    When I click the "Search Result" in the "Header" containing "Recommended Cypress Setup"
    Then I should be redirected to "Recommended Cypress Setup"


// That's all you need to do to stub an endpoint!
cy.route('GET', '/users/*', {
  id: 1,
  name: 'toli'

// or put it in a file
cy.route('GET', '/users/*', 'users.json');


One Framework to Rule Them All

Stubbing - Assertions - Screenshot Diff - Recording -
Reporting - Test Runner - Browser Control



Write tests in plain English

Regular expression turns it into code

Scenario: I should be able to login
    When I open the "Login Page"
    And I type "toli@tolicodes.com" into the "Email Field"
    And I type "ilovepickles" into the "Password Field"
    And I click "Submit"

    Then I should see the "Login Successful" modal

As a developer, product manager, or QA  engineer,
I should be able to read and write feature tests without
programming knowledge


When I open "Some Page"
When I click "Some Element" inside "Some Container"
When I type "some text" into "Some Field"
When I scroll to the bottom of the page
When I drag "Some Element" above "Some Other Element"
When I take a snapshot named "Cheese"

Then I should be redirected to "the Home Page"
Then I should see 2 "Elements" containing "hello!"
Then I should see an "Element" in the "Container"
Then I should see a "red" background on the "Button"
Then I should see a "blue" border on the "Button"

95% of tests I write use the same patterns

Why write custom regular expressions every time?


No Javascript

Centralizing selectors

Selectors for styled components

Flexible grammar

Fixture & stubbing management

Enumerating elements

Sharing state


NO Javascript

  "Account Container": {
    "default": ".AccountSelection"
    "Title": ".Title"
    "Message": ".Message"
    "Accounts Select": ".AccountsSelect",
    "Next Button": "input:contains('Next')"
  "Account Confirmation Modal": {
     "default": ".AccountConfirmationModal"
Scenario: I select an account from the account modal

    When I select "PICKLE FARM" from the 
         "Account Select" in the "Account Modal"
    And  I click the "Next Button" in 
         the "Account Modal"

    Then I should see an 
         "Account Confirmation Modal"

Just write it in English!

Centralizing selectors

  "Account Container": {
    "default": ".AccountSelection"
    "Title": ".Title"
    "Message": ".Message"
    "Accounts Select": ".AccountsSelect",
    "Next Button": "input:contains('Next')"
  "Account Confirmation Modal": {
     "default": ".AccountConfirmationModal"

The first key concept of PickleJS is keeping all your selectors and page URLs in one place and only refer to them by human-readable names

  "Home": "/",
  "Users": "/users",
  "Sign Up": "/sign-up",
  "Messages": "/messages",
  "External Link": "http://extenal.link"


    "Account Selection Container": {
        "default": ".AccountSelection"
        "Title": ".Title"
        "Message": ".Message"
        "Accounts Select": ".AccountsSelect",
        "Next Button": "input:contains('Next')"

Flexible Grammar

Some things sound awkward with a rigid structure

When I click the "Button"
When I click on the "Submit"
When I click "Submit"
When I click a "Button" 
When I click on "Click Me"
When I click on the "Button" in the "Footer"
     containing "Submit"
When I click the "Button" inside the "Modal"
When I click into the "Modal"
When I click inside of the "Modal"
... and much much more

Fixture/StubS Managment

Built for front-end integration testing (no API)

Everything is stubbed by default
(returns empty object with 200 Response)


    '/users': '/users/getUsers',
    'GET /users/*': '/users/getUser',
    'PUT /users/*': '/users/putUsers',
    'POST /users/*': '/users/postUsers'

// Returns a success response with optional json
apiSuccess('/someUrl', 'GET', { hi: 'there' });

// Returns a 404 (default for GET)

Enumerating Elements

When I click the "seventh Button" in the "Modal"
And  I click the "last Button" in the "Modal"
And  I type "hello" in the "ten-thousandth Input"

Then I should see "hello" in the "ten-thousandth Output"

Uses the wordsToNumbers library to easily refer to ordinal elements

Sharing State

When('I login', () => {
   const username = 'toli';

   setState('username', username);


Then('The username should match in the header', () => {
   cy.get('.header .username').should('contain', STATE['username']);

Easily share state in between Scenarios and Steps across files when using Cucumber/Pickle. WIP.

Example App

This website is the example application. Everything is tested using Cypress & Pickle

You can view the source for the website in the
Pickle JS Repo under /website

All the Cypress tests under website/cypress

DOCUMEntation site


Start Simple

The Kitchen Sink


Save developer time - PMs write tests

Automatical documentation of features in English

Real TDD/BDD - PMs write all test cases first


Step 1: Product Manager defines Scenarios for a Feature in Pickle format

Step 2: Developer copies Scenarios to Integration tests in Pickle

Step 3: Developer develops the feature and all the scenarios in Storybook

Step 4: Developer writes unit tests in Jest

Step 5: Developer integrates the feature into the app

Step 6: PR must be approved by 2 team members and Integration/Unit tests must pass

Step 7: QA writes their own set of End to End Tests

Step 8: Deploy

The pickle Future vision

  1. Integration Testing Support: Ability to have Feature Tests (with Fixtures) and Integration Tests (with API) with a switch
  2. Framework Agnostic: Ability to carry over all your tests to other frameworks such as TestCafe or Selenium (maybe...)
  3. Mobile Support: Integration with Appium and BrowserStack
  4. WebGL Support: Ability to test Canvas based interactions via Screenshots. For example:
    When I drag the "File" into the "Trash Can"
    Then I should not see the "File"
  5. Selector File Builder Google Chrome plugin: Just click on the elements you want and it will build a selectors.json file. Eventually support building statements (recording actions)
  6. Pickle Playground & Editor Plugins: autocomplete and validation for phrases and selectors

We're Hiring!

Want to work on developing cool tools like Pickle.js?


Join our Team!



Thank you to

The base framework that makes this possible

My employer who sponsored Pickle's development

The cucumber interpreter for Cypress

Made with Slides.com