When teams design a frontend take-home, the first idea is usually a CRUD app. We decided to go one step further.
This post covers why we designed our assignment as a simulation of real work instead of a pure implementation task, and what we learned building an E2E auto-grading pipeline for it.
"Isn't CRUD enough?"
Our evaluation criteria were clear from the start:
- Turning data into UI — how well a candidate presents a complex data structure as a usable interface
- Handling the unhappy path — consistent UX under network delays and API failures
- Code written for collaborators — clear naming, sensible comments, consistent patterns
- Sustainable architecture — a structure that bends with changing requirements
A plain CRUD app can't really surface most of those. So we set a different goal:
Let candidates experience the problems they'd actually face on our team.
That cuts both ways. Candidates get to see how we solve problems here. We get to see how they'd solve problems once they joined. It shows attitude and structural thinking better than raw implementation speed.
Designing a real-work simulation
We took the UI, API, and logic from one of our production services and rebuilt a simplified version of it. Not a mock-up — a compressed set of situations frontend engineers hit every week:
- Lists and conditional rendering
- Data caching and transformation
- Slow and failing API responses
- Responsive UI and state management
- Multi-step forms with validation
Hidden traps in the requirements 🧩
A task that only asks for features is boring and teaches nothing. So we deliberately planted situations you'd meet in real development:
| Planted situation | What it reveals |
|---|---|
| Random API errors | Error handling |
| Response delays | Loading states and UX design |
| Incomplete data | Data shaping and caching strategy |
| Dependent API calls | Async flow control and structure |
These aren't gotchas. They're signals for how flexibly someone handles real-world mess.
Why we auto-grade with E2E
We used to install, run, and check every submission by hand. It was slow, and every reviewer graded a little differently.
Goals for automation:
- A consistent grading baseline
- Fast pass/fail on minimum requirements
- Less repetitive checking → more time for actual code review
We split grading into two tiers:
| Tier | What it covers |
|---|---|
| Core requirements | Required features |
| Open-ended | UX improvements, error handling, optimization |
Less experienced candidates can still finish the core tier. Experienced candidates can show what they've got in the open-ended tier. The E2E suite grades the two tiers separately.
Mock API instead of a local server
We considered shipping a real server candidates would run locally, but chose a mock API instead:
- No setup tax. No env config, database, or auth just to start building UI.
- A simple, stable response model. We define exactly the fields the frontend needs.
- A small project. No server to maintain means a faster start and less upkeep.
"Build fast, verify fast" — a mock API fit that best.
Making failure reproducible with MSW
Real services always have a success path and a failure path. Against a real API, failure cases are surprisingly hard to reproduce on demand.
So we built the MSW (Mock Service Worker) handlers to read environment variables:
ERROR_RATE=10
DELAY_TIME=300
With that, a share of requests fail on purpose and every response gets artificial latency. In E2E runs and QA we can test realistic scenarios like "10% failure rate" and "300 ms network delay," and check exactly how the UI reacts when things go wrong.
The grading pipeline
Candidate PR → Docker build → E2E run → JSON report → Grade
- The candidate opens a PR against the grading branch.
- CI builds and boots the app in Docker.
- Playwright runs the suite at desktop and mobile viewports in parallel.
- Results are saved as a JSON report.
- The report is parsed into a grading summary and stored as a CI artifact.
Reviewers just open the branch to see the grade — no local setup required.
Recap
What we gained
- Noticeably faster candidate screening
- Interviews refocused on code review and technical conversation
- Candidate feedback along the lines of "it felt like I was briefly part of the team"
What's next
- Browser performance logging
- Automated screenshot comparison in E2E
We still value the process of solving a problem over a perfect answer. A hiring assignment shouldn't just be an evaluation; it should be time for both sides to get to know each other.
I'm Henry, a frontend engineer focused on React, Next.js, TypeScript and Playwright E2E testing. This post is adapted from a write-up I originally published in Korean. I'm open to frontend roles abroad — let's connect on LinkedIn or see my work on GitHub.

Top comments (0)