Categories
Playwright

API Testing using Playwright

I’m a big fan of being able to call APIs during e2e tests to set up data, verify things, do things and all that jazz.

Up until now I’ve been mixing in Supertest with Playwright to call APIs within tests, until now…

Playwright 1.16 includes the ability to call APIs both independently and using the page browser object (which sends the currently stored cookies for API requests).

I’ve updated my example TypeScript project to include these API calls directly using both page and request which looks like:

test('can POST a REST API and check response using approval style', async ({ request }) => {
    const response = await request.post('https://my-json-server.typicode.com/webdriverjsdemo/webdriverjsdemo.github.io/posts', { data: { title: 'Post 4' } })
    expect(response.status()).toBe(201)
    const body = await response.text()
    expect(body).toMatchSnapshot('post4.txt')
  })

  test('can POST a REST API and check response using assertion style (using page)', async ({ page }) => {
    const response = await page.request.post('https://my-json-server.typicode.com/webdriverjsdemo/webdriverjsdemo.github.io/posts', { data: { title: 'Post 4' } })
    expect(response.status()).toBe(201)
    const body = JSON.parse(await response.text())
    expect(body.id).toBe(4)
    expect(body.title).toBe('Post 4')
  })

It’s nice to be able to remove another dependency from my e2e tests and still allow calling APIs using a nice API and reusing the existing objects that Playwright provides. I am continually blown away by how Playwright continues getting more and more awesome 😎

3 replies on “API Testing using Playwright”

Have you checked out playwright? Besides the perf tests it can do everything you’ve asked for in your answer. You don’t need to launch a browser to do pure API testing using the ‘request’ object – and it runs in parallel locally and on CI for no cost or subscription required.

You are right that I haven’t tried to use Playwright for API testing the way you have, so I have that on my to-do list now.

I implemented Karate support for Playwright [1], and I thought that internally it will always spawn a browser. In your test where you have [page.request.post()] – as far as I know, it will internally spin up a browser instance because you can’t have a [page] without that. My guess is the light-weight-ness and parallel-friendly-ness you are seeing is because Playwright defaults to headless mode.

But yes I agree that Playwright is a lot better than Cypress. What I’m not qualified to comment on is what exactly that non-browser [request] object is. My guess is that it is merely a wrapper over the Node http request object [2], in which case do you really need Cypress ? The API may be nice, but can you really do deep assertions on JSON payloads ?

[1] https://twitter.com/ptrthomas/status/1307678474627244032
[2] https://nodejs.org/en/knowledge/HTTP/clients/how-to-create-a-HTTP-request/

Leave a Reply

Your email address will not be published. Required fields are marked *