We Built Our Own Frontend Take-Home Assignment — and Graded It with Playwright

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.

当团队设计前端居家测试题时,第一个想法通常是 CRUD 应用。我们决定更进一步。本文介绍了我们为何将测试题设计为真实工作的模拟,而非纯粹的实现任务,以及我们在为其构建端到端(E2E)自动评分流水线中学到的经验。

“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.

“CRUD 还不够吗?”我们的评估标准从一开始就很明确:将数据转化为 UI——候选人如何将复杂的数据结构呈现为可用的界面;处理异常路径——在网络延迟和 API 故障下保持一致的用户体验;为协作者编写代码——清晰的命名、合理的注释、一致的模式;可持续的架构——能够适应需求变化的结构。普通的 CRUD 应用无法真正体现这些。因此,我们设定了一个不同的目标:让候选人体验他们在我们团队中实际会遇到的问题。这对双方都有利。候选人可以看到我们在这里是如何解决问题的,我们也可以看到他们加入后会如何解决问题。这比单纯的实现速度更能体现态度和结构化思维。

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.

设计真实工作模拟:我们从生产服务中提取了 UI、API 和逻辑,并重建了一个简化版本。这不是模型,而是前端工程师每周都会遇到的情况的压缩集合:列表和条件渲染;数据缓存和转换;缓慢且失败的 API 响应;响应式 UI 和状态管理;带有验证的多步骤表单;需求中隐藏的陷阱。

🧩 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.

🧩 一个只要求实现功能的任务既无聊也学不到东西。因此,我们特意植入了你在实际开发中会遇到的情况: 植入情况 | 揭示的内容 随机 API 错误 | 错误处理 响应延迟 | 加载状态和用户体验设计 不完整数据 | 数据整形和缓存策略 依赖 API 调用 | 异步流程控制和结构 这些不是陷阱,而是衡量一个人处理现实世界混乱情况灵活性的信号。

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.

为什么我们使用 E2E 进行自动评分:我们过去习惯手动安装、运行和检查每一份提交。这很慢,而且每位评审员的评分标准略有不同。自动化的目标:一致的评分基准;对最低要求的快速通过/失败判断;减少重复检查 → 腾出更多时间进行实际的代码审查。我们将评分分为两个层级: 层级 | 涵盖内容 核心要求 | 必需功能 开放式 | 用户体验改进、错误处理、优化 经验较少的候选人仍然可以完成核心层级。经验丰富的候选人可以在开放式层级中展示他们的能力。E2E 套件分别对这两个层级进行评分。

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.

使用 Mock API 代替本地服务器:我们曾考虑提供一个候选人可以在本地运行的真实服务器,但最终选择了 Mock API:没有设置成本。无需环境配置、数据库或身份验证即可开始构建 UI。一个简单、稳定的响应模型。我们精确定义了前端所需的字段。一个小项目。无需维护服务器意味着更快的启动和更少的维护。“快速构建,快速验证”——Mock API 最符合这一点。

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.

利用 MSW 使故障可重现:真实服务总是有成功路径和失败路径。面对真实 API 时,故障案例出奇地难以按需重现。因此,我们构建了 MSW(Mock Service Worker)处理程序来读取环境变量:ERROR_RATE=10,DELAY_TIME=300。这样,一部分请求会故意失败,且每个响应都会产生人为延迟。在 E2E 运行和质量保证中,我们可以测试诸如“10% 失败率”和“300 毫秒网络延迟”等真实场景,并准确检查 UI 在出错时的反应。

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.

评分流水线:候选人 PR → Docker 构建 → E2E 运行 → JSON 报告 → 评分。候选人针对评分分支提交 PR。CI 在 Docker 中构建并启动应用。Playwright 并行在桌面和移动视口运行测试套件。结果保存为 JSON 报告。报告被解析为评分摘要并存储为 CI 工件。评审员只需打开分支即可查看分数——无需本地设置。

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.

总结:我们获得了什么:显著加快了候选人筛选速度;面试重新聚焦于代码审查和技术交流;候选人反馈称“感觉自己短暂地成为了团队的一员”。下一步:浏览器性能日志记录;E2E 中的自动截图对比。我们仍然认为解决问题的过程比完美的答案更重要。招聘测试不应仅仅是一次评估;它应该是双方互相了解的时间。

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.

我是 Henry,一名专注于 React、Next.js、TypeScript 和 Playwright E2E 测试的前端工程师。这篇文章改编自我在韩语中最初发表的一篇文章。我愿意接受海外的前端职位——欢迎在 LinkedIn 上与我联系,或在 GitHub 上查看我的作品。