🚀 QA/SDET Transition Roadmap (3–6 Months)¶
A dual-language, step-by-step plan for transitioning into QA Engineer / Automation Tester / SDET roles. Designed for backgrounds in Coding, Technical Writing, and IT Support.
SDET TRANSITION ROADMAP - ULTRA DETAILED ENGLISH VERSION¶
🎯 FINAL GOALS (3-6 Months)¶
After 3-6 months, you will have:
-
GitHub Portfolio with at least 1 complete automation project
-
CV clearly presenting: Automation Skills + QA Mindset + Manual Testing
-
Confident interview skills with real case studies
=> Target Position: Junior/Mid Automation Tester, QA Engineer, SDET
🧠 PREPARATION PHASE: BUILDING QA MINDSET (Week 0)¶
"Automation First" Mindset
NOT: Writing tests to check
BUT: Designing a testing system that can run automatically
=> Examples of automation thinking:
- Every new feature → Corresponding automated test
- Every bug fixed → Automated regression test
- Every deployment → Automated smoke test runs first
NOT: Test everything
BUT: Test the most important things with highest risk
Risk = Probability (Chance of occurrence) × Impact (Consequences)
1. High Probability × High Impact (Example: Payment processing)
2. High Probability × Low Impact (Example: Input validation)
3. Low Probability × High Impact (Example: Security breach)
4. Low Probability × Low Impact (Example: UI cosmetic issues)
🥇 PHASE 1: FOUNDATIONS & TECHNOLOGY CHOICE (Weeks 1-4)¶
Week 1: Core Theory - Learn Deeply, Understand Essence¶
Day 1-2: SDLC & STLC¶
SOFTWARE DEVELOPMENT LIFE CYCLE (SDLC):
| Step | Describe |
|---|---|
| 1. Planning | → Planning, requirement analysis |
| 2. Design | → Architecture design, UI/UX |
| 3. Development | → Programming |
| 4. Testing | → Testing |
| 5. Deployment | → Deployment |
| 6. Maintenance | → Maintenance |
SOFTWARE TESTING LIFE CYCLE (STLC):
| Step | Describe |
|---|---|
| 1. Requirement Analysis | → Analyze requirements |
| 2. Test Planning | → Create test plan |
| 3. Test Case Development | → Write test cases |
| 4. Test Environment Setup | → Prepare test environment |
| 5. Test Execution | → Execute tests |
| 6. Test Closure | → Close testing, report |
Day 3-4: Agile/Scrum for Testers¶
Daily Standup reports for Testers:
1. What did you test yesterday? Results?
2. What will you test today?
3. Any blockers? (Blocking bugs, environment issues...)
Role in Sprint:
- Sprint Planning: Estimate testing effort
- Sprint Review: Demo test results
- Retrospective: Improve testing process
Day 5-7: Testing Levels - UNDERSTAND DEEPLY¶
1. UNIT TESTING - Written by Developers
Goal: Test individual functions, methods
Framework: JUnit (Java), pytest (Python), Jest (JS)
Goal: Test multiple modules working together
Example: API A calls API B, Database + Service
Goal: Test entire system
Includes: Functional + Non-functional (Performance, Security)
Goal: User acceptance of product
UAT (User Acceptance Test)
Week 2: Testing Types & Bug Reporting¶
Day 1-2: Functional vs Non-Functional¶
FUNCTIONAL TESTING - "Does the system do the right thing?"
- Smoke Testing: Check if build is stable
- Sanity Testing: Check if new feature has basic issues
- Regression Testing: Check if new code breaks existing features
- Integration Testing: Do components work together properly
NON-FUNCTIONAL TESTING - "Does the system work WELL?"
- Performance Testing: Load, Stress, Endurance
- Security Testing: Authentication, Authorization, Injection
- Usability Testing: UX/UI, Accessibility
- Compatibility Testing: Cross-browser, Cross-device
Day 3-4: PROFESSIONAL Bug Reporting¶
HIGH-QUALITY BUG REPORT TEMPLATE¶
Title
| Severity | Module/Feature | Brief description of issue |
|---|---|---|
| Major | Checkout | User cannot proceed to payment when using gift card |
Description
When user applies gift card in checkout process, system doesn't allow proceeding to payment page.
Steps to Reproduce
1. Login with account having gift card balance
2. Add product to cart
3. Navigate to checkout page
4. In Payment section, select "Use Gift Card"
5. Enter gift card code and click "Apply"
6. Click button "Continue to Payment"
Expected Result
=> User is redirected to payment page to complete remaining payment.
Actual Result
Button "Continue to Payment" is disabled, cannot be clicked.
Environment
- Browser: Chrome 98.0.4758.102
- OS: Windows 11
- Device: Desktop
- URL: https://staging.example.com
- User: testuser@email.com / password123
Severity & Priority
- Severity: Major (Feature not working, but workaround exists)
- Priority: High (Affects business revenue)
Attachments
1. Screenshot: checkout_page_bug.png
2. Console Log: [Paste error log here]
3. Network Tab: [Paste failed API call]
Notes
Workaround: Remove gift card to continue checkout.
Day 5-7: Technology Stack Choice - CRITICAL DECISION¶
DETAILED ANALYSIS OF 3 OPTIONS:
OPTION 1: TypeScript + Playwright (RECOMMENDED)
Advantages:
- Playwright: Modern, fast, multi-browser support
- TypeScript: Type-safe, easy to maintain, popular in startups
- Support: Web, API, Mobile, Visual Testing
- Community: Rapidly growing
Suitable for: Wanting to learn modern tech, targeting startups
OPTION 2: Python + Pytest + Playwright
Advantages:
- Python: Easy to learn, simple syntax
- Pytest: Powerful testing framework
- Playwright: Has Python binding
Suitable for: Beginners, want to focus more on logic than syntax
OPTION 3: Java + Selenium + TestNG
Advantages:
- Enterprise: Used by banks, large companies
- Stable: Has been around for years
- Selenium: Industry standard
Suitable for: Targeting enterprise companies, already know Java
DECISION: Choose Option 1 (TypeScript + Playwright)
Reason: Modern, many jobs, easy to learn for those with coding background
🥈 PHASE 2: BUILDING AUTOMATION FRAMEWORK (Weeks 5-10)¶
Week 5: Web Automation Basics with Playwright¶
Day 1: Installation & Hello World¶
1. Install Node.js (>=16)
2. Create project
mkdir automation-framework
cd automation-framework
npm init -y
3. Install Playwright
npm init playwright@latest
Choose: TypeScript, create tests folder, install browsers
4. Basic structure
automation-framework/
├── tests/
│ └── example.spec.ts
├── playwright.config.ts
└── package.json
Day 2-3: Locators - MOST IMPORTANT¶
// DO NOT: Use complex XPath
// await page.locator('//*[@id="app"]/div/div[2]/div/div[1]/form/div[1]/input')
// DO: Use stable locators
// 1. Role-based (BEST)
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByRole('textbox', { name: 'Username' }).fill('user');
// 2. Text-based
await page.getByText('Welcome back').click();
await page.getByLabel('Email Address').fill('test@email.com');
// 3. Test ID (Developer needs to add data-testid)
await page.getByTestId('login-button').click();
// 4. Placeholder
await page.getByPlaceholder('Enter your email').fill('test@email.com');
// 5. Simple CSS Selector
await page.locator('.submit-btn').click();
await page.locator('#username').fill('user');
Day 4-5: Write First Test Case - Login Test¶
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
// Test Suite
test.describe('Login Functionality', () => {
// Positive Test Case
test('Successful login with valid credentials', async ({ page }) => {
// 1. Navigate
await page.goto('https://www.saucedemo.com/');
// 2. Fill credentials
await page.locator('[data-test="username"]').fill('standard_user');
await page.locator('[data-test="password"]').fill('secret_sauce');
// 3. Click login
await page.locator('[data-test="login-button"]').click();
// 4. Assertion
await expect(page).toHaveURL('https://www.saucedemo.com/inventory.html');
await expect(page.locator('.title')).toContainText('Products');
});
// Negative Test Case
test('Failed login with invalid credentials', async ({ page }) => {
await page.goto('https://www.saucedemo.com/');
await page.locator('[data-test="username"]').fill('invalid_user');
await page.locator('[data-test="password"]').fill('wrong_password');
await page.locator('[data-test="login-button"]').click();
// Verify error message
const errorElement = page.locator('[data-test="error"]');
await expect(errorElement).toBeVisible();
await expect(errorElement).toContainText(
'Username and password do not match'
);
});
});
Day 6-7: Hooks & Configuration¶
// tests/login-hooks.spec.ts
import { test, expect } from '@playwright/test';
// Before Each Test
test.beforeEach(async ({ page }) => {
console.log('Running before each test');
await page.goto('https://www.saucedemo.com/');
});
// After Each Test
test.afterEach(async ({ page }) => {
console.log('Running after each test');
// Take screenshot on failure
if (test.info().status === 'failed') {
const screenshotPath = `screenshots/failure-${test.info().title}.png`;
await page.screenshot({ path: screenshotPath, fullPage: true });
}
});
// Before All Tests (Suite Level)
test.beforeAll(async () => {
console.log('Running once before all tests');
});
test.describe('Login with Hooks', () => {
test('should login successfully', async ({ page }) => {
// Test logic here
});
});
Week 6: Applying Test Case Design Techniques¶
Day 1-2: Equivalence Partitioning¶
// Example: Age Field (18-60)
// EP: Divide input into "equivalent" partitions
const testCases = [
// VALID PARTITION: 18-60 (only need to test 1 representative value)
{ age: 30, expected: 'valid' }, // Representative of valid partition
// INVALID PARTITIONS:
{ age: 17, expected: 'invalid' }, // < 18
{ age: 61, expected: 'invalid' }, // > 60
{ age: -5, expected: 'invalid' }, // Negative
{ age: 'abc', expected: 'invalid' }, // Non-numeric
{ age: '', expected: 'invalid' }, // Empty
];
// Implement in test
test.describe('Age Validation - Equivalence Partitioning', () => {
testCases.forEach(({ age, expected }) => {
test(`Age ${age} should be ${expected}`, async ({ page }) => {
// Test logic here
});
});
});
Day 3-4: Boundary Value Analysis¶
// Example: Age Field (18-60)
// BVA: Test boundary values
const boundaryTestCases = [
// VALID BOUNDARIES
{ age: 18, expected: 'valid' }, // Lower boundary
{ age: 60, expected: 'valid' }, // Upper boundary
// INVALID BOUNDARIES
{ age: 17, expected: 'invalid' }, // Just below lower boundary
{ age: 61, expected: 'invalid' }, // Just above upper boundary
// TYPICAL VALID VALUES
{ age: 30, expected: 'valid' }, // Typical valid
{ age: 50, expected: 'valid' }, // Typical valid
];
// Negative Testing Scenarios
const negativeScenarios = [
{ scenario: 'Empty username', username: '', password: 'validpass', expectedError: 'Username is required' },
{ scenario: 'Short password', username: 'validuser', password: '123', expectedError: 'Password must be at least 8 characters' },
{ scenario: 'Invalid email format', username: 'not-an-email', password: 'validpass', expectedError: 'Invalid email format' },
{ scenario: 'SQL Injection attempt', username: "admin' --", password: 'any', expectedError: 'Invalid credentials' },
{ scenario: 'XSS attempt', username: '<script>alert(1)</script>', password: 'any', expectedError: 'Invalid input detected' },
];
Day 5-7: Data-Driven Testing¶
// tests/data-driven/login.data.ts
export const loginTestData = [
{
testName: 'Valid standard user',
username: 'standard_user',
password: 'secret_sauce',
expected: 'success',
expectedURL: '/inventory.html'
},
{
testName: 'Locked out user',
username: 'locked_out_user',
password: 'secret_sauce',
expected: 'error',
expectedError: 'Sorry, this user has been locked out'
},
{
testName: 'Invalid username',
username: 'invalid_user',
password: 'secret_sauce',
expected: 'error',
expectedError: 'Username and password do not match'
},
// Add more test cases...
];
// tests/login-ddt.spec.ts
import { test, expect } from '@playwright/test';
import { loginTestData } from './data/login.data';
loginTestData.forEach((data) => {
test(`Login: ${data.testName}`, async ({ page }) => {
await page.goto('https://www.saucedemo.com/');
await page.locator('[data-test="username"]').fill(data.username);
await page.locator('[data-test="password"]').fill(data.password);
await page.locator('[data-test="login-button"]').click();
if (data.expected === 'success') {
await expect(page).toHaveURL(`https://www.saucedemo.com${data.expectedURL}`);
} else {
const errorElement = page.locator('[data-test="error"]');
await expect(errorElement).toBeVisible();
await expect(errorElement).toContainText(data.expectedError);
}
});
});
Week 7-8: Building Professional Framework with POM¶
Day 1-2: Page Object Model (POM) Structure¶
automation-framework/
├── src/
│ ├── pages/ # Page Objects
│ │ ├── LoginPage.ts
│ │ ├── ProductsPage.ts
│ │ └── CartPage.ts
│ ├── tests/ # Test Cases
│ │ ├── login.spec.ts
│ │ ├── products.spec.ts
│ │ └── cart.spec.ts
│ ├── data/ # Test Data
│ │ └── test-data.ts
│ ├── utils/ # Helper Functions
│ │ ├── api-client.ts
│ │ ├── test-utils.ts
│ │ └── reporting.ts
│ └── fixtures/ # Custom Fixtures
│ └── custom-fixtures.ts
├── playwright.config.ts
├── package.json
└── README.md
Day 3-4: Implement Page Objects¶
// src/pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
// Page Elements
private readonly usernameInput: Locator;
private readonly passwordInput: Locator;
private readonly loginButton: Locator;
private readonly errorMessage: Locator;
constructor(private readonly page: Page) {
this.usernameInput = page.locator('[data-test="username"]');
this.passwordInput = page.locator('[data-test="password"]');
this.loginButton = page.locator('[data-test="login-button"]');
this.errorMessage = page.locator('[data-test="error"]');
}
// Page Actions
async navigate(): Promise<void> {
await this.page.goto('https://www.saucedemo.com/');
}
async login(username: string, password: string): Promise<void> {
await this.usernameInput.fill(username);
await this.passwordInput.fill(password);
await this.loginButton.click();
}
async getErrorMessage(): Promise<string> {
return await this.errorMessage.textContent() || '';
}
async isErrorMessageVisible(): Promise<boolean> {
return await this.errorMessage.isVisible();
}
async clearForm(): Promise<void> {
await this.usernameInput.clear();
await this.passwordInput.clear();
}
}
// src/pages/ProductsPage.ts
export class ProductsPage {
private readonly pageTitle: Locator;
private readonly inventoryList: Locator;
constructor(private readonly page: Page) {
this.pageTitle = page.locator('.title');
this.inventoryList = page.locator('.inventory_list');
}
async getPageTitle(): Promise<string> {
return await this.pageTitle.textContent() || '';
}
async addProductToCart(productName: string): Promise<void> {
const productItem = this.page.locator(
`.inventory_item:has-text("${productName}")`
);
const addToCartButton = productItem.locator('button');
await addToCartButton.click();
}
async getCartItemCount(): Promise<number> {
const cartBadge = this.page.locator('.shopping_cart_badge');
if (await cartBadge.isVisible()) {
const countText = await cartBadge.textContent();
return parseInt(countText || '0');
}
return 0;
}
}
Day 5-6: Test Cases Using POM¶
// src/tests/login-pom.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
import { ProductsPage } from '../pages/ProductsPage';
test.describe('Login with POM', () => {
let loginPage: LoginPage;
let productsPage: ProductsPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
productsPage = new ProductsPage(page);
await loginPage.navigate();
});
test('Successful login redirects to products page', async ({ page }) => {
// Act
await loginPage.login('standard_user', 'secret_sauce');
// Assert
await expect(page).toHaveURL(/.*inventory.html/);
const title = await productsPage.getPageTitle();
expect(title).toBe('Products');
});
test('Login with invalid credentials shows error', async () => {
// Act
await loginPage.login('invalid_user', 'wrong_password');
// Assert
const isErrorVisible = await loginPage.isErrorMessageVisible();
expect(isErrorVisible).toBe(true);
const errorMessage = await loginPage.getErrorMessage();
expect(errorMessage).toContain('Username and password do not match');
});
test('Login with locked out user shows specific error', async () => {
// Act
await loginPage.login('locked_out_user', 'secret_sauce');
// Assert
const errorMessage = await loginPage.getErrorMessage();
expect(errorMessage).toContain('Sorry, this user has been locked out');
});
});
Day 7: API Testing with Playwright¶
// src/tests/api/auth-api.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Auth API Tests', () => {
const baseURL = 'https://restful-api.dev';
test('POST /login with valid credentials', async ({ request }) => {
// Arrange
const loginData = {
username: 'standard_user',
password: 'secret_sauce'
};
// Act
const response = await request.post(`${baseURL}/login`, {
data: loginData
});
// Assert
expect(response.status()).toBe(200);
const responseBody = await response.json();
expect(responseBody).toHaveProperty('token');
expect(typeof responseBody.token).toBe('string');
expect(responseBody.token.length).toBeGreaterThan(0);
});
test('POST /login with invalid credentials', async ({ request }) => {
const response = await request.post(`${baseURL}/login`, {
data: {
username: 'invalid',
password: 'wrong'
}
});
expect(response.status()).toBe(401);
const responseBody = await response.json();
expect(responseBody).toHaveProperty('error');
expect(responseBody.error).toBe('Invalid credentials');
});
test('GET /products returns list of products', async ({ request }) => {
const response = await request.get(`${baseURL}/products`);
expect(response.status()).toBe(200);
const products = await response.json();
expect(Array.isArray(products)).toBe(true);
expect(products.length).toBeGreaterThan(0);
// Verify product structure
const firstProduct = products[0];
expect(firstProduct).toHaveProperty('id');
expect(firstProduct).toHaveProperty('name');
expect(firstProduct).toHaveProperty('price');
});
});
Week 9-10: Reporting, CI/CD & Finalization¶
Day 1-2: Advanced Playwright Configuration¶
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
// Test directory
testDir: './src/tests',
// Timeout
timeout: 30 * 1000, // 30 seconds
expect: {
timeout: 5000
},
// Parallel execution
fullyParallel: true,
workers: process.env.CI ? 2 : undefined,
// Reporter configuration
reporter: [
['html', { outputFolder: 'playwright-report', open: 'never' }],
['junit', { outputFile: 'test-results/junit.xml' }],
['list'] // Console reporter
],
// Global setup/teardown
// globalSetup: require.resolve('./src/global-setup'),
// globalTeardown: require.resolve('./src/global-teardown'),
// Use custom fixtures
// projects: [
// {
// name: 'chromium',
// use: { ...devices['Desktop Chrome'] },
// },
// ],
// Web server for local testing
// webServer: {
// command: 'npm run start',
// url: 'http://localhost:3000',
// reuseExistingServer: !process.env.CI,
// },
});
Day 3-4: Allure Reporting¶
# Install Allure
npm install -D allure-playwright allure-commandline
# Configuration
// playwright.config.ts
reporter: [
['html'],
['allure-playwright']
],
# Generate report
npx playwright test --reporter=allure-playwright
npx allure generate allure-results --clean
npx allure open
typescript
// Example with Allure annotations
import { test, expect } from '@playwright/test';
import { allure } from 'allure-playwright';
test.describe('Checkout Process', () => {
test('Complete purchase with credit card', async ({ page }) => {
// Allure annotations
await allure.epic('Checkout');
await allure.feature('Payment Processing');
await allure.story('Credit Card Payment');
await allure.severity(allure.severityLevel.CRITICAL);
await allure.step('Navigate to checkout', async () => {
await page.goto('/checkout');
});
await allure.step('Fill payment details', async () => {
await page.fill('#card-number', '4111111111111111');
await page.fill('#expiry-date', '12/25');
await page.fill('#cvv', '123');
});
await allure.step('Complete purchase', async () => {
await page.click('#complete-purchase');
});
await allure.step('Verify success', async () => {
await expect(page.locator('.success-message')).toBeVisible();
});
});
});
Day 5-6: GitHub Actions CI/CD¶
# .github/workflows/playwright.yml
name: Playwright Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
workflow_dispatch: # Manual trigger
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
env:
BASE_URL: ${{ secrets.BASE_URL }}
TEST_USER: ${{ secrets.TEST_USER }}
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/
retention-days: 30
- name: Upload Allure results
if: always()
uses: actions/upload-artifact@v3
with:
name: allure-results
path: allure-results/
retention-days: 30
Day 7: Custom Fixtures & Utilities¶
// src/fixtures/custom-fixtures.ts
import { test as base, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
import { ProductsPage } from '../pages/ProductsPage';
// Extend base test with custom fixtures
export const test = base.extend<{
loginPage: LoginPage;
productsPage: ProductsPage;
authenticatedPage: any;
}>({
// Custom fixture: LoginPage
loginPage: async ({ page }, use) => {
const loginPage = new LoginPage(page);
await use(loginPage);
},
// Custom fixture: ProductsPage
productsPage: async ({ page }, use) => {
const productsPage = new ProductsPage(page);
await use(productsPage);
},
// Custom fixture: Pre-authenticated page
authenticatedPage: async ({ browser }, use) => {
// Create new context with storage state
const context = await browser.newContext({
storageState: 'auth.json'
});
const page = await context.newPage();
// Use the authenticated page
await use(page);
// Cleanup
await page.close();
await context.close();
},
});
export { expect };
🥉PHASE 3: MANUAL TESTING & DOCUMENTATION (Weeks 11-12)¶
Week 11: Professional Manual Test Cases¶
Day 1-2: Standard Test Case Template¶
TEST CASE TEMPLATE - INDUSTRY STANDARD
| Test Case | Information | Title | Module | Feature | Created By | Created Date | Last Modified | Version |
|---|---|---|---|---|---|---|---|---|
| ID | TC_CHECKOUT_001 | Complete checkout with credit card payment | Checkout | Payment Processin | [Your Name] | 2024-01-15 | 2024-01-15 | 1.0 |
Test Objective
Verify that a registered user can complete checkout process using credit card payment method.
1. User is registered and logged in
2. User has items in shopping cart
3. Credit card payment method is enabled
4. User has valid shipping address saved
5. Test credit card credentials are available
| User | Credit Card | Expiry | CVV | Shipping Address |
|---|---|---|---|---|
| testuser@example.com / Password123! | 4111 1111 1111 1111 | 12/2025 | 123 | [Valid US address] |
Test Steps & Expected Results
| Step | Action | Expected Result | Status | Notes |
|---|---|---|---|---|
| 1 | Navigate to cart page | Cart page loads with items displayed | ||
| 2 | Click "Checkout" button | Redirected to checkout page | ||
| 3 | Verify shipping address | Pre-saved address is displayed | ||
| 4 | Select shipping method | Standard shipping ($5.99) is selected by default | ||
| 5 | Click "Continue to Payment" | Payment section expands | ||
| 6 | Select "Credit Card" payment | Credit card form displays | ||
| 7 | Enter card number: 4111111111111111 | Field accepts input, no errors | ||
| 8 | Enter expiry: 12/25 | Field accepts input | ||
| 9 | Enter CVV: 123 | Field accepts input | ||
| 10 | Click "Review Order" | Order summary page displays | ||
| 11 | Verify order details | All items, prices, tax, shipping are correct | ||
| 12 | Click "Place Order" | Order confirmation page displays | ||
| 13 | Verify confirmation | Order number is generated | ||
| 14 | Check email | Order confirmation email is received |
Post Conditions
1. Order is created in system
2. Inventory is updated
3. User cart is empty
4. Order appears in user's order history
- Screenshot: checkout_process.png
- Screenshot: order_confirmation.png
- Email: order_confirmation_email.png
| Risk Level | Priority | Automation |
|---|---|---|
| High | P1 | Yes (Automated in checkout.spec.ts) |
Day 3-4: Complex Feature Test Cases¶
COMPLEX TEST CASE: MULTI-STEP CHECKOUT WITH PROMO CODE
Scenario: Apply expired promo code during checkout
| Test Case ID | Test Type | Test Technique |
|---|---|---|
| TC_CHECKOUT_005 | Negative Testing | Boundary Value Analysis |
Test Steps:
1. Add 3 items totaling $150 to cart
2. Apply promo code "SUMMER2023" (expired 2023-12-31)
3. Verify error message: "Promo code has expired"
4. Apply valid promo code "WINTER2024"
5. Verify discount applied (20% off)
6. Proceed with payment
7. Verify final amount = ($150 - $30) + tax + shipping
Edge Cases Covered:
- Expired promo code
- Valid promo code after expired one
- Discount calculation with tax
- Order confirmation with promo details
Day 5-7: Test Plan Template¶
TEST PLAN TEMPLATE
1. Introduction
1.1 Purpose
- This document outlines the test strategy for [Feature Name] release.
1.2 Scope
- In Scope: Checkout process, payment integration, order confirmation
- Out of Scope: User registration, product search, recommendation engine
- Verify all payment methods work correctly
- Ensure order calculations are accurate
- Validate email notifications
- Confirm database updates
3. Test Strategy
3.1 Test Levels
- Unit Testing: Developer responsibility
- Integration Testing: API testing between services
- System Testing: End-to-end workflows
- UAT: Business user validation
3.2 Test Types
- Functional Testing: All payment scenarios
- Regression Testing: Existing features
- Security Testing: PCI compliance
- Performance Testing: Load during peak
4. Test Deliverables
- Test Cases
- Test Data
- Bug Reports
- Test Summary Report
- Automation Scripts
5. Resource & Schedule
- Test Lead: [Name]
- Testers: 2
- Start Date: 2024-01-15
- End Date: 2024-01-30
- Total Effort: 40 person-hours
6. Risks & Mitigation
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| Payment gateway downtime | Medium | High | Mock service for testing |
| Test data corruption | Low | Medium | Daily backups |
| Schedule slippage | High | Medium | Agile iterations, MVP first |
7. Exit Criteria
- All critical test cases executed
- No P1/P2 bugs open
- Automation coverage > 70%
- UAT sign-off received
Week 12: Bug Reporting & Documentation Portfolio¶
Day 1-2: Real Bug Examples from Production¶
REAL BUG REPORT EXAMPLE
Title
- [Critical] [Checkout] Race condition causes double charging when rapidly clicking "Place Order"
Bug ID
- BUG-2024-001
Environment
- Environment: Production
- Browser: Chrome 120.0.6099.110
- OS: macOS Sonoma 14.2
- Device: MacBook Pro M2
- User Role: Registered Customer
- Timestamp: 2024-01-15 14:30:22 UTC
Description
- When user rapidly clicks (3+ times) the "Place Order" button within 500ms, system processes multiple payments resulting in duplicate charges to credit card.
Impact
- Business Impact: Customer charged multiple times, requires refunds
- Customer Impact: Financial loss, trust erosion
- Support Impact: Increased support tickets, manual refund processing
Steps to Reproduce
1. Login to account with valid credit card
2. Add any product to cart
3. Navigate to checkout
4. Fill all required fields
5. On "Place Order" page, quickly click button 5 times (within 500ms)
6. Observe network requests
Expected Result
- Only one payment transaction processed
- One order created
- One charge on credit card
- Button becomes disabled after first click
Actual Result
- Multiple payment API calls (/api/v1/payments)
- Multiple orders created (Order #1001, #1002, #1003)
- Multiple charges on credit card ($49.99 × 3)
- Button remains enabled during processing
Evidence
1. Screenshot: duplicate_orders.png
2. Network Log:
- POST /api/v1/payments - 200 OK (14:30:22.100)
- POST /api/v1/payments - 200 OK (14:30:22.300)
- POST /api/v1/payments - 200 OK (14:30:22.450)
3. Console Error:
- None
4. Database State:
- 3 orders with same cart items
Root Cause Analysis
- Payment button lacks debouncing mechanism. Frontend sends request without waiting for response or disabling button.
Severity:
- Critical
=> Why: Causes direct financial loss, violates PCI compliance principles.
Priority:
- P0 (Immediate Fix)
=> Why: Actively affecting customers, high support volume.
Workaround
- Educate support team to process refunds. Add banner warning users not to click multiple times.
Suggested Fix
// Frontend: Add debouncing and disable button
const placeOrder = debounce(async () => {
placeOrderButton.disabled = true;
try {
await processPayment();
} finally {
placeOrderButton.disabled = false;
}
}, 1000);
//Backend: Add idempotency key
POST /api/v1/payments
Headers: { "Idempotency-Key": "cart_123_session_456" }
Status:
Assigned To: [Backend Lead]
Due Date: 2024-01-17
Current Status: In Progress
Day 3-4: Bug Triage & Prioritization Matrix¶
BUG PRIORITIZATION MATRIX
Severity vs Priority
| Severity (Technical Impact) |
|---|
| - Critical: System crash, data loss, security breach |
| - Major: Feature broken, workaround exists |
| - Minor: Feature partially works, cosmetic issues |
| - Trivial: Typos, minor UI misalignment |
| Priority (Business Impact) |
|---|
| - P0: Fix immediately (blocking release/production) |
| - P1: Fix in current sprint |
| - P2: Fix in next sprint |
| - P3: Fix when resources available |
Decision Matrix¶
| Severity ↓ | Priority → | P0 | P1 | P2 | P3 |
|---|---|---|---|---|---|
| Critical | Always P0 | ✓ | |||
| Major | Depends on: • # of users affected • Workaround exists • Business critical feature |
✓ | |||
| Minor | Usually P2 | ||||
| Trivial | Usually P3 |
| Real Examples: |
|---|
| 1. Login not working for all users → Critical, P0 |
| 2. Checkout fails for PayPal only → Major, P1 |
| 3. Mobile menu alignment issue → Minor, P2 |
| 4. Typo in help text → Trivial, P3 |
Day 5-7: Portfolio Documentation¶
QA PORTFOLIO - [YOUR NAME]
1. Automation Framework Project
-
GitHub: https://github.com/yourusername/automation-framework
-
Tech Stack: TypeScript, Playwright, POM, Allure, GitHub Actions
Features:
- ✅ 50+ automated test cases
- ✅ Page Object Model architecture
- ✅ Data-driven testing
- ✅ API testing integration
- ✅ Cross-browser testing
- ✅ CI/CD with GitHub Actions
- ✅ Allure reporting
- ✅ Visual testing
Sample Test Coverage:¶
├── Authentication (Login/Logout)
│ ├── Successful login
│ ├── Invalid credentials
│ ├── Locked out user
│ └── Session management
├── Products
│ ├── Product listing
│ ├── Filtering & sorting
│ ├── Product details
│ └── Add to cart
├── Checkout
│ ├── Cart management
│ ├── Shipping address
│ ├── Payment processing
│ └── Order confirmation
└── API Tests
├── Auth endpoints
├── Product endpoints
├── Order endpoints
└── Health checks
2. Manual Testing Artifacts
Test Case Examples:
1. [TC-LOGIN-001] Comprehensive login test cases
2. [TC-CHECKOUT-001] Complete checkout flow
3. [TC-PAYMENT-001] Multiple payment methods
Bug Report Examples:
1. [BUG-001] Critical: Race condition in checkout
2. [BUG-002] Major: Memory leak in product gallery
3. [BUG-003] Minor: Accessibility issue in forms
Test Plan Examples:
1. E-commerce Checkout Test Plan
2. User Registration Test Plan
3. Mobile App Test Plan
3. Technical Skills Matrix
Automation:
- Expert: Playwright, TypeScript, POM
- Advanced: API Testing, CI/CD, Reporting
- Intermediate: Performance Testing, Security Testing
Manual Testing:
- Expert: Test Case Design, Bug Reporting
- Advanced: Test Planning, Risk Analysis
- Intermediate: UAT Coordination, Documentation
Tools:
- Test Management:* Jira, TestRail, Zephyr
- CI/CD: GitHub Actions, Jenkins
- Monitoring: Datadog, New Relic
- API Tools: Postman, Swagger
4. Certifications & Courses
1. ISTQB Foundation Level (In Progress)
2. Test Automation University Courses
3. Playwright Official Certification
🧭 PHASE 4: CAREER POSITIONING & INTERVIEWS (Weeks 13-16)¶
Week 13: Portfolio & CV Optimization¶
Day 1-2: CV for Automation Tester/SDET¶
[YOUR NAME]
- QA Automation Engineer / SDET
Contact
- 📧 email@example.com
- 📱 +84 123 456 789
- 🔗 linkedin.com/in/yourprofile
- 💻 github.com/yourusername
Summary
- QA Engineer with 3+ years experience in IT Support and Technical Writing,
transitioning to Automation Testing. Specialized in building automation frameworks
using TypeScript/Playwright, reducing regression testing time by 70%.
- Combines developer mindset with QA perspective to build sustainable testing systems.
Technical Skills
1. Automation
- Languages: TypeScript, Python, JavaScript
- Frameworks: Playwright, Cypress, Selenium, Pytest
- Tools: GitHub Actions, Jenkins, Docker, Allure Report
- Architecture: Page Object Model, Data-Driven Testing
2. Manual Testing
- Test Case Design (EP, BVA, Decision Table)
- Bug Tracking & Triage (Jira, Bugzilla)
- Test Planning & Strategy
- API Testing (REST, GraphQL)
Projects
- E-commerce Automation Framework
- Tech: TypeScript, Playwright, POM, GitHub Actions, Allure
- GitHub: github.com/yourusername/ecommerce-automation
- Built framework from scratch with 60+ test cases
- Implemented Page Object Model for maintainability
- Integrated CI/CD running automatically on each commit
- Created custom reports with Allure
- Result* Reduced manual testing time by 70%
API Testing Suite
- Tech: Python, Pytest, Requests, Postman
- Tested 20+ API endpoints of RESTful service
- Implemented data-driven testing with JSON/YAML
- Created performance tests with Locust
- Coverage: 95% of API endpoints automated
Professional Experience
- Technical Support Specialist | ABC Company | 2020-2023
- Troubleshot and fixed 500+ technical issues
- Wrote documentation for internal tools
- Trained 20+ staff members on software usage
- Transferable Skills: Debugging, Documentation, User Perspective
Education
- Bachelor of Computer Science** | University XYZ | 2016-2020
Certifications
- ISTQB Foundation Level (Expected: March 2024)
- Playwright Test Automation Certification
- Test Automation University Courses
Day 3-4: Optimized GitHub Portfolio¶
🚀 E-commerce Automation Framework
Playwright Tests
https://github.com/yourusername/automation-framework/actions/workflows/playwright.yml/badge.svg
https://github.com/yourusername/automation-framework/actions/workflows/playwright.yml)
Professional automation framework for e-commerce testing using Playwright and TypeScript.
📋 Features - ✅ Modern Stack: TypeScript + Playwright + POM - ✅ Cross-browser: Chrome, Firefox, Safari, Edge - ✅ Multi-environment: Dev, Staging, Production - ✅ CI/CD Ready: GitHub Actions integration - ✅ Beautiful Reports: Allure + HTML reports - ✅ API Testing: Integrated REST API tests - ✅ Visual Testing: Screenshot comparisons
🏗️ Architecture
src/
├── pages/ # Page Objects (POM)
├── tests/ # Test Specifications
├── utils/ # Helper Functions
├── data/ # Test Data (JSON/TS)
└── fixtures/ # Custom Playwright Fixtures
🚀 Quick Start
Prerequisites
- Node.js 16+
- npm or yarn
Installation
# Clone repository
git clone https://github.com/yourusername/automation-framework.git
cd automation-framework
Install dependencies
npm install
Install Playwright browsers
npx playwright install
# Run all tests
npm test
Run specific test file
npm test -- tests/login.spec.ts
npm run test:ui
npm run test:allure
📊 Test Coverage
Authentication: Login, Logout, Registration
Products: Listing, Filtering, Details
Cart: Add/Remove items, Quantity update
Checkout: Shipping, Payment, Order confirmation
API: REST endpoints testing
📈 CI/CD Pipeline
Automated testing pipeline using GitHub Actions:
On push: Run all tests
On PR: Run smoke tests
Schedule: Daily full regression
Report: Upload Allure report
test('Complete checkout with credit card', async ({ page }) => {
const loginPage = new LoginPage(page);
const productsPage = new ProductsPage(page);
const cartPage = new CartPage(page);
await loginPage.login('standard_user', 'secret_sauce');
await productsPage.addProductToCart('Sauce Labs Backpack');
await cartPage.checkout();
// ... more steps
});
https://docs/images/allure-report.png
Interactive test reports with steps, screenshots, and videos
🤝 Contributing
Fork the project
Create your feature branch
Add tests for new functionality
Ensure all tests pass
Submit a pull request
MIT License - see LICENSE file for details
Week 14: Technical Interviews¶
Day 1-2: QA Theory Questions¶
What is SDLC vs STLC? How are they different?
→ SDLC (Software Development Life Cycle): Software development lifecycle
→ STLC (Software Testing Life Cycle): Software testing lifecycle
→ Relationship: STLC is a subset of SDLC, focused on testing activities
How are Severity and Priority different?
→ Severity: Technical impact of bug
→ Priority: Business priority to fix bug
→ Example: Typo on homepage (High Priority, Low Severity)
Memory leak (High Severity, Medium Priority)
What is Regression Testing? When is it needed?
→ Regression: Testing new code doesn't break existing functionality
→ When: After bug fixes, new features, code refactoring
→ Automation is crucial for regression to save time
What Test Case Design Techniques do you know?
→ Equivalence Partitioning: Divide input into partitions
→ Boundary Value Analysis: Test boundary values
→ Decision Table Testing: Test combinations of conditions
→ State Transition Testing: Test system states
How do you estimate testing effort?
→ Based on: Number of test cases, complexity, test environment
→ Formula: (Number of test cases × Average time per test) + Buffer
→ Buffer for: Bug fixing, retesting, environment issues
Day 3-4: Automation Questions¶
Why choose Playwright over Selenium?
→ Playwright: Modern, faster, built-in wait mechanisms
→ Selenium: Legacy, slower, needs explicit waits
→ Playwright supports: Multi-browser, mobile, API, network mocking
What is Page Object Model? Benefits?
→ POM: Design pattern separating UI locators from test logic
→ Benefits: Easy maintenance, code reuse, reduced duplication
→ When UI changes, only update Page Object
How do you handle dynamic elements?
→ Use: Custom wait, retry mechanisms
→ Locator strategies: Text-based, role-based, test-id
→ Playwright auto-wait: No need for explicit sleep
How do you implement Data-Driven Testing?
→ Separate test data into files (JSON, CSV, TS)
→ Read data in tests
→ Run tests with multiple data sets
→ Benefits: Easy to add test cases, maintainable
How do you debug failed tests?
→ Screenshots on failure
→ Video recording
→ Trace viewer (Playwright)
→ Console logs, network logs
Day 5-7: Practical Questions & Case Study¶
CASE STUDY: You're assigned to test "Forgot Password" feature
How would you analyze it?
→ Understand requirements: Input email → send reset link → reset password
→ Identify test scope: UI, API, Email, Security, Performance
→ Identify risks: Security (token expiry), Email deliverability
How would you design test cases?
→ Positive: Valid email, check email received
→ Negative: Invalid email, non-existent email
→ Security: Token expiry, token reuse, brute force protection
→ Performance: Load test for mass password reset requests
What would you automate?
→ API tests: /forgot-password endpoint
→ UI tests: Form validation, success/error messages
→ Integration: Check email delivery (using test email service)
What metrics would you track?
→ Test coverage: % scenarios automated
→ Defect density: Bugs found per test case
→ Automation ROI: Time saved vs time invested
Week 15-16: Mock Interviews & Salary Negotiation¶
Day 1-2: Behavioral Questions¶
"Why are you transitioning from Developer/IT Support to Tester?"
→ "I discovered passion in ensuring product quality
Coding experience helps me understand systems deeply, write effective tests
I enjoy the feeling of 'breaking things' to find bugs before users"
"Describe the most complex bug you've found?"
→ "I discovered a race condition in checkout process
When users clicked rapidly, system created multiple orders
I reproduced with scripts, captured network requests
Suggested fix: Add debouncing and idempotency keys"
"How do you work with developers when finding bugs?"
→ "First, ensure bug is reproducible with clear steps
Write quality bug report with evidence
Communicate respectfully, focus on problem not person
Collaborate on root cause analysis and solution"
"When do you say 'NO' to a release?"
→ "When there are Critical bugs affecting core functionality
When there's no test coverage for high-risk areas
When performance/security requirements aren't met
But always provide risk assessment and alternatives"
Day 3-4: Technical Assignment Practice¶
// ASSIGNMENT: Test login page of any website
// Requirements:
// 1. Write manual test cases (10+ scenarios)
// 2. Automate 5 most important test cases
// 3. Implement Page Object Model
// 4. Add reporting
// 5. Write README with setup instructions
// Solution structure:
src/
├── pages/
│ └── LoginPage.ts
├── tests/
│ └── login.spec.ts
├── data/
│ └── users.ts
└── README.md
// Test cases to cover:
// - Successful login
// - Invalid credentials
// - Empty fields
// - SQL injection attempt
// - Password show/hide
// - Remember me functionality
// - Error message validation
// - Session timeout
// - Concurrent login
// - Accessibility testing
Day 5-7: Salary Negotiation & Offer Evaluation¶
EVALUATE JOB OFFER - CHECKLIST:
1. Compensation Package
✅ Base salary: $X (market range: $Y-$Z)
✅ Bonus structure: Performance, annual
✅ Stock options/RSUs: Vesting schedule
✅ Benefits: Health insurance, 401k match
2. Role & Growth
✅ Title: QA Engineer vs SDET vs Automation Engineer
✅ Career path: Promotion track, skill development
✅ Learning budget: Conferences, courses
✅ Mentorship: Senior engineers available
3. Technical Stack
✅ Modern tools: Playwright/Cypress vs Legacy Selenium
✅ CI/CD: GitHub Actions/Jenkins
✅ Cloud: AWS/Azure/GCP exposure
✅ Development practices: Agile, code reviews
4. Work Culture
✅ Work-life balance: Flexible hours, remote options
✅ Testing culture: QA involved early in SDLC
✅ Engineering quality: Code coverage requirements
✅ Innovation: Time for learning, hackathons
NEGOTIATION SCRIPTS:
When salary is too low:
"Thank you for the offer. Based on my research for [Role] in [Location] with [X] years experience, the market range is [Y-Z]. Given my [specific skills], I was hoping for [desired range]. Is there flexibility?"
When evaluating multiple offers:
"I'm excited about this opportunity. I have another offer at [Company] for [salary]. While I prefer your company because [reasons], the compensation difference is significant. Can we bridge this gap?"
Asking for growth opportunities:
"Beyond compensation, I'm excited about growing into [next role]. Can we discuss the typical timeline for promotion to Senior Engineer and what metrics are used for evaluation?"
📅 16-WEEK TIMELINE OVERVIEW¶
Month 1: Foundation (Weeks 1-4)¶
Weeks 1-2: QA Theory Mastery¶
- SDLC/STLC, Agile/Scrum
- Test levels & types
- Bug reporting fundamentals
Weeks 3-4: Tech Stack Decision¶
- Choose: TypeScript + Playwright
- Setup environment
- Basic scripting
Month 2: Automation Framework (Weeks 5-10)¶
Weeks 5-6: Web Automation Basics¶
- Locators, basic tests
- Test design techniques
- Data-driven testing
Weeks 7-8: Professional Framework¶
- Page Object Model
- API testing integration
- Test organization
Weeks 9-10: CI/CD & Reporting¶
- GitHub Actions
- Allure reports
- Advanced configurations
Month 3: Manual & Documentation (Weeks 11-12)¶
Week 11: Manual Test Cases¶
- Professional test case writing
- Test planning
- Complex scenarios
Week 12: Bug Reporting Portfolio¶
- Real bug examples
- Bug triage process
- Documentation artifacts
Month 4: Career Preparation (Weeks 13-16)¶
Week 13: Portfolio & CV¶
- GitHub optimization
- CV tailoring
- LinkedIn profile
Week 14: Technical Interviews¶
- Theory questions
- Automation questions
- Case studies
Weeks 15-16: Mock Interviews & Offers¶
- Behavioral questions
- Technical assignments
- Salary negotiation
🎯 SUCCESS METRICS - PROGRESS MEASUREMENT¶
After 4 weeks:¶
✅ Clear understanding of SDLC/STLC
✅ Able to write basic automation scripts
✅ Know how to report bugs professionally
✅ Chose suitable tech stack
After 8 weeks:¶
✅ Have automation project on GitHub
✅ Implemented Page Object Model
✅ Can write data-driven tests
✅ Have 20+ automated test cases
After 12 weeks:¶
✅ CI/CD pipeline working
✅ Have professional test reports
✅ Portfolio with manual test cases
✅ Quality bug reporting examples
After 16 weeks:¶
✅ CV optimized for QA/SDET roles
✅ Ready for technical interviews
✅ Have salary negotiation strategy
✅ Can apply for Junior/Mid positions
🚨 COMMON PITFALLS & SOLUTIONS¶
1. "I'm learning multiple technologies at once"
PROBLEM: Learning Selenium, Cypress, Playwright simultaneously
SOLUTION: Choose 1 framework, master it first
2. "I only focus on automation, ignoring manual"
PROBLEM: Don't know how to design test cases, only know coding
SOLUTION: Spend at least 20% time on manual testing skills
3. "My GitHub only has code, no documentation"
PROBLEM: Repository hard to understand, don't know how to run
SOLUTION: Invest in quality README, screenshots, videos
4. "I apply to every job, don't tailor CV"
PROBLEM: Same CV for every company
SOLUTION: Customize CV for each job description
💼 JOB SEARCH STRATEGY¶
Target Companies:
Startups (Seed-Series B): Like modern tech stack, wearing multiple hats
Tech Companies: Have engineering culture, value automation highly
E-commerce: Many testing challenges, clear revenue impact
FinTech/HealthTech: High quality standards, security focus
Week 13: Research phase
- Identify 50 target companies
- Update LinkedIn with keywords
- Follow engineering blogs
Week 14: Application phase
- Apply 5-10 jobs/day
- Customize cover letters
- Track applications in spreadsheet
Week 15: Interview phase
- Schedule 2-3 interviews/week
- Practice mock interviews
- Collect feedback
Week 16: Decision phase
- Evaluate offers
- Negotiate terms
- Plan onboarding
1. LinkedIn Connections:
- Connect with QA managers
- Join QA groups
- Share learning journey
2. GitHub Presence:
- Contribute to open source
- Star similar projects
- Follow industry leaders
3. Local Meetups:
- Testing meetups
- Tech conferences
- Hackathons
REMEMBER:¶
This roadmap is just a map. What matters most is ACTION and PERSISTENCE. Study at least 2 hours daily, code at least 1 hour daily. After 4 months, you'll have enough skills to successfully transition to a QA/SDET role.