Skip to content

Browser check examples

Copy a complete browser check and adapt its paths, text and values to your app. Set up @blopai/test first with Browser checks.

tests/auth.blop.ts
import { agentTest, describe } from "@blopai/test";
describe("auth", () => {
agentTest("seeded user can sign in", async ({ agent }) => {
await agent.goto("/sign-in");
await agent.goal(`
Sign in as test@test.com with password admin123.
After submitting:
- Verify the URL becomes /dashboard.
- Verify the heading "My projects" is visible.
- Verify the user's email "test@test.com" appears in the top nav.
Finish the test as passed only if all three checks succeed.
Otherwise finish as failed and explain which check failed.
`);
});
agentTest("invalid password is rejected", async ({ agent }) => {
await agent.goto("/sign-in");
await agent.goal(`
Try to sign in as test@test.com with password "wrong".
Verify:
- The URL does NOT change to /dashboard.
- An error message containing "incorrect" or "invalid" is visible.
Finish as passed only if both are true.
`);
});
});

The credentials belong to a seeded local user. Never put production credentials in a goal; production needs a secret-backed sign-in and a synthetic identity (Production checks). Three named verifications and a strict pass condition stop the agent passing on partial state.

tests/create-project.blop.ts
import { agentTest, describe } from "@blopai/test";
describe("projects", () => {
agentTest("can create a project", async ({ agent }) => {
await agent.goto("/dashboard/projects/new");
await agent.goal(`
Fill out the new-project form:
- Name: "Checkout QA"
- Repository URL: "https://github.com/example/shop"
- Default branch: "main"
Submit the form.
Verify:
- The URL changes to /dashboard/projects/<some-id>.
- The page heading reads "Checkout QA".
- A toast or banner with "Project created" appears.
Finish as passed only if all three checks succeed.
`);
});
agentTest("missing name is rejected", async ({ agent }) => {
await agent.goto("/dashboard/projects/new");
await agent.goal(`
Submit the form WITHOUT filling in any fields.
Verify:
- The URL still ends in /projects/new.
- An error message near the "Name" field reads "Required" or similar.
Finish as passed only if both are true.
`);
});
agentTest("can upload an avatar", async ({ agent }) => {
await agent.goto("/dashboard/general");
await agent.goal(`
Upload the file at "tests/fixtures/avatar.png" via the avatar input.
Verify the avatar preview updates and a "Saved" toast appears.
Finish as passed only if both are true.
`);
});
});

Give exact values and one check per failure mode. The agent uploads files with browser_upload_file; the fixture path is relative to the directory you run blop test from.

tests/checkout.blop.ts
import { agentTest, describe } from "@blopai/test";
describe("checkout", () => {
agentTest("guest can complete a purchase", async ({ agent }) => {
await agent.goto("/products/widget");
await agent.goal(`
Step 1 — Add to cart:
- Click the "Add to cart" button.
- Verify the cart counter reads "1".
Step 2 — Open the cart:
- Click the cart icon.
- Verify the URL becomes /cart.
- Verify "Widget" appears in the line items.
Step 3 — Begin checkout:
- Click "Checkout".
- Verify the URL becomes /checkout.
Step 4 — Fill shipping:
- Email: "test@example.com"
- Name: "Test User"
- Address: "1 Main St"
- City: "Austin"
- Zip: "78701"
- Click "Continue to payment".
Step 5 — Pay with the test card 4242 4242 4242 4242,
any future expiry, CVC 123. Submit.
Step 6 — Verify success:
- URL becomes /checkout/thanks.
- Heading reads "Order confirmed".
Finish as passed only if every step's verification succeeds.
If any step fails, stop and finish as failed with a reason.
`);
});
});

Numbered steps give the agent checkpoints and make the result’s reason easy to read. Model different starting states, such as guest and signed-in, as separate checks in the same describe. Set an explicit --max-steps for long flows; there is no default cap.