Build a small, reliable end-to-end test suite against a real public product: GitHub.
The objective is not to cover the entire product. The objective is to show sound engineering judgment in how you structure tests, create state, interact with the UI, and verify persisted behavior.
| Surface | URL |
|---|---|
| UI | https://github.com |
| API | https://api.github.com |
| API docs | https://docs.github.com/en/rest/issues/issues |
Implement a GitHub issue lifecycle flow.
Expected deliverables:
helpers/github/helpers.jstests/github/issues_.spec.jstests/github/issues_comments_.spec.js
1. after creating an issue via UI, it should be visible in the UI
- Create a unique issue through the GitHub UI.
- Assert it appears in the repository issues list via the API.
2. after creating an issue via API, edit it and assert via API
- Create a unique issue via the API.
- Open the issue in the UI and edit the title and body.
- Assert the updated title and body via the API.
3. after creating an issue via API, close it and assert via API
- Create a unique issue via the API.
- Open the issue in the UI and close it.
- Assert the issue state is
closedvia the API.
Apply the same test structure pattern to GitHub issue comments. The spec file contains a hint. Figure out the right flows from there.
Clone or fork this repository first. Then set up your own GitHub target before writing any tests.
You must create or provide:
- A temporary GitHub repository that you own and control.
- Issues enabled on that repository.
- A fine-grained personal access token scoped only to that repository with Issues read/write permissions.
- A copy of
.env.examplerenamed to.envwith your own values filled in. - Optionally, a Playwright
storageStatefile for your authenticated GitHub browser session.
Run npm run github:preflight before writing any test. If it fails, fix your setup first.
The solution will be reviewed by cloning your fork and running it with a different
.envpointing to a separate GitHub repository and a different GitHub account. If the tests only work with your specific token, your specific repo name, or any hardcoded value, the solution fails. Every credential and every repository reference must come exclusively from environment variables.
These constraints are intentional. Review will focus on whether you respected them.
- Use flat top-level
test()blocks only. - Do not use
describe(),beforeEach(), orafterEach(). - Do not introduce a Page Object Model.
- Put API logic in
helpers/github/helpers.js, not inline in spec files. - Pair every network-triggering UI action with
Promise.all([waitForResponse, action]). - Do not use
waitForTimeout(). - Prefer semantic locators such as
getByRole,getByLabel, andgetByPlaceholder. - Use API assertions as the primary correctness check.
- Do not spend time overengineering authentication if you can use a valid local storage state.
We are looking for clear priorities:
- State is created through the API where appropriate.
- UI is used for the user-critical behavior being tested.
- Assertions verify persisted backend state, not only visible text.
- Test data is unique and isolated.
- Failures are easy to debug.
- The implementation avoids brittle interaction patterns when a simpler one exists.
A strong candidate typically completes this exercise in 2 to 3 hours. This is provided as an orientating reference only — there is no deadline and no time constraint. Take the time you need to deliver a solution you are proud of.
Keep setup overhead bounded. The exercise is not intended to test GitHub administration depth beyond creating a temporary repo, a scoped token, and optionally a browser storage state.
Include a short note in your submission covering:
- Assumptions you made.
- Tradeoffs you chose.
- What you would improve with another hour.
Review will focus on:
- Test architecture and discipline.
- Async correctness and absence of race conditions.
- Locator quality.
- Separation of API helper logic from spec logic.
- Quality of assertions.
- Overall reliability and readability.
This exercise is intentionally scoped so a strong candidate can complete it in 2 to 3 hours using only:
- Issue creation through the GitHub API.
- Issue editing, commenting, and closing through the GitHub UI.
- Issue verification through GitHub issue and comment endpoints.
It does not require pull requests, projects, code review, Actions, or advanced GitHub administration.