lecture 4 of 150 completed

Talking to the API directly

cy.request skips the browser entirely. It makes setup fast, and it lets you check the server without a screen.

Your delete test needs a contact to exist. Creating it through the form takes eight seconds: load the page, open the dialog, fill four fields, save, wait for the toast.

Multiply that by forty tests and your suite spends most of its life filling in forms it is not testing.

cy.request sends an HTTP request straight to the server, with no browser involved:

cy.request('POST', '/api/contacts', {
  name: 'Dana Fox',
  company: 'FoxLabs',
});

That runs in a few hundred milliseconds. No page load, no typing, no waiting for the screen.

Two very different uses. Keep them apart in your head.

Use one: fast setup. The contact exists so you can test deleting it. Creating it is the Arrange step, and the Arrange step should never be slow or fragile:

beforeEach(() => {
  cy.request('POST', '/api/contacts', { name: 'Dana Fox', company: 'FoxLabs' })
    .its('body.id')
    .as('contactId');
  cy.visit('/contacts');
});

.its('body.id') pulls one value out of the response, and .as('contactId') saves it under a name you can use later with cy.get('@contactId').

Use two: testing the API itself. Here the request is the thing under test:

cy.request({
  method: 'POST',
  url: '/api/contacts',
  body: { name: '' },
  failOnStatusCode: false,
}).then((response) => {
  expect(response.status).to.equal(400);
  expect(response.body.error).to.contain('name is required');
});

Note failOnStatusCode: false. By default Cypress fails the test when a request returns an error status, which is what you want for setup and exactly wrong when the error is what you are checking.

Three things people get wrong.

cy.request is not cy.intercept. cy.request makes a new request from your test. cy.intercept watches or changes the requests the app makes. Different jobs, and interviewers like the distinction.

cy.request does not go through your app's login. It sends cookies the browser already holds, so if you logged in through the UI first, the session usually carries over. If not, you may need to send an auth token yourself.

Do not verify only through the API. If your test creates a contact by API and then checks it by API, you have tested the server twice and the app not at all. Create by API, verify on the screen.

Remember this: arrange through the API because it is fast, and assert through the screen because that is what your user sees.

Reference: cy.request.