Production-grade Playwright + TypeScript end-to-end test suite targeting mempool.space, a real-world Bitcoin blockchain explorer.
This is real-world fintech QA — not a practice site. The application under test handles real production traffic, real Bitcoin data, real-time WebSocket streams, and is used daily by traders, miners, and developers worldwide.
Most QA portfolio projects target practice sites (saucedemo, the-internet, automationexercise). Those prove you can write tests, but not that you can handle real production complexity: dynamic data, WebSocket connections, real network conditions, frequent UI updates, and the absence of stable test IDs.
This suite targets a real production fintech application and demonstrates:
- Working with dynamic, real-time data that changes every block (~10 min)
- Stable selector strategies when the application doesn't ship
data-testidattributes - Page Object Model + fixture composition in idiomatic Playwright TypeScript
- Cross-browser + responsive coverage (Chromium, Firefox, mobile viewports)
- WebSocket-aware testing (live mempool updates)
- CI/CD ready — runs on GitHub Actions in matrix mode
20+ tests across 8 spec files:
| Spec | What it covers |
|---|---|
home.spec.ts |
Title, brand, live block data rendering, search input focus, performance budget |
search.spec.ts |
Search by block height, transaction ID, Bitcoin address, invalid input handling |
block-details.spec.ts |
Block-by-height navigation, Genesis block, future block graceful handling |
transaction.spec.ts |
Historic transaction inspection, inputs/outputs/fee structure |
address.spec.ts |
Satoshi address page, balance/received-amount rendering |
fees-and-mining.spec.ts |
Mining pool page, graphs, API docs accessibility |
responsive.spec.ts |
Mobile (375px), tablet (768px), desktop wide (1920px) layouts |
realtime.spec.ts |
WebSocket connection establishment, live mempool block updates |
Each test uses well-known stable Bitcoin artifacts (Genesis block, the first-ever Bitcoin transaction, Satoshi's historic address) — these will exist permanently, making the suite resilient to time-based flakiness.
mempool-e2e-suite/
├── playwright.config.ts Multi-project (Chromium, Firefox, mobile), HTML + list + JSON reporters
├── tsconfig.json Strict TypeScript with path aliases
├── .github/workflows/ GitHub Actions matrix CI (chromium + firefox)
├── pages/ Page Object Model
│ ├── BasePage.ts Shared navigation, cookie handling, screenshot helpers
│ ├── HomePage.ts Homepage interactions and assertions
│ ├── BlockDetailsPage.ts Block navigation
│ ├── TransactionPage.ts Transaction inspection
│ └── AddressPage.ts Bitcoin address pages
├── fixtures/
│ └── test-fixtures.ts Extended Playwright test with page-object fixtures
├── tests/ Spec files grouped by feature area
├── data/
│ └── test-data.ts Stable Bitcoin artifacts + performance budgets
└── utils/ Reusable helpers (timing, formatting)
Prerequisites: Node.js 18+
git clone https://github.com/asadmukhtar220/mempool-e2e-suite.git
cd mempool-e2e-suite
npm install
npx playwright install chromium firefox
# Run all tests on Chromium
npm test
# Run on a specific browser
npm run test:chromium
npm run test:firefox
# Headed mode (watch the browser)
npm run test:headed
# Interactive UI mode
npm run test:ui
# Debug a specific test
npm run test:debug
# View HTML report
npm run reportThis project uses Playwright's modern fixture pattern instead of plain POM imports. Each test receives ready-instantiated page objects through dependency injection:
test('search by block height navigates to block page', async ({ homePage, page }) => {
await homePage.goto();
await homePage.search('800000');
await expect(page).toHaveURL(/\/block\//);
});Benefits over the classic POM-only approach:
- No
new HomePage(page)boilerplate in every test - Each test is automatically isolated — no shared mutable state
- Page objects can declare their own setup/teardown hooks
- Type-safe end-to-end
Mempool.space ships almost no data-testid attributes. The suite handles this via:
- Role-based locators first —
getByRole('searchbox'),getByRole('heading') - Application component selectors — Angular's
app-mempool-blocks,app-blockchain-blockselement names are stable across UI tweaks - Semantic CSS class fragments —
[class*="mempool-blocks"]survives minor classname changes - Text-based locators as fallback — for headings and labels
This is real-world QA: locator strategy matters more than test count.
npm run test:chromium # Desktop Chrome
npm run test:firefox # Desktop Firefox
npx playwright test --project=mobile-chrome # Pixel 7 viewportThe responsive.spec.ts suite explicitly validates 375px (mobile), 768px (tablet), and 1920px (wide desktop) viewports.
A GitHub Actions workflow runs:
- On every push to
mainordevelop - On every pull request to
main - Nightly at 06:00 UTC
The job matrix runs Chromium and Firefox in parallel, uploads HTML reports as artifacts, and TypeScript-checks the codebase before tests execute.
See .github/workflows/playwright.yml.
Real-world site testing requires defensive patterns. This suite uses:
- No hard-coded
waitof less than necessary — instead,waitForLoadState('domcontentloaded')andexpect(...).toBeVisible({ timeout }) - Retries on CI —
retries: 2in CI mode,1locally - Trace on first retry — automatic Playwright trace capture for failed runs
- Screenshots and video retained on failure for debugging
- Network idle wait wrapped with
.catch(() => {})because mempool.space has persistent WebSocket connections that prevent traditional networkidle resolution - Performance budgets — explicit assertions that homepage loads within 10 seconds, search results within 8 seconds
- Playwright Test 1.48+ (native test runner)
- TypeScript 5.4+ (strict mode)
- Node.js 18+
- GitHub Actions (CI)
No external assertion library, no separate test runner — Playwright Test is self-contained.
Hiring a QA engineer for production work means evaluating: can they handle the messy real world?
This project answers that with code:
- Real production target — not a sandboxed practice site
- Dynamic data — block heights change every 10 minutes, mempool updates every second
- No friendly test IDs — locator strategy matters
- Cross-browser — Chromium + Firefox in CI
- Cross-viewport — mobile, tablet, desktop
- Real-time — WebSocket assertions, performance budgets
- Modern stack — TypeScript strict mode, Playwright fixtures, GitHub Actions
- Defensive — retries, traces, screenshots on failure
Asad Mukhtar — QA Automation Engineer & Browser Automation Specialist
- Fiverr: asadmukhtar464
- GitHub: asadmukhtar220
Services: end-to-end test automation (Playwright, Selenium, Appium), API testing, manual QA, web scraping, and CI/CD test infrastructure. Free 15-minute project scoping call.
MIT — see LICENSE.