Skip to content

About

A web app with 200+ cases built to break the obvious end-to-end test, plus scored Playwright solutions and an AI-agent benchmark.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

e2e-casebook

CI

A small, realistic web app built to be tested end to end. Each case is a feature that is hard to test well, with a list of requirements. Write automated tests that check every requirement. Each case hides a detail that makes the obvious test miss a broken requirement.

Bring your own framework: Playwright, Cypress, WebdriverIO, or anything that drives a browser.

The e2e-casebook landing page

Live demo: https://e2e-proving-ground.onrender.com (free tier: if it has been idle, it takes about a minute to wake, and it starts empty after every wake).

Worked solutions: solutions/ has Playwright approaches to 12 cases, each scored against bugs planted in the app, plus a benchmark of AI agents writing tests for the same cases. The other cases stay unsolved.

Start here

200+ cases is a lot. These twelve show the range:

Case Why it is hard to test
1. Two-user realtime chat Two browsers, a dropped socket, and messages that must arrive once and in order.
3. Optimistic moves The screen changes before the server answers, and has to change back when it says no.
6. Due dates, time zones, and DST The bug only shows in some zones, on some dates.
24. Draft Autosave with retries, and a race you have to make happen.
38. Search Answers that arrive out of order.
72. Upload Progress, cancel, and a server that must keep nothing from a broken upload.
95. Local notes An IndexedDB upgrade while another tab holds the old version open.
104. Concert tickets A page restored from the back/forward cache, which fires no load.
111. Bus stop A service worker that has to work offline.
166. Kitchen timer One alarm, however many tabs are open.
172. Help desk A strict Content Security Policy that nothing may break.
194. Meeting rooms Three requests in a row, where each can fail on its own.

Cases

# Case What it is
1 Two-user realtime chat Open a sandbox, join with a name, and send messages.
2 Concurrent edit Two people open the same card on the board and both edit it.
3 Optimistic moves Cards move between columns at once, before the server answers.
4 Export job Export board as CSV starts a background job with progress.
5 Feature flag New cards are created with one of two variants: an inline form or a dialog.
6 Due dates, time zones, and DST Cards can have a due date.
7 A shared environment Card titles are unique within a sandbox, and the board shows how many cards it has.
8 Magic-link sign-in The Account page signs you in with a link sent by email.
9 A virtualized list The Activity page lists 10,000 entries, rendering only the rows in view and loading them in pages.
10 A toast and a page that is never idle Saving Settings shows "Settings saved" for 2 seconds.
11 Checkout total The Shop page sells three products.
12 Shipping insurance Checkout offers shipping insurance for 4.99 PLN, with no VAT on it.
13 Product reviews Each product has a reviews page, linked from the Shop.
14 Editing a review The browser that posted a review can edit it.
15 Splitting an order Under your orders, "Split order" opens a page that divides the order total between 2 and 8 people.
16 The People picker The split page chooses the number of people with a list built from ARIA roles, not a native select.
17 Cookie consent The Deals page asks for cookie consent before it shows deals picked for you.
18 Gift cards The Gift cards page sells gift cards.
19 Notes The Notes page lists notes you can star, archive, or delete.
20 Budget The Budget page keeps a list of expenses and charts them.
21 Your plan The Plan page shows your Pro plan, 49.00 PLN a month, with the next payment on 1 December 2026.
22 Playlist The Playlist page lists five songs in an order you can change.
23 Top up The Top up page adds money to a wallet.
24 Draft The Draft page holds one letter that saves itself.
25 Calendar The Calendar page connects a calendar from Example Calendar, a separate sign-in service.
26 Contacts The Contacts page imports contacts from a CSV file.
27 Stores The Stores page finds the three stores nearest to you.
28 Quote The Quote page multiplies a unit price by a quantity.
29 Booking The Booking page books a room in three steps: Dates, Guests, and Review.
30 Feed The Feed page lists posts, newest first.
31 Checklist The Checklist page keeps a list of items and keeps working when the connection drops.
32 Vault The Vault page keeps notes behind two-step verification with an authenticator app.
33 Basket The Basket page keeps a basket in the browser, without the server.
34 Support The Support page sends a message to support.
35 Receipt The Receipt page shows a shop receipt with an order number and the time it was printed (24-hour clock).
36 Sign up The Sign up page creates an account (nothing is stored).
37 Bio The Bio page has a small rich-text editor with Bold and Italic buttons (Ctrl+B and Ctrl+I work too) and Save.
38 Search The Search page finds products as you type.
39 Invoices The Invoices page lists two invoices with a Download PDF link each.
40 Price filter The Price filter page shows products between a lowest and a highest price, chosen with a slider that has two handles.
41 Reminders The Reminders page reminds you about something in 1, 5, 15 or 60 minutes.
42 Address The Address page edits your street, city and postcode.
43 Feedback The Feedback page sends a star rating and an optional comment.
44 Share The Share page shows an invite link with Copy link and New link buttons.
45 Updates The Updates page tells you when a new version of the app has been released while the page was open.
46 Inbox The Inbox page lists eight messages with a checkbox each.
47 Orders The Orders page shows orders ten at a time, sorted on the server.
48 Files The Files page lists five files.
49 Tasks The Tasks page is a small to-do list with keyboard shortcuts.
50 Itinerary The Itinerary page shows a three-day trip with a Print itinerary button.
51 Verify phone The Verify phone page texts a code (nothing is really sent).
52 Order summary The Order summary page can be shown in English or Arabic.
53 Shipping address The Shipping address page saves a country and a postcode, and a state for the United States.
54 Gallery The Gallery page shows 24 photos in two columns.
55 Holiday request The Holiday request page picks a first and a last day, on a calendar or in the From and To fields.
56 Stay signed in The Stay signed in page signs in [email protected] with the password correct horse.
57 Podcast The Podcast page plays a 30-second episode (a quiet tone) with its own controls.
58 Bakery The Bakery page has a site header with four links.
59 Session The Session page signs you out after 90 seconds without activity.
60 Team The Team page shows a Roadmap document and its members.
61 Meetings The Meetings page adds a meeting at a date and time, once or every week for 4 weeks.
62 Directory The Directory page lists 10,000 customers.
63 Confirm email The Confirm email page asks for a 6-digit code, one box per digit.
64 Messages The Messages page counts new messages in English or Polish.
65 Passkeys The Passkeys page creates passkeys for ann and signs in with them.
66 Delivery The Delivery page asks you to sign for a parcel.
67 Import The Import page imports 100 customers and shows the progress as it happens.
68 Packing list The Packing list page edits a list of things to pack.
69 Help centre The Help centre opens articles without reloading the page.
70 Order review The Order review page lists 12 items under a header that stays at the top, with a pay bar that stays at the bottom.
71 Sales report The Sales report page adds up 20,000,000 sales by region.
72 Upload The Upload page sends a file of up to 20 MB to the server.
73 Support ticket The Support ticket page takes a description and pasted screenshots.
74 Timesheet The Timesheet page is a grid of hours per day and project.
75 Shop reviews The Shop reviews page shows a reviews widget in a sandboxed frame.
76 Country The Country page is a list of 30 countries you can pick from with the keyboard.
77 Appearance The Appearance page lets you pick a theme and how much motion you see.
78 Statement The Statement page lists a month of transactions and downloads them as a CSV file.
79 Plans The Plans page compares three plans, each with an info button that shows a tooltip.
80 Price alerts The Price alerts page sends a browser notification when a product gets cheaper.
81 Live score The Live score page follows a match and stops asking the server while the tab is hidden.
82 Mobile inbox The Mobile inbox page deletes a message when you swipe it to the left, with an undo.
83 Change password The Change password page changes the account password and works with password managers.
84 Flash sale The Flash sale page counts down to the end of a sale by the shop's clock.
85 Class list The Class list page sorts and searches 15 pupils with Polish names.
86 Newsletter The Newsletter page marks an article as read once it has been on screen for 2 seconds.
87 Post editor The Post editor page writes and publishes a blog post in a panel that scrolls.
88 Announcements The Announcements page shows three banners you can dismiss.
89 Voice note The Voice note page records a voice note with the microphone and saves it.
90 Price list The Price list page checks for new prices and downloads the list only when it changed.
91 Contributors The Contributors page shows names on small cards, cutting the ones that do not fit.
92 Product details The Product details page shows four tabs of details about a hand grinder.
93 Files tree The Files tree page shows folders and files in a tree you can open and close.
94 Promotions The Promotions page shows a carousel of four offers that changes every 5 seconds.
95 Local notes The Local notes page keeps notes in the browser's database and updates it safely across tabs.
96 Letter The Letter page is a text box with its own Undo and Redo that work a word at a time.
97 Recipe The Recipe page shares a recipe with the device's share sheet, or copies its link.
98 Photos The Photos page shows five photos in a viewer that can go full screen.
99 Delivery details The Delivery details page is a form that reflows on narrow screens and with large text.
100 Hotels The Hotels page filters a hotel list in a sheet that covers the whole window.
101 Lamps The Lamps page shows product cards with Save and Compare buttons for mouse, keyboard and touch.
102 Mailing list The Mailing list page embeds a sign-up form that a separate script wires up after the page loads.
103 Trip tags The Trip tags page turns typed text into tags, also when the text comes from an input method.
104 Concert tickets The Concert tickets page sells tickets and must be up to date when the user returns with Back.
105 Privacy settings The Privacy settings page has a pop-up hint for each option and a confirmation after saving.
106 Train ticket The Train ticket page sells a ticket with optional extras over three steps.
107 Pancakes The Pancakes page scales a recipe by servings and works out how many servings your flour makes.
108 Photo album The Photo album page uploads a whole folder of photos, keeping its subfolders.
109 Floor plan The Floor plan page zooms a plan with a pinch, Ctrl and the mouse wheel, or buttons.
110 Reading list The Reading list page keeps the user signed in with a session stored in IndexedDB.
111 Bus stop The Bus stop page links to a departures board that keeps working offline.
112 Workspace The Workspace page opens on Setup or on the Dashboard, depending on the workspace's settings.
113 Saved searches The Saved searches page lists saved searches and shows an empty state when there are none.
114 Groceries The Groceries page adds products to a basket and announces each change to screen readers.
115 Event feedback The Event feedback page has a form whose star rating is a custom element.
116 Shop dashboard The Shop dashboard page has an orders widget that switches layout with its own width.
117 Highlights The Highlights page lets the reader save selected text from an article.
118 Sell your bike The Sell your bike page explains, to every user, why Publish is not available yet.
119 Expense claims The Expense claims page submits claims after you sign in, and lets you sign in again without losing a claim when the session ends.
120 Flats The Flats page lists flats to rent as cards that open the flat, with Save and Compare on each card.
121 Parking permit The Parking permit page takes payment through card fields in an embedded frame.
122 Shared drive The Shared drive page lists files with a custom right-click menu: Open, Duplicate and Delete.
123 Village hall The Village hall page lists questions whose answers open and close, and can still be found while closed.
124 Assistant The Assistant page has three conversations; answers arrive word by word, also while you read another conversation.
125 Comments The Comments page has a comment box that grows with its text, up to six lines.
126 Alert settings The Alert settings page has three on/off switches and a choice of summary email.
127 Choir sign-up The Choir sign-up page shows its form step by step on narrow screens and all at once on wide ones.
128 Shared photos The Shared photos page opens a photo on a tap and starts selecting photos when one is pressed and held.
129 Mail reader The Mail reader page shows a message list and a message side by side, divided by a bar you can drag.
130 Receipts The Receipts page attaches receipt files dragged from the computer onto it, or chosen with a button.
131 Guestbook The Guestbook is a plain HTML page with a form, served by the server and usable without JavaScript.
132 Concert poster The Concert poster page sizes the poster's headline so it fits on one line at any width.
133 Field notes The Field notes page keeps notes in the browser's storage as you type.
134 Club activity The Club activity page lists what happened in the club, with times such as "3 minutes ago".
135 Notice board The Notice board page lists office notices and counts the ones you have not read yet.
136 Prints The Prints page connects your CloudPix photo account through a pop-up window.
137 Study group The Study group page is a group chat that shows who is typing.
138 Billing details The Billing details page saves who invoices are made out to: a private person or a company.
139 Flight search The Flight search page finds flights, and copes when the search is slow.
140 Bank transfer The Bank transfer page sends money to an account number that is formatted as you type.
141 Library card The Library card page takes a date of birth typed by hand and works out your age.
142 Village fête The Village fête page links to a reply form that the server builds and a script improves.
143 Rooms The Rooms page shows a guest house's three rooms with photos sized for each screen.
144 Radio favourites The Radio favourites page lets you like songs, and keeps the saved likes in step with the screen.
145 Shift handover The Shift handover page sends a note for the next shift, where @ mentions people.
146 Ticket contact The Ticket contact page asks where to send tickets, and works with the browser's autofill.
147 Handbook The Handbook page has a menu of sections that open and close, usable with a keyboard and a screen reader.
148 Barber The Barber page books a haircut and holds the chosen time for 5 minutes.
149 Running order The Running order page lists 30 acts of a village show, in an order you change by dragging.
150 Site photos The Site photos page lists folders and photos in a table you sort by name, size or date.
151 Staff The Staff page opens an edit dialog that loads a person's details while you move around it.
152 Support answers The Support answers page filters help articles as you type and highlights the matches.
153 Tile order The Tile order page builds an order that belongs to one browser tab and survives a reload.
154 Shoe size The Shoe size page picks a size from a custom list that opens over its button.
155 Saved cards The Saved cards page asks before removing a card, in a question that fades out.
156 Stock take The Stock take page is a grid of counts you can fill by pasting cells from a spreadsheet.
157 Cookbook The Cookbook page opens dialogs over a long list that must stay put behind them.
158 Trail map The Trail map page opens from a service worker's saved copy and must update to a new version cleanly.
159 Phrasebook The Phrasebook page adds phrases with Enter, including ones typed with an input method (IME).
160 Replies The Replies page keeps an unsent reply per conversation in the browser, up to the last letter typed.
161 Payslips On the Payslips site, the browser's Back and Forward buttons must never show payslips to someone who signed out.
162 Newsroom The Newsroom page pages through stories with Load more, without repeats or gaps, and keeps your place when you come back from a story.
163 Members The Members area sends you to the page you asked for after signing in, but never off the site.
164 Prime counter The Prime counter page runs a count of several seconds that must not freeze the page, and can be cancelled or replaced.
165 Pay by bank The Pay by bank page sends you to a bank on another site, which sends you back with the result.
166 Kitchen timer The Kitchen timer is shared by all open tabs of the page and must ring exactly once when it ends.
167 Transcript The Transcript page has a link for every line, and each link must land on its line, under the page's sticky header.
168 Team chat The Team chat keeps you at the newest message as messages and photos arrive, unless you scrolled up to read.
169 Cinema The Cinema page reserves seats, and its buttons must work from the moment they appear, on any connection.
170 Parts search A search box that waits as long as the server asks after 429 Too Many Requests.
171 Staff guide A contents bar that marks the section you are reading and jumps to a section on click.
172 Help desk A page under a strict Content-Security-Policy with a chat whose code loads on the first click.
173 Video upload An upload in 1 MB parts that carries on where the server stopped, after a lost connection or a reload.
174 Chat history A conversation that loads older messages above when you scroll up, without moving what you read.
175 Close account A page that closes the account, shown in this app's own preview frame but never in another site's.
176 Shipments Parcels with long tracking numbers that must stay exact from the server to the screen and back.
177 Metronome A metronome with page-wide keys that keeps working the same however often you leave and come back.
178 Loyalty points Points read and spent through a partner API on another origin, straight from the browser.
179 Café dashboard Three tiles that fail one at a time: a broken tile says so, reports it, and leaves the others working.
180 Printer status A status that checks less and less often while the printer cannot be reached, and normally again once it can.
181 Holiday homes Cards that load a home's details as soon as the pointer or keyboard reaches them, counting a view only when it is opened.
182 Profile photo A photo turned and cut to a 256 × 256 square in the browser, then sent as a PNG.
183 Travel article An article whose photos and newsletter box arrive after the text, without moving it.
184 Paper boat A 12-second video with captions in English or Polish and a transcript that follows it.
185 Quick invoice An invoice form with many buttons, where Enter saves and no other button ever does.
186 Library catalogue A search kept in the page's address, so it survives a reload, a shared link and Back, whatever the text.
187 Team overview Three panels loaded at once with a short-lived token that is renewed once, quietly, when it runs out.
188 Region packs Map downloads with a progress bar that follows the bytes as they arrive, and a Cancel button.
189 Gym membership Renewal dates for a membership that starts late in the month, in any time zone.
190 Courier pickup A two-column booking form where the keyboard has to move in the order a person reads.
191 Recipe box A list and an editor side by side, with answers kept in a cache that has to forget the right things.
192 Travel wallet Balances in złoty, yen and Bahraini dinar, which have 2, 0 and 3 decimal places.
193 Weather A weather widget that asks the server once per change and once every ten minutes, and no more.
194 Meeting rooms Booking a room in three steps (book, send the invite, refresh the list) where a later step can fail on its own.
195 Shopping list A list where a new item can be ticked or removed before the server has given it an id.
196 Class timetable A month grid whose first weekday and weekend follow the visitor's language and region.
197 Guest invites A box for many email addresses at once, where real but unusual addresses must get through.
198 Shared files A list of shared file names, some of which use direction marks to hide what they are.
199 Exhibition Paintings that open in a dialog with its own address, where Back closes the dialog instead of leaving.
200 Appointment reminders An SMS reminder box that counts characters and messages the way phone networks do.
201 Parcel lockers Choosing a parcel locker from a list sorted by distance, where full lockers cannot be chosen.
202 Ferry tickets Ferry fares for adults and children with a family discount and a passenger limit.

Run it

docker compose up --build

Open http://localhost:3000 to browse the cases by topic, then start a sandbox. A sandbox is a private copy of the app; open its URL in a second window to be the second user.

Test hooks and API

Test hooks reset, seed and break a sandbox from a test. API lists the endpoints the pages use.

Stack

Node 24 or newer runs TypeScript directly; CI uses the newest Node release. Fastify serves the API, the WebSocket, and the React build from one process; data lives in an in-memory SQLite database, so a restart is a full reset. The client is React 19 with Vite and TanStack Query.

Develop

npm ci
npm run dev:server   # API on :3000 with test hooks
npm run dev:web      # Vite on :5173, proxies /api and /__test__
npm run typecheck
npm run test:unit
npm run build && npm run test:smoke   # opens every page in Chromium; axe scan of the shell

License

MIT. Made by bartech-lab.

About

A web app with 200+ cases built to break the obvious end-to-end test, plus scored Playwright solutions and an AI-agent benchmark.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages