Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
50 changes: 50 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
pipeline {
agent any

environment {
PATH = "/usr/local/bin:/opt/homebrew/bin:$PATH"
NODE_HOME = "/Users/macbook/.nvm/versions/node/v20.19.5"
}

stages {
stage('Install Dependencies') {
steps {
dir('QA/bonus-task') {
sh '${NODE_HOME}/bin/npm ci || ${NODE_HOME}/bin/npm install'
}
}
}

stage('Run Cypress Tests') {
steps {
dir('QA/bonus-task') {
sh '${NODE_HOME}/bin/npm test || true'
}
}
}

stage('Generate Allure Report') {
steps {
dir('QA/bonus-task') {
sh 'allure generate allure-results --clean -o allure-report || true'
}
}
}
}

post {
always {
dir('QA/bonus-task') {
archiveArtifacts artifacts: 'cypress/videos/**/*', allowEmptyArchive: true
archiveArtifacts artifacts: 'allure-report/**/*', allowEmptyArchive: true
}
allure includeProperties: false, jdk: '', results: [[path: 'QA/bonus-task/allure-results']]
}
success {
echo 'All tests passed!'
}
failure {
echo 'Tests failed. Check Allure report for details.'
}
}
}
38 changes: 38 additions & 0 deletions QA/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# QA Automation Submission - Hakan Tetik

This directory contains my technical test submissions for the Senior QA Automation Engineer role. Both tasks have been implemented with a focus on **Clean Code**, **Scalability**, and **Enterprise Grade** testing patterns.

## 🚀 Submissions

### 1. [Bank Transfer Task](./bank-transfer-task)
End-to-end automation for an internal banking application.
- **Goal**: Validate business rules, amount/date boundaries, and role-based security.
- **Highlights**: Data-Driven Testing (Fixtures), Boundary Value Analysis, RBAC testing.

### 2. [Bonus Task (Web Automation)](./bonus-task)
Automated testing of the production website `fulll.fr`.
- **Goal**: Validate complex user flows, HubSpot iframe forms, and cross-page navigation.
- **Highlights**: Iframe handling, Cookie banner automation, Mega-menu navigation.

---

## 🛠️ Unified Architecture

Both projects follow a unified, scalable architecture:

- **Core Engine**: A robust `BasePage` motor handling all technical element interactions (Visibility checks, Dynamic waits, Actions).
- **Design Pattern**: Strictly follows the **Page Object Model (POM)** pattern.
- **Centralized Selectors**: All UI elements are separated into dedicated `Locators` files.
- **Type Safety**: Fully implemented in **TypeScript**.
- **Reporting**: Integrated **Allure Report** with automatic video and screenshot capture on failures.
- **CI/CD READY**: Includes `Jenkinsfile` for automated pipeline execution.

## 📊 How to run?

Navigate to each project directory and follow the instructions in their respective README files:
- [Bank Transfer Instructions](./bank-transfer-task/README.md)
- [Bonus Task Instructions](./bonus-task/README.md)

---
**Author**: Hakan Tetik
**Role**: Senior QA Automation Engineer
5 changes: 5 additions & 0 deletions QA/bank-transfer-task/.cypress-cucumber-preprocessorrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"stepDefinitions": [
"cypress/support/step_definitions/**/*.{js,ts}"
]
}
7 changes: 7 additions & 0 deletions QA/bank-transfer-task/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules/
allure-results/
allure-report/
cypress/videos/
cypress/screenshots/
.DS_Store
*.log
72 changes: 72 additions & 0 deletions QA/bank-transfer-task/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Bank Transfer QA Automation

## Overview
This project provides a robust, end-to-end automation suite for the **Bank Transfer** feature of the Internal Bank application. The framework is designed using industry-standard patterns to ensure maintainability, scalability, and high test coverage.

## Tech Stack
- **Cypress** - Core E2E testing framework
- **Cucumber/Gherkin** - BDD (Behavior Driven Development) methodology
- **TypeScript** - Type safety and modern development features
- **Page Object Model (POM)** - Structural design for UI components
- **Allure Reports** - Advanced test reporting with visual artifacts
- **Data-Driven Testing** - Utilizing Cypress Fixtures for scalable test data

## Project Structure
```text
QA/bank-transfer-task/
├── cypress/
│ ├── e2e/
│ │ └── bank_transfer.feature # Human-readable test scenarios
│ ├── fixtures/
│ │ └── transferData.json # Centralized test data (BVA, Error cases)
│ └── support/
│ ├── locators/
│ │ └── BankTransferLocators.ts # UI element selectors
│ ├── pages/
│ │ ├── BasePage.ts # Generic automation engine
│ │ └── BankTransferPage.ts # Business logic for transfer page
│ ├── step_definitions/
│ │ └── bank_transfer.steps.ts # Translation layer between Gherkin and Code
│ └── commands.ts # Global reusable commands (e.g., Login)
├── package.json
└── README.md
```

## Getting Started

### Prerequisites
- Node.js 18 or higher
- npm
- Allure CLI (optional, for viewing reports locally: `brew install allure`)

### Installation
```bash
npm install
```

### Running Tests
| Execution Mode | Command |
|----------------|---------|
| Headless (CLI) | `npm test` |
| Interactive UI | `npm run cypress:open` |
| Advanced Report| `npm run test:allure` |

## Test Coverage & QA Strategy

The suite employs several QA methodologies to ensure 100% reliability:

- **Happy Path Testing**: Validating standard instant and scheduled bank transfers.
- **Boundary Value Analysis (BVA)**: Exhaustive testing of Amount (0.01 - 100k) and IBAN length (14-34) limits.
- **Negative Testing**: Validation of invalid characters in labels and past date rejections.
- **Security (RBAC)**: Ensuring Role-Based Access Control correctly denies access to unauthorized users (e.g., Standard User).
- **Data-Driven Testing**: All boundary values and error-handling data are stored in `fixtures/transferData.json` for easy management.

## Key Technical Features

- **Standardized POM**: Every page inherits from a robust `BasePage`, ensuring code reusability (DRY principle).
- **Calculated Dynamic Dates**: The system automatically calculates dates (tomorrow, +90 days) during runtime, preventing test failures caused by hardcoded dates.
- **Stable Selectors**: Exclusively uses `data-testid` attributes to ensure tests remain resilient to UI design changes.
- **Automatic Sync**: Uses intelligent visibility checks (`waitForVisible`) instead of fragile static waits.

## Author
**Hakan Tetik** - Senior QA Automation Engineer
31 changes: 31 additions & 0 deletions QA/bank-transfer-task/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineConfig } from "cypress";
import { addCucumberPreprocessorPlugin } from "@badeball/cypress-cucumber-preprocessor";
import createBundler from "@bahmutov/cypress-esbuild-preprocessor";
import createEsbuildPlugin from "@badeball/cypress-cucumber-preprocessor/esbuild";
import { allureCypress } from "allure-cypress/reporter";

export default defineConfig({
e2e: {
specPattern: "**/*.feature",
async setupNodeEvents(
on: Cypress.PluginEvents,
config: Cypress.ConfigOptions
): Promise<Cypress.ConfigOptions> {
await addCucumberPreprocessorPlugin(on, config);

allureCypress(on, config, {
resultsDir: "allure-results",
});

on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin(config)],
})
);

return config;
},
baseUrl: "https://internal-bank.fulll.fr",
},
});
69 changes: 69 additions & 0 deletions QA/bank-transfer-task/cypress/e2e/bank_transfer.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@transfer @bank
Feature: Bank Transfer Creation
As an authorized user (Administrator or Purchase Manager)
I want to create bank transfers via a dedicated form
In order to pay my beneficiaries following business rules and security requirements

Background:
Given the user is logged in as an "Administrator"
And the user navigates to the "Bank Transfer" creation page

@happy-path @fixture
Scenario: Create a successful transfer using predefined test data
When they fill the transfer form using "validTransfer" data
And they select the "Instant" transfer mode
And they submit the transfer form
Then a success notification "Transfer successfully created" should be displayed

@boundary @amount
Scenario Outline: Validate transfer amount boundaries
When they enter an amount from fixture "<DataKey>"
And they submit the transfer form
Then they should see a validation message for "<DataKey>" as "<Status>"

Examples:
| DataKey | Status | Comment |
| minValid | Success | Min Valid |
| maxValid | Success | Max Valid |
| belowMin | Error | Below Min |
| aboveMax | Error | Above Max |

@boundary @iban
Scenario Outline: Validate IBAN length constraints
When they enter an IBAN length from fixture "<DataKey>"
And they submit the transfer form
Then they should see a validation status for "IBAN" as "<Status>"

Examples:
| DataKey | Status | Comment |
| minValid | Success | Min length |
| maxValid | Success | Max length |
| tooShort | Error | Too short |
| tooLong | Error | Too long |

@boundary @date
Scenario Outline: Validate date constraints for scheduled transfers
And they select the "Scheduled" transfer mode
When they set the transfer date to "<DatePhrase>"
And they submit the transfer form
Then the system should "<Outcome>" the date

Examples:
| DatePhrase | Outcome | Comment |
| tomorrow | Accept | Min Wait (1 day) |
| +90 days | Accept | Max Wait (90 days)|
| yesterday | Reject | Past date |
| +91 days | Reject | Beyond limit |

@error-handling @label
Scenario: Reject label with special characters
When they enter the invalid label from fixture
And they submit the transfer form
Then they should see an error for the "Label" field

@rbac @security
Scenario: Deny transfer creation for unauthorized roles
Given the user is logged in as a "Standard User"
When they attempt to access the bank transfer creation page
Then they should be redirected to the "Dashboard"
And the transfer form should not be accessible
23 changes: 23 additions & 0 deletions QA/bank-transfer-task/cypress/fixtures/transferData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"validTransfer": {
"beneficiary": "François Robert",
"iban": "FR7612345678901234567890123",
"label": "Facture Janvier",
"amount": "1250.50"
},
"amountLimits": {
"minValid": "0.01",
"maxValid": "100000",
"belowMin": "0.00",
"aboveMax": "100000.01"
},
"ibanLengths": {
"minValid": 14,
"maxValid": 34,
"tooShort": 13,
"tooLong": 35
},
"labels": {
"invalid": "Rent #2024!"
}
}
13 changes: 13 additions & 0 deletions QA/bank-transfer-task/cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
declare global {
namespace Cypress {
interface Chainable {
loginAs(role: string): Chainable<void>;
}
}
}

Cypress.Commands.add('loginAs', (role: string) => {
cy.log(`Logging in as ${role}`);
});

export { };
2 changes: 2 additions & 0 deletions QA/bank-transfer-task/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import "./commands";
import "allure-cypress";
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const Locators = {
formField: (name: string) => `[data-testid="${name}"]`,
submitButton: '[data-testid="submit"]',
notification: '[data-testid="notification"]',
errorMessage: (field: string) => `[data-testid="error-${field}"]`
};
40 changes: 40 additions & 0 deletions QA/bank-transfer-task/cypress/support/pages/BankTransferPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { BasePage } from "./BasePage";
import { Locators } from "../locators/BankTransferLocators";

class BankTransferPage extends BasePage {

visit() {
this.open('/transfers/create');
}

fillTransferDetails(fieldName: string, value: string) {
this.setFieldValue(Locators.formField(fieldName), value);
}

selectTransferMode(mode: string) {
this.selectCheckboxOrRadio(Locators.formField(`mode-${mode.toLowerCase()}`));
}

setDate(phrase: string) {
const formattedDate = this.calculateDate(phrase);
this.setFieldValue(Locators.formField('transfer-date'), formattedDate);
}

submitTransfer() {
this.clickElement(Locators.submitButton);
}

validateSuccessMessage(expectedText: string) {
this.verifyElementContainsText(Locators.notification, expectedText);
}

validateFieldVisibility(field: string, isVisible: boolean) {
this.checkElementPresence(Locators.errorMessage(field), isVisible);
}

validateFormAccessibility(shouldBeVisible: boolean) {
this.checkElementPresence(Locators.submitButton, shouldBeVisible);
}
}

export const bankTransferPage = new BankTransferPage();
Loading