Artem Zakharchenko
banner
kettanaito.com
Artem Zakharchenko
@kettanaito.com
Software engineer. Helping you master automated testing at http://EpicWeb.dev. Author mswjs.io. Instructor egghead.io.

I tell stories @zakarcher.com.

My debut book "LOGGERHEADS" it out 👇
https://zakarcher.com/books/loggerheads
First, don't require more than you need. It sounds obvious and yet I see this mistake everywhere. Accepting just want you need leads to versatile APIs as well as exercises your designer brain.
November 27, 2025 at 3:29 PM
I prefer an [error, data] over { error, data } for async operation results. Why? Because a tuple guarantees the order. Put the error first, which reminds the consumer to handle it. Object keys are order-insensitive and it's easy to forget to check for the "error" key.
November 27, 2025 at 2:37 PM
GitHub broke site references feature and, sadly, forgot about it. This "week" has been going on for some months now.
November 23, 2025 at 9:22 AM
Am I crazy in wanting browser end-to-end tests to look like this?

- Lists everything this test case needs (no magic).
- Per test resources as simple as calling a function.
- Easy client/server setup w/o changing your app.
November 18, 2025 at 4:22 PM
All the while, there's a times better approach: test-based authentication roles (or personas).

Keeps the test's dependencies in the test. Explicit. Introduces no shared state. Performant (reuses and invalidates previous sessions).

github.com/kettanaito/...
November 17, 2025 at 4:40 PM
I cannot be the only one thinking this is a bad way to test authentication-dependent code. This literally creates a dependency between tests. Non-deterministic and magical. Order-dependent. Something as flexible as authentication does not belong on the configuration level.
November 17, 2025 at 4:40 PM
Type testing is the area where I want as much type magic as possible. This is not a good error message. In fact, it's rather terrible. The "2 doesn't equal 2" kind of error experience.
November 14, 2025 at 11:20 AM
I've seen this question flying around: how do I send data from my SSE mock in response to some *other* action somewhere?

The answer: pubsub! And the simplest, built-in pubsub you have on the web is EventTarget:
November 13, 2025 at 3:30 PM
Always. Not when feasible, always.

Your test is a clean slate. It has to bring your system to the right state, interact with it, then check the end state. It must never rely on a state of irrelevant systems to work, even if it depends on those systems.
November 12, 2025 at 2:22 PM
Next, I have a fixture for my database client and a few utilities bound to that fixture. This way, I can seed my database with any records I need and all of them will be written to the database instance associated with the test case. Nothing else can access them.
November 12, 2025 at 1:38 PM
First, this test is COMPLETELY isolated. It runs its own app instance, it creates its own local database, and it tears it all down before running again.

I do that via the `app` fixture that the launcher package I built.
November 12, 2025 at 1:38 PM
This e2e test verifies a rather complex app flow: an existing user with their GitHub account connected. Do you notice how simple this test is? How you can read each step and say to yourself "yeah, sure, that makes sense".

Let's unwrap what makes it so.
November 12, 2025 at 1:38 PM
There is no reason developers shouldn't be able to do this. But they can't. This throws (an invisible SuppressedError with no stack trace, no less).
November 10, 2025 at 3:15 PM
What an absolutely goated release note from iA Writer. Love it.
November 7, 2025 at 10:56 PM
Here's the server-side API mocks. You should probably import the types from GitHub's API client but I'm not doing that in this exercise for simplicity. That also shows that you can annotate things that are missing yourself!
November 7, 2025 at 11:30 AM
Here's how I recommend testing third-party authentication flows. This is the one using GitHub OAuth.

- Server-side mocking with MSW.
- Act as your users do.
- Type-safe and runtime-safe via TypeScript and Zod.

November 7, 2025 at 11:29 AM
MSW plans for November just leaked 🤫
November 3, 2025 at 10:42 AM
Safari is the new IE, huh?
October 31, 2025 at 9:15 PM
This is silly but sometimes I want this syntax to exist in JavaScript.
October 29, 2025 at 9:29 PM
The fact that developers sat in a room and concluded this is an acceptable UI for PWAs. *Sighs*.
October 25, 2025 at 7:19 PM
Do you remember the Internet that looked like this?
October 24, 2025 at 9:14 PM
No, I don't think so. `setupWorker` is just a message channel that will give you request/response events. You resolve them on the client. If the aforementioned call signature of RSC is indeed request in, response out, you can do:
October 19, 2025 at 10:21 AM
TypeScript begs to differ.
October 14, 2025 at 12:28 PM
Wow so few of you actually knew you can type "this" in TypeScript and it's NOT an argument. I need to talk more about API design.
October 13, 2025 at 9:08 PM
Got a type testing question: why do these two examples produce two different type errors?

I'd like to assert the *first* error (about the symbol mismatch). I'm getting something else though once I use type expect.
October 10, 2025 at 4:30 PM