1. Define success
Valid credentials open the Products page. Logout ends the session and shows the login form.
This is the acceptance criteria.Hasan Akdogan · QA Automation Engineer · 1-page PDF
Loading interactive demos…
Quick access to demos, labs, reports, and contact links.
Hasan Akdogan
QA Automation Engineer
Playwright • CI/CD • API Testing
Follow a feature from test design to Playwright automation, reporting, defect investigation and retesting.
How I test a feature from start to finish — one login story through every step: analysis, test case, manual test, automation, report, and a real bug found, reported and retested.
Follow one example, one step at a time. Start with what should happen, then see how a test catches a logout bug.
A user should be able to log in, see the Products page, then log out safely.
Valid credentials open the Products page. Logout ends the session and shows the login form.
This is the acceptance criteria.Follow the steps in the browser and compare the result with the requirement.
Automate this stable flow for regression checks.The key check: after Logout, the login form must be visible again. We will use this same check in the code and the run.
TC-LOGIN-001 documents the expected flow. The sample PASS below describes the manual baseline; the automated build results appear in Step 03.
| User Story | As a user, I should log in successfully and leave the session safely. |
|---|---|
| Acceptance Criteria | User can log in with valid credentials, access the Products page, log out successfully, and return to the login form. |
| Requirement Analysis |
Questions for the PO / extra scenarios:
|
| Test Case ID | TC-LOGIN-001 |
| Test Case Description | Verify successful login with valid credentials and complete Sauce Demo login/logout flow. |
| Pre-Condition | Application is accessible and demo environment is available. |
| Test Steps and Description |
|
| Test Data |
URL:
https://www.saucedemo.com
User: standard_user
Pass: secret_sauce
|
| Expected Result | User logs in successfully, logs out successfully, and the login form is displayed again. |
| Execution | Manual first (Chrome) → then automated: critical, stable and repeated in every regression. |
| Actual Result | Actual behavior matches expected result. Test completed successfully. |
| Comments / evidence | Demo execution output confirms successful flow. |
| Pass / Fail | PASS |
Feature: User Authentication
Scenario: Successful login and logout
Given the login page is displayed
When I log in with valid credentials
Then the inventory page should be visible
When I click Logout
Then the login page should be displayed again
Playwright repeats the user’s actions and checks the expected result after each one.
await loginPage.login(user, password);await inventoryPage.expectLoaded();await inventoryPage.logout();
await expect(loginPage.loginButton).toBeVisible();Why automate this? Login and logout are critical actions. The same test can check them again after every change.
import { test, expect } from '@playwright/test'; import { LoginPage } from './pages/LoginPage'; import { InventoryPage } from './pages/InventoryPage'; test.describe('SauceDemo — auth', () => { let loginPage: LoginPage; let inventoryPage: InventoryPage; test.beforeEach(async ({ page }) => { loginPage = new LoginPage(page); inventoryPage = new InventoryPage(page); await loginPage.goto(); }); test('TC-LOGIN-001: login → inventory → logout', async () => { await loginPage.login('standard_user', 'secret_sauce'); await inventoryPage.expectLoaded(); await inventoryPage.logout(); await expect(loginPage.loginButton).toBeVisible(); }); });
// pages/LoginPage.ts import { type Page, type Locator, expect } from '@playwright/test'; export class LoginPage { readonly username: Locator; readonly password: Locator; readonly loginButton: Locator; readonly errorMessage: Locator; constructor(private readonly page: Page) { this.username = page.locator('[data-test="username"]'); this.password = page.locator('[data-test="password"]'); this.loginButton = page.locator('[data-test="login-button"]'); this.errorMessage = page.locator('[data-test="error"]'); } async goto() { await this.page.goto('/'); // baseURL in playwright.config.ts await expect(this.loginButton).toBeVisible(); } async login(user: string, pass: string) { await this.username.fill(user); await this.password.fill(pass); await this.loginButton.click(); } } // pages/InventoryPage.ts import { type Page, type Locator, expect } from '@playwright/test'; export class InventoryPage { readonly productList: Locator; readonly menuButton: Locator; readonly logoutLink: Locator; constructor(private readonly page: Page) { this.productList = page.locator('.inventory_list'); this.menuButton = page.getByRole('button', { name: 'Open Menu' }); this.logoutLink = page.getByRole('link', { name: 'Logout' }); } async expectLoaded() { await expect(this.page).toHaveURL(/inventory/); await expect(this.productList).toBeVisible(); } async logout() { await this.menuButton.click(); await this.logoutLink.click(); } }
Start with v1.0.1. Login works, but Logout leaves the user on Products — so our final check should fail.
Pick a build and click Run test. Build v1.0.1 has a logout bug, so the test fails. Report the bug, then retest on the fixed build v1.0.2.
Execution summary
Test failed — bug found
After clicking Logout the user stays on /inventory.html. I checked it manually too: it is a product bug, not a flaky test.
Retest passed — bug can be closed
Same test on build v1.0.2 passes. The test stays in the regression suite so this bug cannot come back unnoticed.
Run the test in Step 03 to generate evidence. Here is what to look for in this example.
Logout ends the session. The login form is visible again.
The user stays on Products. The login-form check fails.
Run the same test on the fixed build. A passing result confirms this logout check works again.
There are no environment variables (simulation)
| Test name | Status | Duration |
|---|---|---|
— |
— | — |
On a real run, Playwright saves PNGs per step or on failure. In this demo, assert thumbnails (login, inventory, logout) load only after the run finishes; until then, the slots stay empty.
On a real run, set video: 'on' or
'retain-on-failure' in
playwright.config — output often lands
in test-results/. In this demo, a screen recording
(video evidence) is attached only after the run
completes.
Demo file: videos/pw-run-demo-evidence.mp4 — optimized screen capture of the
login → inventory → logout run.
This panel is a front-end simulation. In production, wire the same layout to your reporter output or Allure JSON — the workflow matches how QA engineers triage runs after npx playwright test.
This interactive lab is loading. If this message stays, please refresh the page.
This interactive lab is loading. If this message stays, please refresh the page.
This interactive lab is loading. If this message stays, please refresh the page.
Hasan’s portfolio · AI assistant