Mocking tRPC call w/ Playwright (Transform Error)

MTMatt Thompson4/26/2023
I have a tRPC call that I would like to mock out for a Playwright E2E test.
I've followed their docs as shown below and used the same transformer (superjson) from our tRPC setup.

When inspected via network tab the Call seems to succeed as expected. (image)
However, the client errors w/

TRPCClientError: Unable to transform response from server
    at transformResult (transformResult-6fb67924.mjs:74:1)
    at eval (httpBatchLink.mjs:188:56)


https://playwright.dev/docs/mock#mock-api-requests
    import { transformer } from '@/utils/trpc';
    ... 
    await page.route('**/api/trpc/onboarding.verifyPrimaryPractice?batch=1', (route) => {
      route.fulfill({
        status: 200,
        body: transformer.stringify({ success: true }),
        headers: { 'Content-Type': 'application/json' },
      });
    });
Nnlucas4/26/2023
Are you writing code to interact with the API directly?
Nnlucas4/26/2023
Maybe best to use the tRPC Client for this? https://trpc.io/docs/client/introduction
Nnlucas4/26/2023
OH sorry, I see you're intercepting and stubbing it out?
Nnlucas4/26/2023
Not familiar with playwright
Nnlucas4/26/2023
We would generally recommend you bring your API under test with tRPC. It's easier to stub out external services and control DB state than to replace the API, and makes for more representative e2e tests
Nnlucas4/26/2023
If you're really keen on it though, it looks like your approach is on the right track
MTMatt Thompson4/26/2023
Correct, we are using trpc client below on the form submit.
I'm trying to stub that call out.

Outside of the transform piece - it seems to be working as expected.
I'm just unsure why the transform fails.

  const verifyPractice = trpc.onboarding.verifyPrimaryPractice.useMutation({
    onSuccess: () => {...}
    onError: () => {...}
  })

  ... 

  const handleOnSubmit = async (data) => await verifyPractice.mutateAsync(data);
Nnlucas4/26/2023
You have batching enabled on the client (batch=1), but it looks like your transformed response is in the unbatched response form
Nnlucas4/26/2023
2 recommendations:

1. return your response in an array like you'll see when you run your app for real
2. don't match the whole URL, just match the onboarding.verifyPrimaryPractice bit, as a batched up call will have several paths comma separated and an encoded array of inputs to send to each one respectively - shouldn't be too hard to parse the inputs and respond in the correct form
Nnlucas4/26/2023
Probably will save pain all round if you just disable batching during testing though. I bet responding to a batched request with 2 calls in would be a PITA
MTMatt Thompson4/26/2023
Looking at the above.
Do you mind expanding on this a bit?

" We would generally recommend you bring your API under test with tRPC.
Nnlucas4/26/2023
Run the API for real
Nnlucas4/26/2023
Emulate any 3rd party services, run local DBs with real/mock data in.
MTMatt Thompson4/26/2023
Ah, Yea
For the most part we are doing that with Factories, etc.

This call has a 3rd party call where I don't have a Sandbox to run against.

I was originally looking for the equiv of Jest.mock in Playwright E2E
The closest thing they support is Network mocking
Sadly the 3rd party call couldn't be mocked in this scenario as the tRPC call is calling it within

Fun edge case I guess.

I'm looking at the real result like you mentioned above and trying to mock the array.
I didn't take that into account earlier. 🤞
MTMatt Thompson4/26/2023
Worked 🙂

End Result for me:
    await page.route('**/api/trpc/onboarding.verifyPrimaryPractice?batch=1', (route) => {
      route.fulfill({
        status: 200,
        body: JSON.stringify([
          { result: { data: { json: { success: true } }, meta: { values: {} } } },
        ]),
        headers: { 'Content-Type': 'application/json' },
      });
    });


In this case I don't really care about the return - I simply want it to keep going
But you could mock out the full return under data.json here.

The way the tests run, I shouldn't have more than one for batch
MTMatt Thompson4/26/2023
Thanks for the 👀 and help @Nick Lucas