This means starting with composing the Cucumber features file.
Feature: Login User
User visits the Login Page, fills in the form, and submits
Background: Navigate to the Login Page
When user navigates to /login
Scenario Outline: Invalid Input
Tests that the 'Login' button is disabled when either input elements contain invalid values
When user types in "<email>" in the "#email" element
And user types in "<password>" in the "#password" element
Then the "#login-button" element should have a "disabled" attribute
Examples:
| testCase | email | password |
| Both Invalid | invalid-email | shortpw |
| Invalid Email | invalid-email | abcd1234qwerty |
| Short Password | valid@ema.il | shortpw |
Scenario: Valid Input
Tests that the 'Login' button is enabled when valid values are provided, and that upon successful login, the UI display will display the message "You've been logged in successfully"
When a random user is registered
And user types in his/her email in the "#email" element
And user types in his/her password in the "#password" element
Then the "#login-button" element should not have a "disabled" attribute
When user clicks on the "#login-button" element
Then the "#login-success" element should appear within 2000 milliseconds
This introduces several new steps. The When a random user is registered step directly calls the API to register a user. We will use this user to test our login step. It is implemented inside a new module called spec/cucumber/steps/auth/index.js:
import chai, { expect } from 'chai';
import chaiAsPromised from 'chai-as-promised';
import { Given, When, Then } from 'cucumber';
import { By, until } from 'selenium-webdriver';
import bcrypt from 'bcryptjs';
import fetch, { Request } from 'node-fetch';
import { generateSampleData } from '../utils';
chai.use(chaiAsPromised);
Then(/^a random user is registered$/, function () {
this.email = generateSampleData('email');
this.password = generateSampleData('password');
this.digest = bcrypt.hashSync(this.password, 10);
const payload = {
email: this.email,
digest: this.digest
};
const request = new Request(`http://${process.env.API_SERVER_HOST_TEST}:${process.env.API_SERVER_PORT_TEST}/users/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: 'cors',
body: JSON.stringify(payload)
})
return fetch(request)
.then(response => {
if (response.status === 201) {
this.userId = response.text();
} else {
throw new Error('Error creating new user');
}
})
});
We are using the generateSampleData utility function we defined earlier to generate details for a new user. We are also storing these details within the context. Next, we use the Fetch API to send a Create User request to the API. However, the Fetch API is an API native to the browser. Therefore, in order to use the Fetch API in Node, we must install a polyfill, node-fetch:
$ yarn add node-fetch --dev
Then, for the steps And user types in his/her email in the "#email" element and And user types in his/her password in the "#password" element, we are using the details stored in the context to fill out the Login form and submit it. If the request is successful, an element with an ID of login-success is expected to appear.