Browser testing in Postman Agent Mode

Browser testing in Postman Agent Mode

Talia Kohan

UI tests and API tests usually live in separate worlds. The frontend team writes Playwright specs, the API team writes Postman Collections, and the two drift apart over time. Tests stay green, contracts silently break, and the first time anyone notices is when a user files a bug.

Postman just shipped a built-in web browser as a tool inside Postman Agent Mode. Combined with the Postman Playwright integration we announced earlier this year, you can now ask Agent Mode to drive your app in a real browser, record the network traffic, and generate UI tests and API tests against the same observed behavior — then run them together in a single command that fits into CI.

In this post, I’ll walk through that workflow end-to-end: kicking off a browser session in Agent Mode, getting Playwright and Postman Collection tests out the other side, and wiring the whole thing into Application Inventory so the results show up in your team’s dashboard.

Why one browser session beats two test suites

The standard pattern looks fine on paper. Playwright clicks around the frontend. The Postman Collection hits the API. Both pass. Ship it.

The problem shows up between the layers. Your frontend starts calling an undocumented endpoint after a refactor. Your API starts returning a new field that nobody adds to the schema. The UI tests don’t notice — they only assert on rendered text. The API tests don’t notice either — they’re hitting endpoints based on what the contract used to say, not what the frontend actually calls today. That’s the gap contract drift lives in, and it’s the gap Agent Mode’s browser tool is built to close.

When Agent Mode drives the browser, every request the frontend fires gets recorded once. Both test suites are generated from that single recording, which means they reference the same observed behavior instead of two independently-maintained mental models. If the API changes, both suites notice. If the UI starts calling something new, the API tests pick it up the next time you regenerate.

Prerequisites

You’ll need:

Heads up: the browser tool runs inside Agent Mode itself — there’s nothing extra to install. If your Postman app is on v12 and Agent Mode shows a Browser option in the tools list, you’re ready.

Step 1: Ask Agent Mode to drive your app

Open Agent Mode in your workspace and give it a task that involves a flow in your frontend. The trick is to be specific about what you want it to do in the browser and what you want it to produce.

Agent Mode opens the embedded browser, runs the flow, and streams the captured requests into your workspace as it goes. You’ll watch it click through your app in real time.

What you get back is a new Postman Collection containing every request the frontend made, whatever your app actually calls — along with a .spec.ts Playwright file that mirrors the same flow.

Step 2: Review the generated tests

I always review before I commit. Agent Mode is good, but it’s pattern-matching from observed traffic, and there are decisions only you can make — which fields are required, which are stable, which are environment-specific.

A typical generated Postman test script looks like this:

// Generate a unique email each run to avoid duplicate-user conflicts
const ts = Date.now();
const email = `testuser_api_${ts}@example.com`;
pm.collectionVariables.set('reg_email', email);

// Patch the request body with the generated email
const body = JSON.parse(pm.request.body.raw);
body.email = email;
pm.request.body.update({ mode: 'raw', raw: JSON.stringify(body) });

The Playwright side looks like this:

  test('registers a new user and shows the profile view', async ({ page }) => {
    const email = uniqueEmail();

    // Intercept the register API call so we can assert on it
    const [registerResponse] = await Promise.all([
      page.waitForResponse((res) =>
        res.url().includes('/api/auth/register') && res.request().method() === 'POST'
      ),
      (async () => {
        await page.getByRole('button', { name: 'Register' }).click();
        await page.locator('#register-form input[name="email"]').fill(email);
        await page.locator('#register-form input[name="password"]').fill(VALID_PASSWORD);
        await page.locator('#register-form button[type="submit"]').click();
      })(),
    ]);

    // API responded with 201
    expect(registerResponse.status()).toBe(201);
    const body = await registerResponse.json();
    expect(body.success).toBe(true);
    expect(body.data.user.email).toBe(email);
    expect(body.data.accessToken).toBeTruthy();

    // Success message appears
    await expect(page.locator('#message')).toContainText('Account created');

    // Profile view is shown (auth view hidden)
    await expect(page.locator('#profile-view')).toBeVisible();
    await expect(page.locator('#auth-view')).toBeHidden();

    // Profile fields are populated correctly
    await expect(page.locator('#profile-email')).toHaveText(email);
    await expect(page.locator('#profile-id')).not.toHaveText('-');
    await expect(page.locator('#profile-created')).not.toHaveText('-');

    // Token is persisted in localStorage
    const token = await page.evaluate(() => localStorage.getItem('auth.accessToken'));
    expect(token).toBeTruthy();
  });

Step 3: Run both suites with one command

Once the tests are checked in, you run them together with the Postman CLI:

postman app test

That single command runs your Playwright suite, captures the network traffic during the run, and validates the observed API calls against the requests in your Postman Collection. You get one set of results that covers both layers.

The output looks roughly like this:

$ postman app test

→ Running UI tests via Playwright...
  ✓ create a new project (2.3s)
  ✓ delete a project (1.8s)

→ Validating captured API traffic against collection "Demo App API"...
  ✓ POST /api/auth/login        matched ✓ schema ✓ status
  ✓ POST /api/projects          matched ✓ schema ✓ status
  ✓ DELETE /api/projects/:id    matched ✓ schema ✓ status

┌─────────────────────────┬────────────┬────────────┐
│                         │   executed │     failed │
├─────────────────────────┼────────────┼────────────┤
│              UI tests   │          2 │          0 │
├─────────────────────────┼────────────┼────────────┤
│          API requests   │          3 │          0 │
├─────────────────────────┼────────────┼────────────┤
│       contract checks   │          9 │          0 │
└─────────────────────────┴────────────┴────────────┘

If a frontend refactor starts calling an endpoint that isn’t in your Postman Collection, the contract check fails even though the Playwright assertion still passes. That’s the catch you were missing before.

Patterns I’ve found useful

Re-record after every meaningful UI change

The whole point of generating both suites from one recording is that they stay in sync. The moment you start hand-editing one without the other, drift creeps back in. When the UI flow changes, regenerate the recording. It takes a minute.

Keep credentials in environments, never in prompts

Agent Mode prompts are fine for orchestration, but they’re not the place for API keys or test passwords. Reference Postman Environments with secret-typed variables and let Agent Mode pull from there. Easier to rotate, harder to leak.

Start with read-only flows

The first time you turn Agent Mode loose on a real app, point it at a flow that only does reads — search, list views, profile pages. Once you’ve seen it work end-to-end, graduate to flows that create or delete state. The same caution you’d apply to any test automation framework applies here.

Let the contract check fail loud

The temptation is to mark the contract check as a warning instead of a failure, especially early on when there’s a lot of drift to clean up. Resist it. A contract check that doesn’t fail the build doesn’t get fixed.

Try it yourself

Pick a flow in your app that you’ve been meaning to write tests for. Open Agent Mode, point it at the URL, describe the flow in plain English, and ask for Playwright tests plus a Postman Collection. Review the output, run postman app test, and watch both layers validate against the same recording.

If you want a starting point, the Postman Playwright integration blog post walks through postman app init in detail, and the Postman samples on GitHub include working configurations you can clone and adapt.

The piece I keep coming back to is how much friction this removes. Writing API tests by hand from a Playwright recording was always a chore — copy the request, paste it into a new Postman Collection request, write the assertions, remember to update both the next time the UI changes. Agent Mode does that copy-paste-assert loop for you and ties the two ends together. The tests you ship are the tests for what your app actually does, not what someone thought it did six months ago.

Resources

What do you think about this topic? Tell us in a comment below.

Comment

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


This site uses Akismet to reduce spam. Learn how your comment data is processed.