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
GAME CHANGERS
Time travel
Debug in Chrome DevTools
Live reload
Auto wait/sleep
Class-A stubbing
Recording test runs
Stable, complete and built from scratch
TIME TRAVEL
DEBUG IN DEVTOOLS
LIVE RELOAD
AUTO WAIT/SLEEP
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"
CLASS-A STUBBING
// 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');
STABLE, COMPLETE & BUILT FROM SCRATCH
One Framework to Rule Them All
Stubbing - Assertions - Screenshot Diff - Recording -
Reporting - Test Runner - Browser Control
RECORDING TESTS
CUCUMBER
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
Enter PICKLE JS!
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?
CHALLENGES
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"
}
SELECTORS FOR
STYLED COMPONENTS
{
"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)
router({
'/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)
apiNotFound('/someUrl');
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);
cy.get('.loginInput').type(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
Text
Start Simple
The Kitchen Sink
THE IMPACT
Save developer time - PMs write tests
Automatical documentation of features in English
Real TDD/BDD - PMs write all test cases first
THE PROPOSED DEV FLOW
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
- Integration Testing Support: Ability to have Feature Tests (with Fixtures) and Integration Tests (with API) with a switch
- Framework Agnostic: Ability to carry over all your tests to other frameworks such as TestCafe or Selenium (maybe...)
- Mobile Support: Integration with Appium and BrowserStack
- 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" - 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)
- Pickle Playground & Editor Plugins: autocomplete and validation for phrases and selectors
We're Hiring!
Thank you to
The base framework that makes this possible
My employer who sponsored Pickle's development
The cucumber interpreter for Cypress