1

I am new to Playwright and js so I'm a bit lost here. I want to be able to send a request and then check status, content of response, headers, etc.

I thought I would be able to do something like

  test('blah', async ({ request }) => {
    await request.get('http://localhost:444').then(res => {
      expect(res.status()).toBe(200)
      expect(res.headers()['content-type']).toBe('application/octet-stream')
      expect(res.json()).toContain('foo')
    })
  })

but this doesn't work and the expect sees res.json() as "{}" and if I try to print the response to console with console.log(res.json()) I get back Promise { <pending> }

I eventually got my test working properly by using the below code but it seems messy to me and I dont know why I have to do this? am I doing this correctly? or am I way off?

test('blah', async ({ request }) => {
    await request.get('http://localhost:4444/')
      .then(res => {
        expect(res.status()).toBe(200)
        return res.json()
      })
      .then(json => {
        expect(JSON.stringify(json)).toContain('foo')
      })
  })
user1244808
  • 49
  • 1
  • 7
  • 1
    Since you're already using async await, why use then()? – Phix Mar 08 '22 at 17:11
  • 2
    You have to await the json resolution too `return (await res.json())` – Peterrabbit Mar 08 '22 at 17:16
  • Im an idiot basically, need to learn js a bit more. This worked, thanks for your help test('should allow me to addasd todo items', async ({ request }) => { const res = await request.get('http://localhost:1444'); expect(res.status()).toBe(200) expect(JSON.stringify(await newIssue.json())).toContain('foo') }) – user1244808 Mar 08 '22 at 21:37

2 Answers2

0

Try the following to refactor your solution into better readable and reusable code.

FYI - the response I was expecting contains an 'email' and a 'token' json fields (as shown in postman screenshot). I was able to verify the endpoint by asserting on the response body's email field.

const USER = 'andresdev@gmail.com';
const PWD = 'Test@1234';

test('validate that login endpoint works correctly', async ({ request }) => {

    // make request and get response
    const loginResponse = await request.post('/api/user/login', {
        data: {
            email: USER,
            password: PWD,
        }
    });

    // assert on response OK (HTTP 200)
    await expect(loginResponse.ok()).toBeTruthy();

    // get 'email' value from response's body data
    let responseEmail = await loginResponse.body().then(b => { 
        let data = JSON.parse(b.toString()); 
        return data.email;
    });

    // assert on email from response equal to email from request
    await expect(responseEmail).toEqual(USER);
});
0

I eventually got my test working properly by using the below code but it seems messy to me and I dont know why I have to do this? am I doing this correctly? or am I way off?

You can improve the code by not mixing await and then, asserting that the response content is JSON before attempting to parse it, and not re-stringifying the body after parsing, instead asserting on paths in the object.

I'm not sure where "foo" is within your response, which is part of the reason why the test is unclear, but you can adapt the following example to use the actual path to that key or value and make a specific assertion for it:

import {expect, test} from "@playwright/test"; // ^1.31.2

test("retrieves a comment", async ({request}) => {
  const url = "https://jsonplaceholder.typicode.com/comments/1";
  const response = await request.get(url);
  expect(response.status()).toBe(200);
  expect(response.headers()["content-type"]).toContain("application/json");
  const body = await response.json();
  expect(body.postId).toBe(1);
  expect(body.id).toBe(1);
  expect(body.name).toBe("id labore ex et quam laborum");
  expect(body.email).toBe("Eliseo@gardner.biz");
});
ggorlen
  • 44,755
  • 7
  • 76
  • 106