Browser Verification in Claude Code
Add autonomous browser-based UI verification to your Claude Code pre-PR workflow.
Introduction
30 Second Summary
Code reviews catch logic errors, but they can't tell you if a button is missing or a form is broken. That's the kind of thing you only discover when someone actually opens the page in a browser.
In this project, you will set up Claude Code to autonomously verify your web implementations using a real browser before creating pull requests. Claude Code will open your app, inspect elements, test interactions, take screenshots, and report issues on its own.
What You'll Build
A browser-based verification workflow where Claude Code drives the browser-use CLI to open pages, inspect the DOM, test form submissions, and screenshot results before every PR.
By the end of this project, you'll have:
- The browser-use CLI installed and connected to a cloud browser with free stealth browsing, proxies, and CAPTCHA solving.
- A CLAUDE.md pre-PR workflow that tells Claude Code to verify your UI automatically before creating pull requests.
- A completed end-to-end verification run where Claude Code opens a page, tests interactions, and reports real issues it finds.
- A secret mission to test email verification flows using AgentMail through a cloud browser, all handled autonomously by Claude Code.
Are there any prerequisites?
You need an active Claude Code installation with a subscription, Chrome installed on your machine, and Node.js/npm available in your terminal. Familiarity with Claude Code workflows (like CLAUDE.md and slash commands) will help you get the most out of this project.
Install and Verify the Browser-Use CLI
Claude Code can implement features, refactor code, and write tests. But it has no way to see what your app actually looks like in a browser.
The browser-use CLI solves this by giving terminal-based agents the ability to open a real Chrome session, inspect the page, and interact with elements. In this step, you will install it and confirm it works on your machine.
In this step, get ready to:
- Install the browser-use CLI and verify it with browser-use doctor.
- Test a headless browser session against a live web page.
- Launch headed mode to see exactly what the agent sees.
Install the CLI and run the doctor check
The browser-use CLI controls Chrome through the Chrome DevTools Protocol. A background daemon keeps the browser session alive between commands, so each command runs in about 50 milliseconds.
- Install the browser-use CLI by running this command:
curl -fsSL https://browser-use.com/cli/install.sh | bash
What does this command do?
This downloads and runs the official installer script. It installs the browser-use binary and adds it to your shell's PATH so you can run it from any terminal window.
- Verify the installation by running:
browser-use doctor
You should see output confirming that the CLI found Chrome and that the background daemon is running.
Command not found?
The installer modifies your PATH via your login shell profile. Open a new terminal tab and try running browser-use doctor again.
If the issue persists, confirm that Chrome is installed on your machine. The browser-use CLI only supports Chrome.
Still stuck? Ask for help here.
Test a basic browser session
By default, browser-use runs Chrome in headless mode. The browser starts in the background with no visible window, which is exactly how Claude Code will use it.
- Open a headless browser session by running:
browser-use open https://example.com
The CLI launches Chrome in the background and navigates to the page. You will not see a window because headless mode is active.
- Inspect the page's interactable elements by running:
browser-use state
What does browser-use state show?
It returns a numbered list of every interactable element on the page. Links, buttons, form inputs, and other clickable elements each get an index number.
You can reference these index numbers in later commands like browser-use click 0. This is the core browser automation workflow: navigate to a page, then inspect its state.
- Close the browser session by running:
browser-use close
Seeing an error when opening?
Make sure Chrome is installed and up to date. The browser-use CLI only works with Chrome. Safari and Firefox are not supported.
If you see a timeout error, the background daemon may not be running. Run browser-use doctor again to check its status.
Need more help? Ask here.
Try headed mode for visual confirmation
Headed mode opens a visible Chrome window so you can watch the browser respond to each command. This is useful for debugging and understanding how browser-use interacts with a page.
- Launch a visible Chrome window by running:
browser-use --headed open https://example.com
A Chrome window appears on your screen and navigates to example.com. This is exactly what the agent sees.
- Inspect the numbered elements by running:
browser-use state
You should see the same kind of numbered element list as before. Note the index of the first element.
- Click the first interactable element by running:
browser-use click 0
Watch the Chrome window respond. Depending on which element is at index 0, it might navigate to a new page or trigger an interaction.
- Close the browser session by running:
browser-use close
Chrome window not appearing?
Make sure you included the --headed flag before open. Without it, the browser runs in headless mode and no window appears.
If the window opens but immediately closes, run browser-use close first to end any leftover sessions, then try the headed command again.
Still having trouble? Ask here.
The CLI is installed and working in both headless and headed modes. Next up, you will provision cloud browser access and install the browser-use skill so Claude Code can drive the browser on its own.
Set Up Cloud Access and Install the Skill
Your local browser-use setup works, but it only runs on your machine. Cloud browsers give Claude Code access to stealth browsing, proxies in 195+ countries, and automatic CAPTCHA solving.
In this step, you will provision a cloud API key through an agent self-registration flow. Then you will install the browser-use skill so Claude Code knows the full set of CLI commands it can use.
In this step, get ready to:
- Provision a cloud API key via the agent self-registration challenge.
- Install the browser-use skill for Claude Code.
- Restart Claude Code and confirm it recognizes the browser-use commands.
Provision a cloud API key via agent self-registration
Browser Use Cloud uses an agent self-registration flow instead of a traditional signup page. You request a challenge, solve it, and receive an API key automatically.
- Start the registration challenge by running this command:
browser-use cloud signup
This returns two values: a Challenge ID and a Challenge (an obfuscated math problem).
What is agent self-registration?
Instead of filling out a web form, browser-use verifies you can reason through a math problem. This is designed so AI agents can self-provision access without human intervention. The challenge requires reasoning, not just arithmetic.
- Solve the math problem displayed in your terminal.
- Your answer must be a string with 2 decimal places (e.g., "13.60").
- Submit your answer by running this command, replacing the placeholders with your actual challenge ID and answer:
browser-use cloud signup --verify [[CHALLENGE_ID="your challenge ID from the previous command"]] [[CHALLENGE_ANSWER="your answer with 2 decimal places"]]
What happens on success?
On success, the CLI saves your API key automatically to ~/.browser-use/config.json. You never need to copy or paste the key manually.
Now test that cloud access is working by connecting to a cloud browser session.
- Connect to a cloud browser by running this command:
browser-use cloud connect
- Inspect the cloud browser's state by running:
browser-use state
You should see a list of interactable elements from the cloud browser's default page, confirming the session is live.
- Close the cloud session by running:
browser-use close
Cloud connect failing?
If you see an authentication error, your challenge answer may have been incorrect. Run browser-use cloud signup again to get a fresh challenge and re-verify.
Check that ~/.browser-use/config.json exists and contains an API key. If the file is missing, the verify step did not succeed.
Help me debug my browser-use cloud connection
Install the browser-use skill for Claude Code
Claude Code needs to know what browser-use commands are available and how to use them. A skill is a Markdown file that gives Claude Code this knowledge on demand.
- Install the browser-use skill by running this command:
npx skills add https://github.com/browser-use/browser-use --skill browser-use
- When prompted, select claude-code as the target agent.
What does this command do?
The npx skills add command downloads a SKILL.md file that contains the full browser-use CLI reference. Claude Code reads this file at startup so it knows every command available: open, state, click, input, screenshot, and more.
- Verify the skill was installed by checking for the SKILL.md file:
ls ~/.claude/skills/browser-use/SKILL.md
You should see the file path printed. If you get a "No such file or directory" error, the skill installed to the wrong location.
SKILL.md not found at that path?
There is a known bug where global installs land in ~/.agents/skills/ instead of ~/.claude/skills/. Claude Code only reads from ~/.claude/skills/.
Fix this by manually copying the file to the correct location:
mkdir -p ~/.claude/skills/browser-use && cp ~/.agents/skills/browser-use/SKILL.md ~/.claude/skills/browser-use/SKILL.md
Help me find where my browser-use skill was installed
Restart Claude Code and confirm the skill is loaded
Skills are loaded at startup, not dynamically. Claude Code needs a fresh session to pick up the new skill file.
- Exit your current Claude Code session (type /exit or press Ctrl+C).
- Re-launch Claude Code in your project directory.
- Ask Claude Code: "What browser-use commands do you have available?"
Claude should respond with knowledge of the CLI commands like open, state, click, input, type, screenshot, and close.
Claude Code doesn't know about browser-use?
If Claude responds with generic information instead of specific CLI commands, the skill file is not in the right location. Double check that ~/.claude/skills/browser-use/SKILL.md exists.
Also confirm you fully exited and relaunched Claude Code. Opening a new conversation in the same session is not enough.
Help me get Claude Code to recognize my browser-use skill
Cloud access is provisioned and Claude Code knows the full browser-use command set. Next up, you will write the pre-PR verification workflow that tells Claude Code exactly when and how to use these commands.
Write the Pre-PR Browser Verification Workflow
Your browser-use CLI is installed, cloud access is provisioned, and Claude Code knows the full command set. Now it's time to tell Claude Code when and how to use those commands.
Claude Code reads project-level instructions from a file called CLAUDE.md. In this step, you'll write a pre-PR verification workflow in that file and create a dedicated /verify-ui skill. Together, these give Claude Code a clear playbook for browser-based QA.
In this step, get ready to:
- Add a pre-PR browser verification section to your project's CLAUDE.md.
- Create a /verify-ui skill with a step-by-step verification checklist.
- Restart Claude Code and confirm both the workflow and skill are loaded.
Add browser verification rules to your project's CLAUDE.md
CLAUDE.md loads automatically every time Claude Code starts a session. Any instructions you put here apply to every conversation in the project.
Why CLAUDE.md instead of a skill?
Skills load on demand when you invoke them or when Claude determines they are relevant. CLAUDE.md loads every session. The "always verify before PRs" rule belongs in CLAUDE.md so Claude Code never skips it. The detailed checklist goes in a skill to keep CLAUDE.md lean (under 200 lines is the recommended best practice).
- Create a file called CLAUDE.md in your project root. If you already have one, open it and add the section below at the end.
- Paste the following content into CLAUDE.md:
## Pre-PR Browser Verification
Before creating any pull request, verify the implementation in a real browser using browser-use CLI.
### Workflow
1. Start the dev server if it is not already running.
2. Use `browser-use open <url>` to navigate to each affected page.
3. Run `browser-use state` to inspect the DOM and verify expected elements exist.
4. Test key interactions with `browser-use click <index>` and `browser-use input <index> "<text>"`.
5. Take a screenshot with `browser-use screenshot <filename>.png` for visual reference.
6. Report findings before creating the PR. Include what was checked, what passed, and any issues found.
IMPORTANT: Always run `browser-use close` when the browser session is complete.
What does this section tell Claude Code?
- The numbered workflow gives Claude Code a repeatable sequence: open the page, inspect it, interact with it, screenshot it, report results.
- The IMPORTANT line ensures Claude Code always cleans up the browser session. Without it, headless Chrome processes can pile up in the background.
- Because this lives in CLAUDE.md, Claude Code will follow these rules in every session without you having to remind it.
- Save CLAUDE.md.
You won't see a visible change yet. You'll confirm Claude Code picks up these instructions in the final substep of this step.
Create a /verify-ui skill for on-demand verification
The CLAUDE.md section tells Claude Code to verify before PRs. The skill contains the detailed checklist of what to verify. Placing it in .claude/skills/ (project scope) means you can commit it to git and share it with your team.
- Create the skill directory by running this command:
mkdir -p .claude/skills/verify-ui
- Confirm the directory exists by running:
ls .claude/skills/
You should see verify-ui listed as a directory.
- Create a file called SKILL.md inside .claude/skills/verify-ui/.
- Paste the following content into SKILL.md:
---
name: verify-ui
description: "Run browser-based UI verification on the current project. Opens the app in a browser, checks layout, tests interactions, and reports issues."
user-invocable: true
agent: "claude-code"
allowed-tools:
- Bash
- Read
- Glob
---
# Browser UI Verification
Run a browser-based verification of the current project's UI. Use browser-use CLI commands to automate the checks.
## Verification Steps
1. **Start the dev server** if it is not already running. Check if a server is listening on the expected port first.
2. **Open the page**: Run `browser-use open <url>` to navigate to the app.
3. **Inspect the DOM**: Run `browser-use state` to get all interactable elements with indices.
4. **Check page structure**:
- Verify the page has a heading (h1 or h2)
- Check that navigation links are present and have valid hrefs
- Confirm form fields exist if the page has forms
- Look for empty containers or missing content
5. **Test interactions**:
- Fill form fields using `browser-use input <index> "<text>"`
- Click buttons and links using `browser-use click <index>`
- After clicking navigation, run `browser-use state` to check the resulting page
6. **Take a screenshot**: Run `browser-use screenshot verification.png` for visual reference.
7. **Report findings**: Summarize what was checked, what passed, and what failed. Include specific element details.
8. **Clean up**: Run `browser-use close` to shut down the browser session. Stop the dev server if you started it.
## Important Rules
- ALWAYS run `browser-use state` before interacting with elements. Element indices change between page loads.
- ALWAYS run `browser-use close` when verification is complete.
- If a page takes time to load, wait briefly and run `browser-use state` again.
- Report issues with specific details: element index, expected behavior, actual behavior.
What does this skill do?
- The YAML frontmatter at the top registers the skill with Claude Code. user-invocable: true means you can trigger it by typing /verify-ui in Claude Code.
- allowed-tools grants the skill access to Bash (to run CLI commands), Read (to read project files), and Glob (to find files by pattern).
- The numbered verification steps give Claude Code a concrete checklist. It inspects the DOM, checks structure, tests interactions, screenshots the result, and reports back.
- The "Important Rules" section prevents common mistakes like interacting with stale element indices or leaving browser sessions open.
- Save .claude/skills/verify-ui/SKILL.md.
- Confirm the file is in the right place by running:
ls .claude/skills/verify-ui/
You should see SKILL.md listed in the output.
Don't see SKILL.md in the output?
- Make sure you created the file inside .claude/skills/verify-ui/ and not in .claude/skills/ directly. The file must be nested one folder deeper.
- Check that the filename is exactly SKILL.md (all caps, not skill.md or Skill.md). Claude Code looks for this exact filename.
- Help me troubleshoot my SKILL.md file location for Claude Code.
Awesome, I've got everything!
Double check you've saved both CLAUDE.md and SKILL.md before continuing.
I'd like to double check the full code
Here is the full .claude/skills/verify-ui/SKILL.md file. Make sure yours matches exactly.
---
name: verify-ui
description: "Run browser-based UI verification on the current project. Opens the app in a browser, checks layout, tests interactions, and reports issues."
user-invocable: true
agent: "claude-code"
allowed-tools:
- Bash
- Read
- Glob
---
# Browser UI Verification
Run a browser-based verification of the current project's UI. Use browser-use CLI commands to automate the checks.
## Verification Steps
1. **Start the dev server** if it is not already running. Check if a server is listening on the expected port first.
2. **Open the page**: Run `browser-use open <url>` to navigate to the app.
3. **Inspect the DOM**: Run `browser-use state` to get all interactable elements with indices.
4. **Check page structure**:
- Verify the page has a heading (h1 or h2)
- Check that navigation links are present and have valid hrefs
- Confirm form fields exist if the page has forms
- Look for empty containers or missing content
5. **Test interactions**:
- Fill form fields using `browser-use input <index> "<text>"`
- Click buttons and links using `browser-use click <index>`
- After clicking navigation, run `browser-use state` to check the resulting page
6. **Take a screenshot**: Run `browser-use screenshot verification.png` for visual reference.
7. **Report findings**: Summarize what was checked, what passed, and what failed. Include specific element details.
8. **Clean up**: Run `browser-use close` to shut down the browser session. Stop the dev server if you started it.
## Important Rules
- ALWAYS run `browser-use state` before interacting with elements. Element indices change between page loads.
- ALWAYS run `browser-use close` when verification is complete.
- If a page takes time to load, wait briefly and run `browser-use state` again.
- Report issues with specific details: element index, expected behavior, actual behavior.
Test the CLAUDE.md and skill loading
Claude Code loads skills at startup, not dynamically. You need to restart it for the new files to take effect.
- Exit Claude Code (type /exit or press Ctrl+C).
- Re-launch Claude Code in your project directory by running:
claude
- Ask Claude Code: "What does my pre-PR verification workflow look like?"
Claude Code should describe the verification steps from your CLAUDE.md. It should mention opening the browser, inspecting the DOM, testing interactions, taking screenshots, and reporting findings.
- Type /verify-ui in Claude Code to confirm the skill is registered and accessible.
Claude Code should recognize the command and start working through the verification checklist. It will likely report that no dev server is running yet. That is expected.
Claude Code doesn't recognize the workflow or skill?
- Make sure you restarted Claude Code after creating the files. Editing CLAUDE.md or adding skills does not take effect until the next session.
- Confirm you launched Claude Code from the same directory where CLAUDE.md and the .claude/ folder live. Project-scoped files are only loaded when Claude Code starts in the project root.
- Check that your SKILL.md has valid YAML frontmatter. A missing --- fence at the top or bottom of the frontmatter will prevent Claude Code from parsing the skill.
- Help me troubleshoot why Claude Code isn't loading my CLAUDE.md or verify-ui skill.
Your verification workflow is defined and Claude Code knows how to follow it. Next up, you'll put this workflow to the test by verifying a real web page.
Run a Real Verification Cycle
Your CLAUDE.md workflow and /verify-ui skill are locked and loaded. Claude Code knows what to do before creating a pull request. Now it is time to prove the whole system works end-to-end.
You will create a sample web page with common UI elements, have Claude Code run a full browser verification against it, and then deliberately break something to confirm the workflow actually catches problems.
In this step, get ready to:
- Create a test HTML page with a contact form, navigation bar, and heading.
- Have Claude Code run a full browser verification cycle against your page.
- Introduce a deliberate defect and confirm Claude Code detects it.
Create a simple test page
Claude Code needs a real web page to verify. You will create a small HTML page that includes the most common UI elements a verification workflow would inspect: headings, navigation links, form fields, and a footer.
- Create a file called index.html in your project root and paste in the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Verification Test Page</title>
<style>
/* Base layout */
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
color: #333;
}
/* Navigation bar */
nav {
background: #f5f5f5;
padding: 10px 20px;
border-radius: 8px;
margin-bottom: 30px;
}
nav a {
margin-right: 15px;
text-decoration: none;
color: #0066cc;
}
nav a:hover {
text-decoration: underline;
}
/* Contact form */
form {
display: flex;
flex-direction: column;
gap: 15px;
max-width: 400px;
}
label {
font-weight: 600;
}
input, textarea {
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}
textarea {
min-height: 100px;
resize: vertical;
}
button {
background: #0066cc;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background: #0052a3;
}
/* Footer */
footer {
margin-top: 50px;
padding-top: 20px;
border-top: 1px solid #eee;
color: #666;
font-size: 14px;
}
</style>
</head>
<body>
<!-- Page heading -->
<h1>My Project</h1>
<!-- Navigation bar with internal links -->
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/docs">Documentation</a>
<a href="/contact">Contact</a>
</nav>
<!-- Contact form section -->
<h2>Contact Us</h2>
<form action="/submit" method="POST">
<label for="name">Name</label>
<input type="text" id="name" name="name" placeholder="Your name" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="you@example.com" required>
<label for="message">Message</label>
<textarea id="message" name="message" placeholder="How can we help?" required></textarea>
<button type="submit">Send Message</button>
</form>
<!-- Page footer -->
<footer>
<p>© 2026 My Project. All rights reserved.</p>
</footer>
</body>
</html>
What does this page include?
- An h1 heading ("My Project") and an h2 section heading ("Contact Us") that the verification can check for proper heading structure.
- A nav bar with four links: Home, About, Documentation, and Contact.
- A contact form with name, email, and message fields, plus a Send Message submit button. The form's action attribute points to /submit.
- A footer with a copyright notice.
These elements give the verification workflow plenty to inspect: heading hierarchy, link validity, form structure, and page completeness.
- Save index.html.
Awesome, I've got everything!
Great. Make sure you have saved index.html before moving on.
I'd like to double check the full code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Verification Test Page</title>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
color: #333;
}
nav {
background: #f5f5f5;
padding: 10px 20px;
border-radius: 8px;
margin-bottom: 30px;
}
nav a {
margin-right: 15px;
text-decoration: none;
color: #0066cc;
}
nav a:hover {
text-decoration: underline;
}
form {
display: flex;
flex-direction: column;
gap: 15px;
max-width: 400px;
}
label {
font-weight: 600;
}
input, textarea {
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}
textarea {
min-height: 100px;
resize: vertical;
}
button {
background: #0066cc;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background: #0052a3;
}
footer {
margin-top: 50px;
padding-top: 20px;
border-top: 1px solid #eee;
color: #666;
font-size: 14px;
}
</style>
</head>
<body>
<h1>My Project</h1>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/docs">Documentation</a>
<a href="/contact">Contact</a>
</nav>
<h2>Contact Us</h2>
<form action="/submit" method="POST">
<label for="name">Name</label>
<input type="text" id="name" name="name" placeholder="Your name" required>
<label for="email">Email</label>
<input type="email" id="email" name="email" placeholder="you@example.com" required>
<label for="message">Message</label>
<textarea id="message" name="message" placeholder="How can we help?" required></textarea>
<button type="submit">Send Message</button>
</form>
<footer>
<p>© 2026 My Project. All rights reserved.</p>
</footer>
</body>
</html>
Now you need to serve this page so the browser can access it.
- Start a local server by running this command in the terminal:
python3 -m http.server 8080
- Open http://localhost:8080 in Chrome. You should see a page titled "My Project" with a navigation bar, a contact form with three fields, and a footer.
Pro tip: keep the server running
The server runs in the foreground and blocks your terminal. Keep this tab open and use a separate terminal tab for Claude Code and other commands throughout the rest of this step.
Page not loading?
- Make sure you are running the python3 command from the same folder that contains index.html.
- If port 8080 is already in use, try python3 -m http.server 8081 and adjust the URL accordingly.
- My local server still is not loading.
Ask Claude Code to verify the page
This is the moment of truth. You will ask Claude Code to run a full browser verification against your test page using the browser-use CLI.
Why not use the cloud browser for this?
Cloud browsers cannot access localhost. For verifying local dev servers, Claude Code uses the default headless mode, which connects to Chrome on your machine. Cloud mode is for testing on public URLs or when stealth and proxy features are needed.
- Open a new terminal tab (keep the server running in the other tab).
- Launch Claude Code in your project directory.
- Type the following prompt into Claude Code:
Use browser-use to open http://localhost:8080 and verify the page has a working contact form, navigation links, and proper heading structure. Take a screenshot and report any issues.
Claude Code will now execute your verification workflow autonomously. Watch the commands it runs in the terminal output.
What should I see?
Claude Code should execute a sequence like this:
- browser-use open http://localhost:8080 to navigate to your page.
- browser-use state to inspect all interactable elements and their indices.
- browser-use input commands to fill in the name, email, and message form fields.
- browser-use click to press the submit button.
- browser-use screenshot to capture a visual reference.
- browser-use close to shut down the browser session.
After finishing, Claude Code will produce a verification report describing what it found, what it tested, and whether any issues were detected.
- Review Claude Code's verification report in the chat output.
- Confirm that the report mentions the h1 heading, the four navigation links, the three form fields, and the submit button.
Claude Code not running browser-use commands?
- Make sure you restarted Claude Code after installing the browser-use skill in Step 2. Skills are loaded at startup, not dynamically.
- Verify the skill file exists at ~/.claude/skills/browser-use/SKILL.md. If it is missing, copy it manually from ~/.agents/skills/browser-use/SKILL.md.
- Claude Code is not using browser-use even after restarting.
Simulate a verification failure
A verification workflow is only useful if it catches problems. You will introduce a deliberate defect into your page and confirm that Claude Code detects it.
- In index.html, find the opening <form> tag:
<form action="/submit" method="POST">
- Remove the action="/submit" attribute so the line looks like this:
<form method="POST">
- Save index.html.
The form now has no submission endpoint. A thorough verification should flag this as a problem. Time to see if your workflow catches it.
- In Claude Code, type the following prompt:
Verify http://localhost:8080 again. Check the contact form carefully and report any issues with its configuration.
- Review Claude Code's updated verification report.
- Confirm that Claude Code detected the missing action attribute on the form. The report should mention that the form has no submission endpoint or that the action attribute is missing.
Why does this matter?
This is the whole point of the verification workflow. Before creating a pull request, Claude Code can catch structural issues that would otherwise slip through code review. A missing form action is subtle enough that a human reviewer might miss it, but the browser verification catches it by inspecting the actual DOM.
Now restore the original code so your test page is back to a clean state.
- In index.html, find the <form> tag you just edited:
<form method="POST">
- Add the action attribute back so it looks like this:
<form action="/submit" method="POST">
- Save index.html.
Claude Code did not catch the defect?
- Make sure you saved index.html before asking Claude Code to re-verify. The local server serves the file from disk, so unsaved changes are not visible.
- Try being more specific in your prompt. Ask Claude Code to "inspect the form element and check that it has an action attribute" so it focuses on the right area.
- You can also run browser-use state yourself in a separate terminal to confirm the form element appears without the action attribute in the DOM output.
- Claude Code is still not catching the missing action attribute.
Secret mission
Add AgentMail Email Verification Testing
Your verification workflow can open pages and click buttons. But can it handle a full signup flow that requires email verification? In this mission, you will use Browser Use Cloud's built-in AgentMail to create ephemeral inboxes, receive verification emails, and complete end-to-end auth flows autonomously.
Before you go
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs locally with a free cloud tier, so there are no ongoing costs.
Resources you used:
- browser-use CLI (installed to your system PATH).
- Cloud browser API key (saved to ~/.browser-use/config.json).
- browser-use skill for Claude Code (installed to ~/.claude/skills/browser-use/).
- Project-local /verify-ui skill (.claude/skills/verify-ui/SKILL.md).
- CLAUDE.md with your pre-PR verification workflow.
- index.html test page.
- Local Python HTTP server (if still running on port 8080).
Keep everything running
No action needed. Choose this if you are still actively building and want the browser-use CLI, cloud access, and your verification workflow ready to go.
- Your browser-use CLI, cloud API key, and installed skills will persist across terminal sessions.
- Your CLAUDE.md and /verify-ui skill will load automatically in future Claude Code sessions within this project.
- If you left the Python HTTP server running, it will stop when you close the terminal.
Pause - I'll come back to this later
Shut down any running processes to free up system resources. Your files and configuration stay in place for when you return.
- Stop the local Python HTTP server if it is still running. Press Ctrl + C in the terminal where you started it.
- Close any open browser-use sessions by running browser-use close.
- Exit Claude Code.
- Your CLI installation, cloud API key, skills, and CLAUDE.md will all be waiting when you come back.
Delete - I don't want to use this again
Remove all project resources and start fresh.
- Stop the local Python HTTP server if it is still running. Press Ctrl + C in the terminal where you started it.
- Close any open browser-use sessions by running browser-use close.
- Delete the test page: index.html.
- Delete the project-local skill directory: .claude/skills/verify-ui/.
- Remove the pre-PR verification section from your CLAUDE.md, or delete the file entirely if you created it for this project.
- Delete the global browser-use skill: rm -rf ~/.claude/skills/browser-use.
- Delete your cloud API key configuration: rm -rf ~/.browser-use/.
- Uninstall the browser-use CLI if you no longer need it. Check the installer documentation for the uninstall command specific to your system.
Mission accomplished
You Did It
Claude Code now has eyes on your web app. You built a complete browser-based verification workflow that catches real issues before they ever make it into a pull request.
Here's what you learned:
- Installed the browser-use CLI with cloud browser access and provisioned an API key through agent self-registration. No manual signup required.
- Created a CLAUDE.md pre-PR verification workflow and a reusable /verify-ui skill that Claude Code follows automatically before creating pull requests.
- Ran a real end-to-end verification cycle where Claude Code opened a page, inspected elements, tested interactions, took screenshots, and detected a deliberate defect.
- Extended the workflow with AgentMail to test email verification flows through the cloud browser, with ephemeral inboxes that clean up automatically.
Ready to quiz yourself?