Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Principle:Microsoft Playwright Verify Network Interactions

From Leeroopedia
Knowledge Sources
Domains Network_Testing, Mocking, API_Verification
Last Updated 2026-02-11 00:00 GMT

Overview

Waiting for and asserting on specific network requests and responses to verify API integrations and request correctness.

Description

After setting up network mocks and running user interactions, tests need to verify that the application made the correct network requests with the expected parameters and handled responses appropriately. This final step in the network mocking workflow closes the feedback loop: mocks provide controlled inputs, and verification confirms the application produced the expected outputs (both UI changes and outgoing network calls).

Verify Network Interactions encompasses two complementary capabilities:

Waiting for network events: Asynchronous operations in web applications mean that network requests often happen after user interactions, with unpredictable timing. Tests must be able to wait for specific requests or responses before making assertions, avoiding flaky timing-dependent checks. The wait operation should support URL matching (string, regex, or predicate function) and timeout configuration.

Asserting on network data: Once a request or response is captured, the test inspects its properties to verify correctness. Common assertions include:

  • Request assertions: Verify the correct URL, HTTP method, headers (e.g., authentication tokens), and request body (e.g., form data or JSON payload) were sent.
  • Response assertions: Verify the status code, response headers, and response body match expectations.
  • Request ordering: Verify that requests were made in the expected sequence.
  • Request counting: Verify that a specific endpoint was called the expected number of times.

This principle extends beyond simple response checking. It verifies the contract between frontend and backend: the frontend sends the right requests with the right parameters, and the backend (or mock) responds with the right data.

This principle is library-agnostic. Every test framework that supports network observation needs mechanisms to synchronize with asynchronous network events and assert on their properties.

Usage

Apply this principle when:

  • You need to verify that a form submission sends the correct POST body to the API.
  • You want to confirm that clicking a button triggers the expected API call.
  • You need to assert that authentication headers are present on API requests.
  • You want to verify that the application handles API error responses correctly by checking both the network response and the resulting UI state.
  • You need to wait for a specific API response before asserting on the page content it populates.
  • You want to verify that the application makes the correct sequence of API calls during a workflow.

Theoretical Basis

Network interaction verification combines the observer pattern with synchronization primitives:

VERIFICATION WORKFLOW:
  1. Set up mocks (route handlers, HAR fixtures)
  2. Perform user action (click, type, navigate)
  3. WAIT for expected network event
     -> URL match + timeout guard
     -> Returns Request or Response object
  4. ASSERT on captured network data
     -> Check URL, method, headers, body
     -> Compare against expected values
  5. ASSERT on UI state (populated by the response)

The waiting mechanism uses an event waiter pattern:

waitForRequest(urlOrPredicate, options):
  waiter = createEventWaiter("request")
  waiter.rejectOnTimeout(options.timeout)
  waiter.rejectOnPageCrash()
  waiter.rejectOnPageClose()

  for each emitted request:
    if urlOrPredicate matches request:
      return request

  // Throws on timeout, crash, or close

The predicate-based approach supports complex matching:

// Simple URL match
waitForRequest("https://api.example.com/users")

// Regex match
waitForRequest(/\/api\/users\/\d+/)

// Predicate function (most flexible)
waitForRequest(request =>
  request.url().includes("/api/users") &&
  request.method() === "POST" &&
  request.postDataJSON().name === "Alice"
)

The Promise.all pattern is essential for avoiding race conditions: the wait must be registered before the action that triggers the network event:

// CORRECT: Register wait before triggering action
[request] = await Promise.all([
  waitForRequest("/api/submit"),
  page.click("#submit-button")
])

// WRONG: Action might fire before wait is registered
await page.click("#submit-button")
request = await waitForRequest("/api/submit")  // Might miss it!

Related Pages

Implemented By

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment