Skip to content
Merged
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# QA Automation Project (v2.6.2)
# QA Automation Project (v2.6.3)

[![Coverage](https://img.shields.io/badge/Coverage-100%25-brightgreen)](https://github.com/destrutoyt/yourrepo)
![Build Status](https://img.shields.io/github/actions/workflow/status/destrutoyt/qa-automation-automationexercise/playwright.yml)
![GitHub License](https://img.shields.io/github/license/destrutoyt/qa-automation-automationexercise)
![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/t/destrutoyt/qa-automation-automationexercise/main)
![version](https://img.shields.io/badge/version-2.6.2-blue)
![version](https://img.shields.io/badge/version-2.6.3-blue)

## 🚀 Project Overview

Expand Down Expand Up @@ -40,7 +40,7 @@ Latest Build Status:
![Latest Build](./images/docker-success-build.png)

## ⚠️ Issues
As of version 2.6.0 (08/21/2025):
As of version 2.6.3 (10/20/2025):
- ✅ Tests are stable and running successfully
- ✅ Docker builds complete without errors
- ⚠️ If you encounter any issues, please submit a pull request with suggested fixes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "qa-automation-automationexercise",
"version": "2.6.2",
"version": "2.6.3",
"description": "QA automation project showcasing UI, API, and visual tests for AutomationExercise. Integrated with Docker, Allure, and CI/CD pipelines.",
"main": "index.js",
"directories": {
Expand Down
2 changes: 1 addition & 1 deletion page-objects/Login.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Page } from '@playwright/test'
import loginData from '../utils/fixtures/loginData.json'
import loginData from '../utils/fixtures/userData.json'

export class UserLogin {
private page: Page
Expand Down
27 changes: 27 additions & 0 deletions tests/api-handling.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,30 @@ test('@API - (POST) Search Product with valid product', async ({ request }) => {
const body = await response.json()
expect(body.products.length).toBeGreaterThan(0)
})

// NOTE: API does not update first_name or last_name even if provided.
// These fields remain from registration data.
test('@API - (PUT) Update User Info with Parameters', async ({ request }) => {
const response = await request.put('https://automationexercise.com/api/updateAccount', {
form: {
name: 'Julian Andres',
email: 'johnDoe24@gmail.com',
password: 'johnDoe#24',
title: 'Mr',
birth_date: `24`,
birth_month: `June`,
birth_year: `1990`,
company: 'Tech Corp',
address1: '123 Main St',
address2: 'Apt 4B',
country: 'United States',
state: 'California',
city: 'Los Angeles',
zipcode: '90001',
mobile_number: '1234567890',
},
})
expect(response.status()).toBe(200)
const body = await response.json()
expect(body.message).toBe('User updated!')
})
14 changes: 7 additions & 7 deletions tests/auth-flow.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { test, expect } from '@playwright/test'
import { RegistrationTypes, LoginTypes } from '../utils/types'
import { RegistrationTypes, UserDataTypes } from '../utils/types'
import registrationData from '../utils/fixtures/registrationData.json'
import loginData from '../utils/fixtures/loginData.json'
import data from '../utils/fixtures/userData.json'

// Registration & Login data (JSON > JS object)
const login: LoginTypes = structuredClone(loginData)
const userData: UserDataTypes = structuredClone(data)
const registerData: RegistrationTypes = structuredClone(registrationData)

test('@AUTH - Register a new user', async ({ page }) => {
Expand Down Expand Up @@ -79,18 +79,18 @@ test('@AUTH - Login with existing user', async ({ page }) => {
await page.goto('/login')

// Fill in the login form
await page.fill('[data-qa="login-email"]', login.email)
await page.fill('[data-qa="login-password"]', login.password)
await page.fill('[data-qa="login-email"]', data.email)
await page.fill('[data-qa="login-password"]', data.password)
await page.click('[data-qa="login-button"]')

// Refreshes webpage and checks if user is logged in
await page.reload()
await expect(
page.getByText('Logged in as ' + registerData.name),
page.getByText('Logged in as ' + data.name),
).toBeVisible()

// Logout and checks if user is logged in
await page.click('[href="/logout"]')
await page.goto('/')
await expect(page.getByText('Logged in as ' + registerData.name)).toBeHidden()
await expect(page.getByText('Logged in as ' + data.name)).toBeHidden()
})
27 changes: 14 additions & 13 deletions tests/cart-checkout.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { test, expect } from '@playwright/test'
import { UserLogin } from '../page-objects/Login'
import { RegistrationTypes, ProductTypes } from '../utils/types/'
import products from '../utils/fixtures/productData.json'
import registrationData from '../utils/fixtures/registrationData.json'
import { UserDataTypes, ProductTypes } from '../utils/types/'
import { AddressValidation } from '../page-objects/AddressValidation'

import products from '../utils/fixtures/productData.json'
import data from '../utils/fixtures/userData.json'

export const productData: ProductTypes[] = products.products
export const userData: RegistrationTypes = structuredClone(registrationData)
export const userData: UserDataTypes = structuredClone(data)

test.beforeEach(async ({ page }) => {
const userLogin = new UserLogin(page)
await userLogin.autoLogin() // Uses predefined credentials from loginData.json. Manual login with provided credentials is available.
await userLogin.autoLogin() // Uses predefined credentials from userData.json. Manual login with provided credentials is available.
await page.goto('/products')
})

Expand Down Expand Up @@ -39,14 +40,14 @@ test('@CART - Checkout process', async ({ page }) => {
const addressValidator = new AddressValidation(page)
await addressValidator.load()

expect(addressValidator.fullname).toBe(userData.name)
expect(addressValidator.address1).toBe(userData.address.address)
expect(addressValidator.address2).toBe(userData.address.address2)
expect(addressValidator.city).toBe(userData.address.city)
expect(addressValidator.state).toBe(userData.address.state)
expect(addressValidator.zipcode).toBe(userData.address.zipcode)
expect(addressValidator.country).toBe(userData.address.country)
expect(addressValidator.mobileNumber).toBe(userData.address.mobile_number)
expect(addressValidator.fullname).toBe(userData.first_name + ' ' + userData.last_name) // Added first_name and last_name instead of name due to API limitation (see api-handling.spec.ts for more info)
expect(addressValidator.address1).toBe(userData.address1)
expect(addressValidator.address2).toBe(userData.address2)
expect(addressValidator.city).toBe(userData.city)
expect(addressValidator.state).toBe(userData.state)
expect(addressValidator.zipcode).toBe(userData.zipcode)
expect(addressValidator.country).toBe(userData.country)
expect(addressValidator.mobileNumber).toBe(userData.mobile_number)

// Validate order
const cartTable = page.locator('#cart_info tbody')
Expand Down
8 changes: 4 additions & 4 deletions tests/contact-test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { test, expect } from '@playwright/test'
import { UserLogin } from '../page-objects/Login'
import { LoginTypes } from '../utils/types'
import loginData from '../utils/fixtures/loginData.json'
import { UserDataTypes } from '../utils/types'
import loginData from '../utils/fixtures/userData.json'

const login: LoginTypes = structuredClone(loginData)
const login: UserDataTypes = structuredClone(loginData)

test.beforeEach(async ({ page }) => {
const userLogin = new UserLogin(page)
await userLogin.autoLogin() // Uses predefined credentials from loginData.json. Manual login with provided credentials is available.
await userLogin.autoLogin() // Uses predefined credentials from userData.json. Manual login with provided credentials is available.
await page.goto('/contact_us')
})

Expand Down
9 changes: 2 additions & 7 deletions tests/product-interactions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ const productData: ProductTypes[] = products.products

test.beforeEach(async ({ page }) => {
const userLogin = new UserLogin(page)
await userLogin.autoLogin() // Uses predefined credentials from loginData.json. Manual login with provided credentials is available.
await userLogin.autoLogin() // Uses predefined credentials from userData.json. Manual login with provided credentials is available.
await page.goto('/products')
await expect(page.getByText('Logged in as Julian Andres')).toBeVisible()
})

test('@PRODUCT - Search product by name', async ({ page }) => {
// Validates that user is logged in
await expect(page.getByText('Logged in as John Doe')).toBeVisible()

// Search for a product
await page.locator('[placeholder="Search Product"]').fill('Men Tshirt')
await page.click('#submit_search')
Expand All @@ -24,9 +22,6 @@ test('@PRODUCT - Search product by name', async ({ page }) => {
await expect(page.locator('.productinfo p')).toHaveText('Men Tshirt')
})
test('@PRODUCT - Search multiple products by name', async ({ page }) => {
// Validates that user is logged in
await expect(page.getByText('Logged in as John Doe')).toBeVisible()

// Search for multiple products
for (const product of productData) {
await page.locator('[placeholder="Search Product"]').fill(product.name)
Expand Down
4 changes: 0 additions & 4 deletions utils/fixtures/loginData.json

This file was deleted.

19 changes: 19 additions & 0 deletions utils/fixtures/userData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "Julian Andres",
"email": "johnDoe24@gmail.com",
"password": "johnDoe#24",
"title": "Mr",
"birth_date": "24",
"birth_month": "June",
"birth_year": "1990",
"first_name": "John",
"last_name": "Doe",
"company": "Tech Corp",
"address1": "123 Main St",
"address2": "Apt 4B",
"country": "United States",
"state": "California",
"city": "Los Angeles",
"zipcode": "90001",
"mobile_number": "1234567890"
}
2 changes: 1 addition & 1 deletion utils/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './registrationTypes';
export * from './loginTypes';
export * from './userDataTypes';
export * from './productTypes';
4 changes: 0 additions & 4 deletions utils/types/loginTypes.d.ts

This file was deleted.

19 changes: 19 additions & 0 deletions utils/types/userDataTypes.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export interface UserDataTypes {
name: string;
email: string;
password: string;
title: string;
birth_date: string;
birth_month: string;
birth_year: string;
first_name: string;
last_name: string;
company?: string;
address1: string;
address2: string;
country: string;
state: string;
city: string;
zipcode: string;
mobile_number: string;
}
Loading