End-to-end test automation suite for automationexercise.com, covering the core e-commerce user journey: Registration → Login → Product Search → Product Details → Cart → Checkout → Order Confirmation.
Built with Playwright and TypeScript, using the Page Object Model (POM) pattern and custom fixtures for setup and state reuse.
- Playwright (
@playwright/test) — test runner and browser automation - TypeScript — type-safe test and page object code
- dotenv — environment-based configuration
AutomationExercise/
├── authConfig/
│ └── auth.setup.ts # logs in once, saves session to auth/user.json
├── auth/
│ └── user.json # generated storage state (gitignored)
├── tests/
│ └── e2e/
│ ├── login-signup/
│ │ ├── signup.spec.ts
│ │ └── login.spec.ts
│ ├── search/
│ │ └── search.spec.ts
│ ├── product-details/
│ │ └── product-details.spec.ts
│ ├── cart/
│ │ └── cart.spec.ts
│ ├── checkout/
│ │ └── checkout.spec.ts
│ └── payment/
│ └── payment.spec.ts
├── pages/
│ ├── login.page.ts
│ ├── signup.page.ts
│ ├── search.page.ts
│ ├── product.page.ts
│ ├── cart.page.ts
│ ├── checkout.page.ts
│ └── payment.page.ts
├── fixtures/
│ └── app.fixture.ts # custom fixtures wiring page objects into tests
├── test-data/
│ └── products.ts # known product IDs used across test suites
├── utils/
│ └── api-client.ts # API helpers (e.g. fetching product data for verification)
├── playwright.config.ts
├── .env # local environment config (gitignored)
└── README.md
npm install
npx playwright installCreate a .env file in the project root:
BASE_URL=https://automationexercise.com
VALID_USERNAME=your_test_account_email@example.com
VALID_PASSWORD=your_test_account_password
A valid registered account on the site is required for
VALID_USERNAME/VALID_PASSWORD— these are used by the authentication setup project to log in and generate a reusable session.
Run everything:
npx playwright testRun a specific project:
npx playwright test --project=chromium # login-signup, search, product-details (no auth required)
npx playwright test --project=authenticated # cart, checkout, payment (auth applied automatically)
npx playwright test --project=setup # runs only the login/session-seeding stepRun a specific file or test by name:
npx playwright test tests/e2e/search/search.spec.ts
npx playwright test -g "case sensitivity"Useful debug modes:
npx playwright test --ui # interactive UI mode
npx playwright test --headed # see the browser
npx playwright test --debug # step through with the Inspector
npx playwright show-report # view the last HTML reportTests under cart/, checkout/, and payment/ require a logged-in session. Rather than logging in via the UI in every test:
- The
setupproject (authConfig/auth.setup.ts) runs once, logs in via the UI, and saves the authenticated session toauth/user.jsonusing Playwright'sstorageState. - The
authenticatedproject declaresdependencies: ['setup']and loadsauth/user.jsonautomatically — every test incart/,checkout/, andpayment/starts already logged in. - Tests under
login-signup/,search/, andproduct-details/run under thechromiumproject with no stored session, since they don't require authentication.
If a test specifically needs to verify logged-out behavior (e.g. the sign-in prompt on checkout), it overrides the project default locally with test.use({ storageState: { cookies: [], origins: [] } }).
pages/— one class per page, holding locators and page-specific actions (no assertions).fixtures/app.fixture.ts— wires page objects into thetestfunction so specs can request{ loginPage, cartPage, checkoutPage, ... }directly instead of manually instantiating them. Specs importtest/expectfrom this file, not from@playwright/test.
Example:
import { test, expect } from '../../fixtures/app.fixture';
test('user can search for a product by name', async ({ searchPage }) => {
await searchPage.goto();
await searchPage.searchProduct('Blue Top');
await searchPage.verifySearchResultsContainTerm('Blue Top');
});test-data/products.tsholds a fixed, deliberately varied set of known product IDs (different categories, brands, and naming edge cases) used for product-details and search verification — not randomly generated, so failures are reproducible across runs.- Dynamic values that must be unique per run (e.g. signup emails) are generated via helpers in
utils/, not hardcoded, to avoid collisions across parallel test runs.
- This site has no formal requirements document (BRD); test scope was derived by direct exploration of the UI and its public API (
/api/productsList,/api/verifyLogin, etc.). - Some validation rules assumed in early drafts of the test cases (e.g. password complexity, payment field format validation) were later verified against actual site behavior and adjusted — see test case documentation for details.
- API testing is scoped as a separate, module-by-module pass and is not yet part of this repository.