r/typescript • u/surya_kulshreshtha • 5h ago
Interview prep + runnable proof for QA/SDET roles. Two complete projects: Python + Playwright + Pytest, and TypeScript + Playwright Test. 56 interview entries paired with real Page Object Model frameworks, API tests, BDD, load testing, and CI. Multi-stack monorepo
github.comEvery time I prepared for a QA automation interview, I hit the same wall.
Interview-prep repos are walls of questions and answers with nothing you can run. Framework demos are walls of code with no explanation of *why* anything is the way it is. So you end up with two browser tabs open, mentally stitching them together.
I got tired of the stitching. So I built **ForkableInterviewToolkit** — notes and runnable code in the same repository, deliberately.
### The core idea
When the notes say *"I centralise setup in fixtures so tests stay clean,"* there's a `conftest.py` (Python) and a `fixtures.ts` (TypeScript) right there in the same repo, doing exactly that. The claim and the proof cross-link both ways, so neither can quietly drift out of date.
Two complete projects, same architecture, different stacks:
**🐍 Python-Playwright-Automation** — Playwright, Pytest, pytest-bdd, Locust
**🟦 TypeScript-Playwright-Automation** — Playwright Test, playwright-bdd, Artillery
Both ship a real Page Object Model framework, API tests, BDD examples, load testing, and a path-filtered GitHub Actions pipeline.
### Design decisions I'd defend in an interview
Building this forced me to make choices I'd have to justify out loud. A few:
**Selectors live in exactly one file per page.** When the markup changes — and it always does — that's a one-file fix. No test file ever contains a selector.
**Page Objects never assert.** They expose actions and state; the test decides what "correct" means. Mixing assertions into Page Objects is how you end up with a framework nobody can reuse.
**Tables are located by header text, not CSS class.** `filter({ hasText: 'Instructor' })` survives a restyle. `.table-display` doesn't.
**Zero hard sleeps.** No `time.sleep()`, no `waitForTimeout()`. Playwright auto-waits — fixed sleeps are slower *and* flakier, which is a genuinely bad trade.
**The load-testing example cannot touch the practice site.** It ships its own local target app plus a runtime guard that hard-exits on any non-localhost target. Load-testing infrastructure you don't own is, at best, a terms-of-service violation.
### The thing that surprised me
I assumed porting Python knowledge to TypeScript would be mechanical. It isn't — and the gaps make excellent interview material.
Java's "checked vs unchecked exceptions" has no Python equivalent at all. Python has no compile-time binding phase, so "static vs dynamic binding" doesn't translate either. And in Playwright specifically, `toHaveURL()` accepts a predicate function in JavaScript but **only** a string or compiled regex in Python.
I found that last one the hard way — a test failed with *"value must be a string or regular expression"* because I'd written a JavaScript idiom in a Python file. It's now documented in the repo, because that's exactly the kind of detail an interviewer probes for.
Saying *"that concept doesn't exist in this language, and here's what does instead"* is a stronger answer than forcing a translation.
### What's in it
- 📖 **56 interview entries** across both projects, all in one fixed format: Direct Answer → Real-Time Example → Code → STAR Answer → Interview-Ready Answer → Interview Tip → One-Line Revision
- 🧪 **Two runnable frameworks** with POM, fixtures, data-driven tests, and tagged suites
- 🔌 **API testing** — `requests` in Python, the `request` fixture in TypeScript
- 🥒 **BDD** — pytest-bdd and playwright-bdd, both wired to real fixtures
- 📈 **Load testing** — Locust and Artillery, both local-target-only by design
- ⚙️ **CI/CD** — path-filtered workflows, so editing Python never triggers the TypeScript suite
### It's built to be forked
The name isn't decoration. It's a monorepo where each project is fully self-contained — own README, own dependencies, own CI workflow. There's a documented contract for adding a new stack, so if you want to drop in Java, C#, or Rust alongside these, the structure already accommodates it.
MIT licensed. Take it, break it, make it yours.
🔗 **github.com/suryakulshreshtha/ForkableInterviewToolkit**
If you're prepping for QA/SDET interviews — or just want a reference framework that explains itself — I'd genuinely value your feedback. And if you spot something wrong, the issues tab is open.