0
0
Cypresstesting~15 mins

Asserting request properties in Cypress - Deep Dive

Choose your learning style9 modes available
Overview - Asserting request properties
What is it?
Asserting request properties means checking that the details of a network request made by your web app are correct during testing. This includes verifying the URL, method, headers, body, and response. It helps ensure your app talks to servers as expected. This is done automatically in tests using Cypress, a tool for web testing.
Why it matters
Without asserting request properties, bugs in how your app communicates with servers can go unnoticed. This can cause wrong data to be sent or received, leading to broken features or security issues. By checking requests, you catch problems early, saving time and improving user experience.
Where it fits
Before this, you should understand basic Cypress test writing and how web requests work. After learning this, you can explore advanced network stubbing, response mocking, and performance testing in Cypress.
Mental Model
Core Idea
Asserting request properties is like checking the details on a letter before sending it to make sure it has the right address, content, and postage.
Think of it like...
Imagine mailing a letter: you check the envelope to confirm the address, stamp, and message inside are correct before sending it. Similarly, asserting request properties checks the request details before trusting the app's behavior.
┌─────────────────────────────┐
│       Test triggers action  │
└─────────────┬───────────────┘
              │
              ▼
┌─────────────────────────────┐
│  Network request is sent     │
│  (URL, method, headers, body)│
└─────────────┬───────────────┘
              │
              ▼
┌─────────────────────────────┐
│  Cypress captures request    │
│  and asserts properties      │
└─────────────┬───────────────┘
              │
              ▼
┌─────────────────────────────┐
│  Test passes if assertions   │
│  match expected values       │
└─────────────────────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding network requests basics
🤔
Concept: Learn what a network request is and its main parts like URL, method, headers, and body.
When your web app talks to a server, it sends a network request. This request has a URL (where it goes), a method (like GET or POST), headers (extra info), and sometimes a body (data sent). Understanding these parts helps you know what to check in tests.
Result
You can identify the key parts of any network request your app makes.
Knowing the parts of a request is essential before you can check if they are correct in tests.
2
FoundationBasics of Cypress network interception
🤔
Concept: Learn how Cypress can listen to network requests your app makes during tests.
Cypress can watch network requests using cy.intercept(). You tell Cypress what requests to watch by URL or method. Then, you can wait for these requests and check their details.
Result
You can capture network requests in your test code.
Capturing requests is the first step to checking their properties automatically.
3
IntermediateAsserting request URL and method
🤔Before reading on: do you think you can check both URL and method in one assertion or need separate ones? Commit to your answer.
Concept: Learn to check that the request goes to the right URL and uses the correct HTTP method.
Use cy.intercept() with an alias, then cy.wait() for that alias. The intercepted request object has properties like request.url and request.method. Use expect() assertions to check these. Example: cy.intercept('POST', '/api/login').as('loginRequest') // trigger login action cy.wait('@loginRequest').then(({ request }) => { expect(request.url).to.include('/api/login') expect(request.method).to.equal('POST') })
Result
Test passes only if the request URL contains '/api/login' and method is POST.
Checking URL and method ensures your app calls the right server endpoint with the correct action.
4
IntermediateChecking request headers and body content
🤔Before reading on: do you think headers and body are always present in every request? Commit to your answer.
Concept: Learn to assert that request headers and body data match expected values.
Headers carry extra info like content type or authorization. The body contains data sent, often JSON. Example: cy.intercept('POST', '/api/login').as('loginRequest') // trigger login cy.wait('@loginRequest').then(({ request }) => { expect(request.headers).to.have.property('content-type', 'application/json') expect(request.body).to.deep.equal({ username: 'user1', password: 'pass123' }) })
Result
Test passes only if headers and body exactly match expected values.
Verifying headers and body prevents bugs like sending wrong data or missing authentication.
5
AdvancedAsserting response properties and status codes
🤔Before reading on: do you think asserting request properties includes checking server responses? Commit to your answer.
Concept: Learn to check the server's response to your request, including status code and body.
After intercepting a request, you can also check the response. Example: cy.intercept('POST', '/api/login').as('loginRequest') // trigger login cy.wait('@loginRequest').then(({ response }) => { expect(response.statusCode).to.equal(200) expect(response.body).to.have.property('token') })
Result
Test passes only if server responds with status 200 and includes a token.
Checking responses ensures the server behaves as expected, not just the request.
6
ExpertHandling dynamic request properties in assertions
🤔Before reading on: do you think you should assert exact values for all request properties even if some change each time? Commit to your answer.
Concept: Learn strategies to assert requests when some properties vary, like timestamps or tokens.
Some request parts change every time (like IDs or timestamps). Use partial matching or custom checks. Example: cy.wait('@loginRequest').then(({ request }) => { expect(request.body).to.include.keys('username') expect(request.body.timestamp).to.be.a('string') }) Or use regex or custom functions to check dynamic values without failing tests.
Result
Tests pass reliably even when some request data changes each run.
Knowing how to handle dynamic data prevents flaky tests and false failures.
Under the Hood
Cypress uses the browser's network layer to intercept HTTP requests and responses. When cy.intercept() is called, Cypress hooks into the browser's fetch and XMLHttpRequest APIs. It captures request details before sending and response details after receiving. This allows Cypress to expose these details to test code for assertions.
Why designed this way?
Intercepting requests at the browser level allows Cypress to observe real app behavior without modifying app code. This design avoids false positives from mocks and lets tests verify actual network traffic. Alternatives like server-side proxies were more complex and less reliable.
┌───────────────┐
│  Test code    │
│  calls cy.intercept() ──────┐
└───────┬───────┘             │
        │                     ▼
┌───────▼────────┐    ┌───────────────────┐
│ Browser network│────│  App sends request│
│ layer hooks    │    └───────────────────┘
└───────┬────────┘             │
        │                     ▼
┌───────▼────────┐    ┌───────────────────┐
│ Cypress captures│────│ Server responds   │
│ request & resp │    └───────────────────┘
└───────┬────────┘             │
        │                     ▼
┌───────▼────────┐
│ Test code gets │
│ request & resp │
│ details for    │
│ assertions     │
└────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does asserting a request URL guarantee the request body is correct? Commit to yes or no.
Common Belief:If the request URL is correct, the whole request must be correct.
Tap to reveal reality
Reality:The URL can be right but the body or headers might be wrong or missing.
Why it matters:Relying only on URL checks can miss bugs where wrong data is sent, causing failures in backend processing.
Quick: Can you assert request properties without intercepting the request first? Commit to yes or no.
Common Belief:You can check request details anytime without setting up interception.
Tap to reveal reality
Reality:You must intercept the request with cy.intercept() to capture its details for assertions.
Why it matters:Trying to assert without interception leads to tests that never see the request, causing false passes or errors.
Quick: Do request properties always stay the same between test runs? Commit to yes or no.
Common Belief:Request properties are always fixed and predictable in tests.
Tap to reveal reality
Reality:Some properties like tokens or timestamps change each run and need flexible assertions.
Why it matters:Failing to handle dynamic data causes flaky tests that fail unpredictably.
Quick: Does asserting response status code guarantee the request was sent correctly? Commit to yes or no.
Common Belief:If the response status is good, the request must have been correct.
Tap to reveal reality
Reality:A good response can come even if the request had unexpected data, due to server defaults or errors.
Why it matters:Only checking response status can miss subtle request bugs that cause wrong app behavior.
Expert Zone
1
Cypress intercepts requests asynchronously, so timing your assertions with cy.wait() is crucial to avoid race conditions.
2
Headers can be case-insensitive and sometimes normalized by browsers, so exact string matches may fail; use flexible checks.
3
When multiple requests match an intercept, Cypress returns the first by default; use unique aliases or filters to target the right one.
When NOT to use
Asserting request properties is less useful when testing purely UI behavior without network calls or when using full API mocks. In those cases, focus on UI state or mock responses instead.
Production Patterns
In real projects, teams use request assertions to verify critical API calls during login, payments, or data submission. They combine assertions with stubbing to isolate tests and catch regressions early.
Connections
API Contract Testing
Builds-on
Asserting request properties in Cypress helps verify that the app respects the API contract, ensuring frontend and backend agree on data formats and endpoints.
HTTP Protocol
Same pattern
Understanding HTTP methods, headers, and status codes is essential to correctly assert request properties and interpret server responses.
Quality Control in Manufacturing
Analogous process
Just like inspecting parts on a production line to ensure they meet specifications, asserting request properties inspects network calls to ensure they meet expected standards.
Common Pitfalls
#1Failing to wait for the intercepted request before asserting.
Wrong approach:cy.intercept('GET', '/api/data').as('getData') // trigger action expect(cy.get('@getData')).to.exist
Correct approach:cy.intercept('GET', '/api/data').as('getData') // trigger action cy.wait('@getData').then(({ request }) => { expect(request.url).to.include('/api/data') })
Root cause:Not using cy.wait() means assertions run before the request happens, causing false failures.
#2Asserting exact request body when it contains dynamic values.
Wrong approach:expect(request.body).to.deep.equal({ user: 'abc', timestamp: '2023-06-01T12:00:00Z' })
Correct approach:expect(request.body).to.include({ user: 'abc' }) expect(request.body.timestamp).to.be.a('string')
Root cause:Trying to match dynamic data exactly causes flaky tests that fail when values change.
#3Checking request headers with wrong casing.
Wrong approach:expect(request.headers['Content-Type']).to.equal('application/json')
Correct approach:expect(request.headers['content-type']).to.equal('application/json')
Root cause:HTTP headers are case-insensitive but JavaScript object keys are case-sensitive, causing mismatches.
Key Takeaways
Asserting request properties means checking the details of network calls your app makes during tests to ensure correctness.
Cypress intercepts requests at the browser level, letting you capture and assert URL, method, headers, body, and response.
Proper timing with cy.wait() and handling dynamic data are key to reliable assertions.
Ignoring request assertions risks missing bugs in how your app communicates with servers, leading to broken features.
Expert use includes flexible matching, understanding HTTP details, and combining assertions with stubbing for robust tests.