Browser evidence beyond raw API calls
Auth redirects, sessions, forms, and visible UI state can stay in the same evidence model as your API tests. Keep Puppeteer, add traces, screenshots, assertions, and a clear promotion path.
API and browser evidence stays together.
Why the browser surface exists
Browser automation should continue the same verification model, not become a second system just because the path touches UI state. The browser page keeps that line auditable.
Why browser steps matter
Authentication redirects and session state live beyond raw HTTP calls.
Real user flows often depend on form state, navigation, and visible UI transitions.
Teams should not lose the audit trail just because a test touches the browser.
What Glubean preserves
The same assertions, traces, screenshots, and CI path continue into browser steps.
You keep Puppeteer power and plugin compatibility while adding Glubean evidence.
Browser and API activity can still belong to one evidence-backed verification story.
Keep Puppeteer power
You do not lose browser power to gain evidence structure. You keep Puppeteer, plugin support, and raw access. Glubean adds evidence, assertions, lifecycle, and promotion on top.
// Modern Puppeteer (v21+ Locator API) + Jest
const browser = await puppeteer.launch();
const page = await browser.newPage();
try {
await page.goto("http://localhost:3000/login");
await page.locator("#email").fill("user@test.com");
await page.locator("#password").fill("secret");
await Promise.all([
page.waitForNavigation({ waitUntil: "load" }),
page.locator('button[type="submit"]').click(),
]);
expect(page.url()).toContain("/dashboard");
const text = await page.$eval("h1", (el) => el.textContent);
expect(text).toBe("Welcome back");
} catch (err) {
await page.screenshot({ path: "fail.png", fullPage: true });
throw err;
} finally {
await browser.close();
}
// ✓ auto-wait (Locator) ✗ assertions ✗ traces ✗ metrics// @glubean/browser
import { browserTest } from "./base.ts";
export const login = browserTest("login", async ({ page }) => {
await page.goto("/login");
await page.type("#email", "user@test.com");
await page.type("#password", "secret");
await page.clickAndNavigate('button[type="submit"]');
await page.expectURL("/dashboard");
await page.expectText("h1", "Welcome back");
});
// ✓ auto-wait ✓ assertions ✓ traces ✓ metrics ✓ screenshots
// page.raw is the native Puppeteer Page — zero capability lossSame browser engine underneath. The difference is the evidence layer: assertions, lifecycle, traces, screenshots, and promotion path.
Plugin ecosystem
Stealth plugins, captcha helpers, custom launch behavior, puppeteer-extra. If the test needs browser-specific power, you should not give that up to keep the evidence structured.
configure.ts + base.ts
// tests/configure.ts
import { configure } from "@glubean/sdk";
import { browser } from "@glubean/browser";
import puppeteerExtra from "puppeteer-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";
import RecaptchaPlugin from "puppeteer-extra-plugin-recaptcha";
puppeteerExtra.use(StealthPlugin());
puppeteerExtra.use(RecaptchaPlugin({ provider: { id: "2captcha", token: "TOKEN" } }));
export const { chrome } = configure({
plugins: {
chrome: browser({ launch: true, puppeteer: puppeteerExtra }),
},
});
// tests/base.ts — create a per-test page fixture
import { test } from "@glubean/sdk";
import { chrome } from "./configure.ts";
export const browserTest = test.extend({
page: async (ctx, use) => {
const pg = await chrome.newPage(ctx);
try {
await use(pg);
} finally {
await pg.close();
}
},
});Why this matters
Keep stealth, recaptcha, and other puppeteer-extra plugins.
Use raw Puppeteer APIs when the test needs lower-level browser access.
Add Glubean assertions, traces, screenshots, and lifecycle on top of that stack.
Browser steps stay in the same model you already use for API verification.
Keep low-level access and the plugin ecosystem you already trust.
Run locally, in CI, and later in Cloud without changing the artifact.
Full browser evidence
When the path moves into the browser, you still keep one artifact from authoring to CI to Cloud, with browser-specific proof attached to the same run history.
tests/login.test.ts
import { browserTest } from "./base.ts";
export const login = browserTest("login-flow", async ({ page, secrets }) => {
await page.goto("/login");
await page.type("#email", "user@test.com");
await page.type("#password", secrets.require("TEST_PASSWORD"));
await page.clickAndNavigate('button[type="submit"]');
await page.expectURL("/dashboard");
await page.expectText("h1", "Welcome back");
});
// traces ✓ metrics ✓ network logs ✓ console errors ✓ screenshots ✓Browser-specific proof
Inline run
Click play in the editor and the browser flow executes alongside your API tests.
Assertions with retries
URL, text, and visibility assertions wait for the UI to settle instead of failing too early.
Trace and diff
Browser actions, timings, and failures stay inspectable and comparable across runs.
Screenshots on failure
Visual evidence is captured automatically when the flow breaks.
Debuggable like code
The browser flow is still real TypeScript, so the debugging experience stays familiar.
When to use what
If you need the deepest browser framework for cross-browser grids, complex drag-drop, canvas-heavy surfaces, or visual regression at full scale, use Playwright. Glubean browser is strongest when the goal is to keep API and browser checks in one evidence model, one trace system, and one promotion path.
Use Glubean browser for
auth flows, forms, CRUD paths, dashboard checks, and browser steps that belong inside the same evidence loop as your API tests.
Reach for Playwright for
full browser lab coverage, highly interactive UI systems, and the heaviest browser-only test workloads.
Start with the same evidence loop
Familiar to anyone who already knows Puppeteer — with the evidence, observability, and promotion path that were missing.
Also available on npm