Hi all,
I've been using Remix for almost a year now, and I love it! It makes building apps so much easier.
The only thing I still haven't figured out is how to mock external APIs in my E2E tests. Ideally I would love to find a solution that allows me to only intercept some of those requests and more importantly to use different responses, in order to test error cases or other cases that are hard to reproduce. I've tried with Cypress/Playwright and MSW, but with very little success.
Have you found a solution for this?
#Mocking external services in E2E tests
1 messages · Page 1 of 1 (latest)
If I'm not mistaken many people have had success with MSW and Remix?
@dreamy burrow @sharp bay defo knows more about this 👍
let me try finding a code sample
it should work
try MSW again, let us know the progress you're making!
Any specific issues you've faced? Remix + Cypress + MSW should work fine.
yeah it should
another example, but this one is missing the handlers only https://github.com/epicweb-dev/rocket-rental/blob/main/mocks/index.js
thanks for looking into this @lean musk !
❤️
@sharp bay my only issue is with one-time overrides, I never managed to do it
// this would go in a spec where I test what happens when there are no books, for example
server.use(
rest.get('/books', (req, res, ctx) => {
return res.once(ctx.json({ data: [] }))
})
)
Are they not applied?
no. My setup is very similar to this https://github.com/epicweb-dev/rocket-rental/blob/main/mocks/index.js
but importing the server in the cypress test to specify a one-time override doesn't seem to work
You don't need to import server in Cypress. You need to create a worker in your app, expose it on window, and access it in Cypress instead.
https://mswjs.io/docs/api/setup-worker/use This page illustrates how.
the requests I want to mock are in Remix's loader, so they happen server side. Don't I need msw/node for that?
I used to follow the example you linked when I was using create-react-app, and it was working perfectly, but I think with Remix it's different as the request to intercept doesn't start in the browser
@sharp bay am I right in thinking that the worker will only intercept requests executed client side?
Yes. You do use msw/node to mock requests from the loader but I don't think you can append runtime handlers as your tests and Remix don't share runtime
So they don't share a server instance you could do server.use() on
So using playwright has working well for me - what sort of issues did you run into with playwright?
I haven't found a way to mock external services and specify one-time overrides within individual tests.
For example if I use an API to retrieve a list of books, I'd like to test what happens when the response:
1 - contains 100 books
2 - contains 0 books
3 - contains an error
I'm surprised if this is not a very common use case when writing tests
So for testing the actual logic of the loaders, you can use normal unit tests (https://sergiodxa.com/articles/test-remix-loaders-and-actions)
You can then use playwright to mock different responses from your loader, including errors, etc (https://playwright.dev/docs/network#modify-requests)
Sergio Xalambrí
If you are using Remix, most of your application code will live in the loaders and actions instead of React compo...
Playwright provides APIs to monitor and modify network traffic, both HTTP and HTTPS. Any requests that page does, including XHRs and fetch requests, can be tracked, modified and handled.
thanks Itxchh, I'll try your suggestions
Gl 🙂
@halcyon steppe did you manager to mock api request using playwright?
stackblitz just released their webcontainers for public use, might also provide a way to to this? https://webcontainers.io/