Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add e2e tests for admin login feature #564

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Project setup

on:
pull_request:
branches:
- main
push:
branches:
- main

jobs:
setup:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18

- name: Setup PostgreSQL
uses: ikalnytskyi/action-setup-postgres@v5
with:
port: 5432
database: evershop
username: postgres
password: pgAdmin12345

- name: Install dependencies
run: npm install

- name: Setup database schema
env:
NODE_ENV: production
DB_HOST: localhost
DB_PORT: 5432
DB_NAME: evershop
DB_USER: postgres
DB_TABLE: admin_user
ADMIN_EMAIL: [email protected]
ADMIN_PASSWORD: a1234578
SUPPRESS_NO_CONFIG_WARNING: "true"
PGPASSWORD: pgAdmin12345
run: |
./tests/setupDB.sh
npm run user:create -- --name admin --email $ADMIN_EMAIL --password $ADMIN_PASSWORD
npm run dev &

- name: Wait for development server
run: |
sudo apt-get install wait-for-it -y
wait-for-it -h localhost -p 3000 -t 10

- name: Run e2e tests
working-directory: tests
run: |
npm install
npx playwright install chromium
npm run test:e2e e2e
27 changes: 27 additions & 0 deletions tests/cucumber.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const { Before, BeforeAll, AfterAll, After, setDefaultTimeout } = require("@cucumber/cucumber");
const { chromium } = require("playwright");
require('dotenv').config();

const timeout = process.env.TIME_OUT ? parseInt(process.env.TIME_OUT) : 60000;
setDefaultTimeout(timeout);

BeforeAll(async function () {
global.browser = await chromium.launch({
headless: process.env.HEADLESS === "false" ? false : true,
slowMo: process.env.SLOW_MO ? parseInt(process.env.SLOW_MO) : 0,
})
});

Before(async function () {
global.context = await global.browser.newContext();
global.page = await global.context.newPage();
});

After(async function () {
await global.page.close();
await global.context.close();
});

AfterAll(async function() {
await global.browser.close();
});
5 changes: 5 additions & 0 deletions tests/e2e/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = {
baseUrl: process.env.BASE_URL || 'http://localhost:3000',
}

module.exports = config;
29 changes: 29 additions & 0 deletions tests/e2e/features/adminLogin.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Feature: login
As an admin
I want to log in to the website admin panel
So that I can manage my products

Background:
Given user 'admin' has navigated to the admin login page


Scenario: login with valid credentials
When user 'admin' logs in with following credentials
| email | password |
| [email protected] | a1234578 |
Then user 'admin' should be navigated to admin panel dashboard


Scenario Outline: login with invalid credentials
When the user tries to log in with following credentials
| email | password |
| <email> | <password> |
Then error message "<errorMessage>" should be shown
Examples:
| email | password | errorMessage |
| [email protected] | abc | Invalid email or password |
| [email protected] | pSynidexxx.899 | Invalid email or password |
| [email protected] | | This field can not be empty |
| | pSynidexxx.899 | This field can not be empty |
| | | This field can not be empty |
| admin | adminadmin123 | Invalid email |
21 changes: 21 additions & 0 deletions tests/e2e/pageObjects/LoginPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const config = require('../config.js');
class LoginPage {
constructor() {
this.adminPanelUrl = `${config.baseUrl}/admin`;
this.adminLoginUrl = `${config.baseUrl}/admin/login`;
this.emailSelector = "//input[@name='email']";
this.passwordSelector = "//input[@name='password']";
this.loginBtnSelector = "//button[@class='button primary']";
this.dashboardSeletor = "//div[@class='self-center']/h1";
}

async navigateToLoginPage() {
await page.goto(this.adminLoginUrl);
}
async login(inputData) {
await page.fill(this.emailSelector, inputData[0].email);
await page.fill(this.passwordSelector, inputData[0].password);
await page.click(this.loginBtnSelector);
}
}
module.exports = { LoginPage };
40 changes: 40 additions & 0 deletions tests/e2e/stepDefinitions/adminLoginContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const { Given, When, Then } = require('@cucumber/cucumber');
const { expect } = require('@playwright/test');
const { LoginPage } = require('../pageObjects/LoginPage');
const login = new LoginPage();

Given(
'user {string} has navigated to the admin login page',
async function (user) {
await login.navigateToLoginPage();
expect(page.url()).toBe(login.adminLoginUrl);
}
);

When(
'user {string} logs in with following credentials',
async function (user, credentials) {
const loginCredentials = credentials.hashes();
await login.login(loginCredentials);
}
);

Then(
'user {string} should be navigated to admin panel dashboard',
async function (user) {
await expect(page.locator(login.dashboardSeletor)).toBeVisible();
}
);

When(
'the user tries to log in with following credentials',
async function (credentials) {
const invalidCredentials = credentials.hashes();
await login.login(invalidCredentials);
}
);

Then('error message {string} should be shown', async function (errorMessage) {
const warnings = await page.getByText(errorMessage).count();
expect(warnings).toBeLessThanOrEqual(2);
});
Loading