mswjs / source

Generate MSW request handlers from various sources (HAR files, OpenAPI documents, etc).
https://source.mswjs.io
134 stars 5 forks source link

Generate handlers from runtime #21

Closed kettanaito closed 1 year ago

kettanaito commented 2 years ago

We should also support generating request handlers from runtime. I'm referring to Node.js runtime, as browser runtime has a built-in recorder to convert traffic to HAR. In Node.js, however, there's no such tool.

Use case

The primary use case would be the adoption of MSW in new codebases with a lot of existing tests. Developers have expressed multiple times that it'd be great to run all tests, see what requests are made, and generate handlers from that. They often refer to an actual JavaScript module being emitted as the result of this generation, which I'm skeptical about.

Skepticism about using JS modules as artifacts

I understand the intention of running a command and getting a ready-to-use module for your testing setup. However, I find that unreliable and flaky due to the maintenance considerations.

Codebases change and evolve, and so do tests. If you follow the command -> module pattern, you will be tempted to update the generated handlers.js module whenever your tests start making new requests (nobody's stopping you from that, so that's more than likely to happen). However, I doubt that the raw generated handlers are applicable to your tests straight away. I think most people would want to use the generated module _as the starting point, adding and removing logic, customizing URLs, doing anything, really—it's their module now. The thing is, running the command again will destroy all the custom changes, making developers either perform them again (tedious) or automate this process (unnecessary and unpredictable automation).

Alternative

There's a different approach we may take. In the end, what developers want is the way to flush all requests that are happening and generate handlers for them. I suggest we use HAR as the intermediate step.

HAR is standard

We don't have to implement our own data structures to describe HTTP transactions. We've got HAR! It's a time-proven format that can describe any network traffic.

HAR support

This library already supports f (har) -> handler[], which makes the task at hand scoped to generating HAR from Node.js runtime.

Versatility

I always prefer versatile, standalone solutions. Listening to traffic in a Node.js process and turning that traffic into a snapshot.har file sounds useful even outside of this library's context.

Implementation

We can use @mswjs/interceptors to spy on outgoing traffic in a Node.js process (already supported). What we'd have to design is the storage for that traffic.

Although HAR is great, I think storing transactions in that format straight away may be troublesome. There may be a more flexible way to record transactions and then map them to HAR.

weyert commented 2 years ago

Personally, I think, I would mark this as low priority as someone could use something like Proxyman to export a .har file, and Playwright also also allows to write .har files. If someone already has Playwright (or Cypress) they would be able to export .har files

kettanaito commented 2 years ago

@weyert, I somewhat agree. This feature is mainly designed for Node.js environments. For example, when adopting MSW in a large test base in Jest. You can't export traffic from Node to HAR because there's no standard API to observe the traffic, to begin with.

kettanaito commented 1 year ago

I think instead of making this a separate feature, we should instead provide the means to collect a process's runtime network into a HAR file and then use the existing fromTraffic to reduce friction.

That runtime -> HAR file generation can be a separate library the user should install if they wish to flush their Node.js process network into a network archive. Reducing the source of truth for the network to the common denominator, that being a HAR file, is the way to go.

I will close this for that very reason.