From Cypress Basics to CI/CD with GitHub Actions


From Cypress Basics to CI/CD with GitHub Actions
Getting started in QA Automation can feel overwhelming. You write your first local tests⦠but then what? In this guide, we'll walk through how a beginner-friendly Cypress project evolves into a fully functional Continuous Integration (CI) pipeline using GitHub Actions.
This is more than a simple login test. Itβs a full educational example based on this repository:
π jsaldaza/cypress-login-dashboard-ci-demo
π Why Cypress?
Cypress is a modern JavaScript-based end-to-end (E2E) testing tool that makes writing and running tests a breeze for web applications. Why is it great for QA?
β Runs in the browser for real-time feedback
β Automatically waits for elements (no
sleep()
nonsense)β Has a slick UI for test execution and debugging
β Offers full support for CI/CD and parallel test execution
β Integrates smoothly with BDD and Page Object Models
Itβs especially great for frontend-heavy apps and teams that want quick test feedback and robust debugging tools.
π§± Project Structure Breakdown
The goal of this project is to teach and demonstrate what a Cypress-based automation project looks like β from scratch to CI/CD.
cypress-login-dashboard-ci-demo/
βββ cypress/
β βββ e2e/
β β βββ login/
β β β βββ login.feature
β β β βββ login.js
β β βββ dashboard/
β β β βββ dashboard.feature
β β β βββ dashboard.js
β βββ support/
β β βββ pageObjects/
β β β βββ loginPage.js
β β β βββ dashboardPage.js
β β βββ commands.js
β β βββ e2e.js
βββ .github/
β βββ workflows/
β βββ cypress.yml
βββ .env.example
βββ cypress.config.js
βββ package.json
Highlights:
Feature files written in Gherkin (
login.feature
,dashboard.feature
)Test steps implemented in
.js
files using Cypress + CucumberPage Object Model (POM) separates locators and actions (
loginPage.js
,dashboardPage.js
).env.example
shows how to use environment variables for credentialsCI configured via GitHub Actions in
.github/workflows/cypress.yml
π Login Testing with Gherkin + Page Objects
Hereβs a simplified feature example for login:
Feature: Login functionality
Scenario: Successful login
Given I visit the login page
When I enter valid credentials
Then I should see the dashboard
Scenario Outline: Invalid logins
Given I visit the login page
When I enter "<username>" and "<password>"
Then I should see an error "<error>"
Examples:
| username | password | error |
| Admin | wrong123 | Invalid credentials |
| wrongUser | admin123 | Invalid credentials |
And the Cypress implementation using POM:
Given('I visit the login page', () => {
loginPage.visit();
});
When('I enter valid credentials', () => {
loginPage.fillCredentials(Cypress.env('username'), Cypress.env('password'));
loginPage.submit();
});
Then('I should see the dashboard', () => {
cy.url().should('include', '/dashboard');
});
Environment variables (CYPRESS_username
, CYPRESS_password
) are stored safely via .env
and GitHub Secrets in CI. π
π Dashboard Testing and UI Validations
Once logged in, we verify the dashboard loads correctly and UI elements are visible. Some assertions include:
Correct page title based on language (English/Spanish)
Widgets like βTime at Workβ or βMy Actionsβ visible
Language toggle functionality
We encapsulate all of this in the dashboardPage.js
Page Object.
verifyHeader(expectedText) {
cy.get('h1.page-title').should('have.text', expectedText);
}
This keeps our test logic clean and readable.
βοΈ CI/CD Setup with GitHub Actions
Inside .github/workflows/cypress.yml
, we define a CI pipeline:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Run Cypress tests
run: npx cypress run --env allure=true
env:
CYPRESS_username: ${{ secrets.CYPRESS_username }}
CYPRESS_password: ${{ secrets.CYPRESS_password }}
Highlights:
GitHub Secrets manage credentials safely π
Cypress runs in headless mode (
npx cypress run
)CI triggers on
push
andpull_request
Generates Allure reports (optional)
π§ Key Best Practices in This Project
Use POM (Page Object Model): Centralize selectors and actions
Keep tests data-driven: Easily extend login scenarios
Use Gherkin + Cucumber: Make specs readable and maintainable
Store secrets safely: No hardcoded credentials, ever!
Set up CI early: Donβt wait until the end of the project to automate
This base project is intentionally simple and beginner-friendly, but scalable. Itβs meant to teach, not overwhelm.
π§ͺ Why Start with Automation + CI Early?
Catch bugs before release
Give fast feedback to developers
Create confidence in your releases
Save time on repetitive manual tests
Build a culture of quality
By starting small and growing your test suite, you're investing in stability and agility for your team.
π― Ready to Try It Yourself?
You can clone the full project from GitHub:
π jsaldaza/cypress-login-dashboard-ci-demo
Use it to learn, practice, or extend your own automation framework.
Happy testing!
~ jsaldaza
Subscribe to my newsletter
Read articles from Andres Saldarriaga directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
