Tutorial Cypress BDD POM Scenario CRUD

Fadhila Rizki Anindita
6 min readJun 14, 2024

Cypress is one of the most open source automation tools, for automating API & Web. Base language of cypress is javascript. Cypress have enough easy learning curve, many documentation, good competitor of selenium, but if we use many dependencies, must to install one by one.

BDD is Behaviour Driven Development, use syntax gherkin, easy to read for QA, Dev, Product & User. This collaborative approach brings together the business and technical aspects of projects. BDD simulates how an application should behave from the end user’s perspective.

Page object model (POM) is a design pattern where classes are represented as pages. POM reduces code duplication and makes code more reusable. A page object is an object-oriented class that serves as an interface to a page of your webThe tests then use the methods of this page object class whenever they need to interact with the UI of that page.

We will learn automate Web, specifically https://computer-database.gatling.io/computers. In this tutorial, i’m using windows. Before start, please make sure you have been install node js & npm. If there are no node js & npm, visit https://nodejs.org/en/download/package-manager.

  1. Open text editor (eg visual studio code, sublime, atom, etc)
  2. Click File, Click Open Folder
  3. Choose directory you wanna save your folder, click create new folder, rename folder, click open folder.
  4. Open terminal in text editor (ctrl + )
  5. Config npm & install cypress (type one per one line and than enter)
npm init -y
npm install cypress --save-dev
npx cypress open

6. You’ll see it, click E2E Testing (E2E means End to End)

7. You’ll see it, click Continue

8. Show another popup, choose browser (I choose Electron), & click Start E2E Testing in Electron

9. Show last popup, click scaffold example specs

10. Click Okay, I got it!

11. File .cy.js auto generate every install cypress, and than close

12. Back to Terminal Visual Studio Code, for continue install dependencies (type one per one line and than enter)

npm install @badeball/cypress-cucumber-preprocessor --save-dev
npm install @bahmutov/cypress-esbuild-preprocessor --save-dev
npm install cypress-mochawesome-reporter --save-dev

13. Update cypress.config.js

const { defineConfig } = require("cypress");
const createBundler = require("@bahmutov/cypress-esbuild-preprocessor");
const preprocessor = require("@badeball/cypress-cucumber-preprocessor");
const createEsbuildPlugin = require("@badeball/cypress-cucumber-preprocessor/esbuild");

module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
require('cypress-mochawesome-reporter/plugin')(on);
on("file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin.default(config)],
}));
preprocessor.addCucumberPreprocessorPlugin(on, config);
return config;
},
specPattern: "**/*.feature",
},
videosFolder: "cypress/reports/videos",
screenshotsFolder: "cypress/reports/screenshots",
reporter: 'cypress-mochawesome-reporter',
reporterOptions: {
charts: true,
reportPageTitle: 'report-cypress',
embeddedScreenshots: true,
inlineAssets: true,
saveAllAttempts: false,
},
})

14. Update package.json (don’t changes name, name means your folder name)

{
"name": "cypress-bdd1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@badeball/cypress-cucumber-preprocessor": "^20.0.6",
"@bahmutov/cypress-esbuild-preprocessor": "^2.2.1",
"@faker-js/faker": "^8.4.1",
"cypress": "^13.11.0",
"cypress-mochawesome-reporter": "^3.8.2"
},
"cypress-cucumber-preprocessor": {
"step_definitions": "cypress/support/step_definitions/",
"nonGlobalStepDefinitions": false
}
}

15. Create computer.feature in folder e2e

Feature: Computer features
Scenario: Verify success add computer
When I submit data new computer
Then I should success add computer

Scenario: Verify success search computer
When I search data computer "Atlas Computer"
Then I should success search computer

Scenario: Verify success update computer
When I update data computer "Atlas Computer"
Then I should success update computer

Scenario: Verify success delete computer
When I delete data computer "Atlas Computer"
Then I should success delete computer

16. Create folder pages in folder e2e, create folder computer page in folder pages, create elements.js &ComputerPage.js

17. Type code below in elements.js (define any element object)

module.exports = {
computerpage:{
add_button: "#add",
computer_name_field: "#name",
introduced_field: "#introduced",
discontinued_field: "#discontinued",
company_dropdown: "#company",
create_button: ".btn primary",
search_field: "#searchbox",
filter_button: "#searchsubmit",
computer_name_link: "a[href*='/computers/300']",
save_button: ".btn primary",
delete_button: "input.btn.danger"
}
}

18. Type code below in ComputerPage.js (define any method)

var elements = require('./elements')

class ComputerPage {

clickOnAddButton() {
return cy.get(elements.computerpage.add_button).click()
}

typeInComputerNameField(value) {
return cy.get(elements.computerpage.computer_name_field).type(value)
}

typeInIntroducedField(value) {
return cy.get(elements.computerpage.introduced_field).type(value)
}

typeInDiscontinuedField(value) {
return cy.get(elements.computerpage.discontinued_field).type(value)
}

selectCompany() {
return cy.get(elements.computerpage.company_dropdown).click()
}

clickOnCreateButton() {
return cy.get(elements.computerpage.create_button).click()
}

verifySuccessCreate() {
return
}

clickOnSearchField(value) {
return cy.get(elements.computerpage.search_field).type(value)
}

clickOnSearchButton() {
return cy.get(elements.computerpage.filter_button).click()
}

verifySuccessSearch() {
return cy.contains('Atlas Computer').should('be.visible');
}

clickOnComputerLink() {
return cy.get(elements.computerpage.computer_name_link).click()
}

updateInComputerNameField() {
return cy.get(elements.computerpage.computer_name_field).type()
}

clickOnSaveButton() {
return cy.contains('Save this computer').click()
}

verifySuccessUpdate() {
return cy.contains('has been updated').should('be.visible');
}

clickOnDeleteButton() {
return cy.get(elements.computerpage.delete_button).click({ force: true })
}

verifySuccessDelete() {
return cy.contains('has been deleted').should('be.visible');
}


}

export default ComputerPage

19. Type code below in command.js

Cypress.Commands.add('add_computer', (computer_name, introduced, discontinued) => {
cy.get('#add').click(),
cy.get('#name').type(computer_name),
cy.get('#introduced').type(introduced);
cy.get('#discontinued').type(discontinued);
cy.get('#company').select('Apple Inc.').should('have.value', '1')
cy.contains('Create this computer').click()
})

20. Add computer.json in folder fixtures, type code below

{
"computer_name_update": "Computer New Update",
"introduced": "2018-01-02",
"discontinued": "2025-01-02",
"introduced_update": "2018-01-02"
}

21. Create folder step_definitions in folder support, create step.js, type code below (define detail step from .feature) (beforeEach like background step, will execute first before every scenario.)

import { Given, When, Then, DataTable } from '@badeball/cypress-cucumber-preprocessor'
import ComputerPage from '../../e2e/pages/computerPage/ComputerPage'

const computerPage = new ComputerPage()

beforeEach(() => {
cy.visit('https://computer-database.gatling.io/computers/', { timeout: 10000 });
});

When('I submit data new computer', () => {
cy.add_computer("Computer New", "2018-01-01", "2025-01-01")
})

Then('I should success add computer', () => {
computerPage.verifySuccessCreate()
})

When('I search data computer {string}', (value) => {
computerPage.clickOnSearchField(value)
computerPage.clickOnSearchButton()
})

Then('I should success search computer', () => {
computerPage.verifySuccessSearch()
})

When('I update data computer {string}', (value) => {
computerPage.clickOnSearchField(value)
computerPage.clickOnSearchButton()
computerPage.clickOnComputerLink()
cy.fixture("computer").then(computer => {
const computer_name_update= computer.computer_name_update
cy.get('#name').type(computer_name_update);
computerPage.clickOnSaveButton()
})

})

Then('I should success update computer', () => {
computerPage.verifySuccessUpdate()
})

When('I delete data computer {string}', (value) => {
computerPage.clickOnSearchField(value)
computerPage.clickOnSearchButton()
computerPage.clickOnComputerLink()
computerPage.clickOnDeleteButton()
})

Then('I should success delete computer', () => {
computerPage.verifySuccessDelete()
})

22. This is my folder structure

23. Let’s try run automate, type in Terminal

npx cypress open

23. Run in Terminal without open browser

npx cypress run

24. Type in Terminal and get simple report, find your report in folder mochawsome-report. right click mochawsome.html, click copy path, paste path in browser, enter.

npx cypress run --reporter mochawesome

That’s all from this tutorial, wish help you to learn automation. Visit repo this project https://github.com/fadhilara/cypress-bdd-pom. If any error & feedback, please drop in comment. Next article, will learn about other language, faker and integration with CI/CD. Stay tuned!

Refferences :

https://github.com/mmonfared/CyBDD

https://github.com/rsrohit/CyBDDFramework

https://medium.com/tech-tajawal/page-object-model-pom-design-pattern-f9588630800b

https://kailash-pathak.medium.com/cypress-13-integration-with-bdd-cucumber-pom-a367f534b363

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Fadhila Rizki Anindita
Fadhila Rizki Anindita

No responses yet

Write a response