# Verify a PR's UI end to end (/use-cases/design/pr-ui-verification)



Copy this prompt to start your first task:

<Prompt>
  Set up a daily follow-up to verify this PR's UI: PR #[number] / branch [branch-name], requirements: [describe]. Check whether it matches the requirements, screenshot the key states, and flag anything broken. Keep checking once a day until it's merged or closed.
</Prompt>

<LivePreview component="NewThread" scenario="{ draft: &#x22;Set up a daily follow-up to verify this PR's UI: PR #[number] / branch [branch-name], requirements: [describe]. Check whether it matches the requirements, screenshot the key states, and flag anything broken. Keep checking once a day until it's merged or closed.&#x22; }" />

## What is this workflow? [#what-is-this-workflow]

"Verify a PR's UI end to end" is the recurring job of turning a PR link into a real verdict instead of a single screenshot. The teammate confirms the PR's identity — link, branch, head commit, merge status, CI status, and preview URL — then captures real, labeled screenshots of exactly the states the request calls for, and reports back three separate results (visual, frontend implementation, and end-to-end) instead of one collapsed "looks good." If something blocks verification — a login wall, a build failure, a fixture mismatch, a missing dependency, or a backend that isn't running — it names the blocker instead of guessing. Every check updates the same Artifact link, and an optional watcher can re-verify automatically whenever CI, the preview, or the head commit changes.

<Callout type="warn">
  This teammate reads PRs, runs tests, opens previews, takes screenshots, and reports on its own. Five things always wait for a human: merging the PR, pushing to or rewriting the branch, changing shared preview configuration, publishing to production, and requesting or expanding repo write access.
</Callout>

## How to use this workflow [#how-to-use-this-workflow]

<Steps>
  <Step>
    ### Hire a Full-Stack Code Review Expert, not a screenshot tool [#hire-a-full-stack-code-review-expert-not-a-screenshot-tool]

    Open **AI Teammates** in the sidebar, click **Hire AI Teammate**, and pick the **Full-Stack Code Review Expert** template. Its default bio is generic reproduction-and-report work. Replace it on the Profile step so it knows this job is verification of a specific PR, not a general check-in:

    <Prompt>
      You verify a PR's UI end to end. First confirm the PR, branch, head commit, and CI status. Screenshots come from the real target-branch page, never a guess or old image, each one labeled with scenario, state, and capture time. Report visual and frontend-implementation results separately, never one combined 'looks good.' Hit a login wall, fixture mismatch, build failure, or missing backend? Stop and report the blocker. Never merge, push, change preview config, or request write access.
    </Prompt>

    <LivePreview component="CreateAssistantPage" scenario="{ focus: &#x22;profile&#x22;, initialState: { start: &#x22;template&#x22;, templateRef: &#x22;@helio/code-reviewer&#x22;, name: &#x22;Full-Stack Code Review Expert&#x22;, bio: &#x22;You verify a PR's UI end to end. First confirm the PR, branch, head commit, and CI status. Screenshots come from the real target-branch page, never a guess or old image, each one labeled with scenario, state, and capture time. Report visual and frontend-implementation results separately, never one combined 'looks good.' Hit a login wall, fixture mismatch, build failure, or missing backend? Stop and report the blocker. Never merge, push, change preview config, or request write access.&#x22; } }" />

    [More on hiring →](/ai-teammates/hire-an-ai-teammate)
  </Step>

  <Step>
    ### Connect GitHub [#connect-github]

    The teammate needs read access to PRs, commits, checks, and deployment URLs. A workspace admin installs the GitHub App once (**Settings → Integrations**), then grants this teammate the repo. The grant narrows which repositories the teammate can reach, not the permission level — the teammate's token carries whatever permissions the installed GitHub App has, so if the App was installed with write access for coding teammates, this teammate technically has it too. The boundary that keeps verification read-only is the bio above ("you never push, merge, or rerun anything"), so keep that line in. [Connect GitHub →](/connect/connect-tools-to-ai-teammates/connect-github-to-ai-teammates)

    <LivePreview component="AssistantIntegrations" />
  </Step>

  <Step>
    ### Set up two preview paths [#set-up-two-preview-paths]

    The default path is the hosted preview: open the deployment URL from the PR's checks, wait for the target component to actually load, and screenshot exactly the states the request called for, never just the homepage.

    The fallback is a local device, for when the hosted preview sits behind a login wall the teammate can't get past. In **Settings → Devices** (a personal setting, not a workspace-admin one, any member can add their own), click **Add a device** and run the connect command on a machine with the project's toolchain already installed. When hiring or configuring the teammate, the Engine step's **Runs on** field lets you point it at that device instead of Helio Cloud for this kind of work. Full setup: [Run on your own machine →](/connect/devices)
  </Step>

  <Step>
    ### Send one complete verification request [#send-one-complete-verification-request]

    A request missing the target state or the delivery location isn't ready to run against, it just invites a guess. State the PR, the scenario, the expected state, what's allowed, what's off-limits, and where the report should land:

    <Prompt>
      Verify PR #[number] (branch [branch-name]): [describe the expected behavior — what should happen and what shouldn't]. Check the hosted preview first, fall back to your device if it's login-gated. Screenshot [state one] and [state two]. Don't merge or push anything. Post the report as an artifact in this channel.
    </Prompt>

    <LivePreview
      component="AssistantChat"
      scenario="{ assistantName: &#x22;Full-Stack Code Review Expert&#x22;, messages: [
    { author: &#x22;user&#x22;, text: &#x22;Verify PR #482 (branch feature/sidebar-unread-count): the sidebar thread should show an unread badge that clears on open. Check the hosted preview first, fall back to your device if it's login-gated. Screenshot the unread state and the cleared state. Don't merge or push anything. Post the report as an artifact in this channel.&#x22; },
    { author: &#x22;assistant&#x22;, text: &#x22;Confirmed PR #482, head commit a3f91c2, CI green, deployment URL live. Hosted preview loaded without a login wall, so staying on that path, no need for the device fallback. Opening the sidebar now and screenshotting both states before I check anything else.&#x22; },
  ] }"
    />
  </Step>

  <Step>
    ### Split the conclusion into three layers [#split-the-conclusion-into-three-layers]

    A single "looks good" hides exactly the failure that matters most: visual evidence and implementation correctness can diverge. If a preview fixture defaults `canEdit` to true, a screenshot meant to prove the read-only state will show edit controls that shouldn't be there, even though the frontend code and its tests are completely correct. The right conclusion isn't "broken" or "works," it's "frontend implementation and tests hold up, but this preview's fixture can't produce valid visual evidence for the read-only state":

    <LivePreview
      component="AssistantChat"
      scenario="{ assistantName: &#x22;Full-Stack Code Review Expert&#x22;, messages: [
    { author: &#x22;user&#x22;, text: &#x22;So does the unread badge work or not?&#x22; },
    { author: &#x22;assistant&#x22;, text: &#x22;Three separate answers. Visual: confirmed, both states screenshotted from the real preview at commit a3f91c2, badge shows on new messages and clears on open. Frontend implementation: confirmed, the relevant unread-state tests and typecheck pass, and the clear-on-open handler fires correctly in the DOM. End-to-end: not verified, the preview's mock data doesn't hit the real read-receipt endpoint, so I can't confirm the cleared state persists after a refresh against a real backend. That last piece needs a real environment run before I'd call this fully done.&#x22; },
  ] }"
    />
  </Step>

  <Step>
    ### Publish the report, and keep it on one link [#publish-the-report-and-keep-it-on-one-link]

    The report goes out as an Artifact, visible to your organization, not the public internet. A follow-up check on the same PR updates that same artifact instead of creating a new one, so anyone with the link already open sees the latest result on refresh.
  </Step>
</Steps>

## Automations [#automations]

Turn recurring verification into an automation instead of re-running it by hand. Open **Automations** in the sidebar, click **Create via Chat**, and describe the trigger in the New Thread that opens:

<Prompt>
  Watch PR #[number]. Every 30 minutes, check if the head commit, CI status, or deployment status changed. If nothing changed, stay quiet. If CI fails, post the failing job. If the preview becomes ready, confirm it actually loads, then let me know verification can start. Never merge, push, or rerun anything yourself.
</Prompt>

The same shape covers two other cases worth setting up once you're doing this regularly: re-running the verification matrix and refreshing the same artifact whenever a new commit lands on a passing PR, and a weekly digest of open UI PRs that have gone stale (no review in days, red CI, a 404 or login-gated preview, or a report that's fallen out of date).

**Approval:** This flow runs on its own — reading the PR, running tests, opening previews, and screenshotting the requested states don't need your sign-off. Merging the PR, pushing to or rewriting the branch, changing shared preview configuration, publishing to production, and requesting or expanding repo write access always pause for a human instead. See [Control](/ai-teammates/control) for how approvals work more generally.

## Tips for Better Results [#tips-for-better-results]

| Tip                                                           | Description                                                                                                                                                                                                                          |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| State the PR, scenario, and expected state together           | A request missing the target state or delivery location can't be run against — it just invites a guess. Give the PR, branch, expected behavior, what's allowed and off-limits, and where the report should land, all in one message. |
| Let it fall back to a device when the hosted preview is gated | If the hosted preview sits behind a login wall, connect a device under **Settings → Devices** and point the Engine's **Runs on** field at it, instead of settling for stale screenshots.                                             |
| Read all three layers, not just one verdict                   | Visual evidence and implementation correctness can diverge — a fixture defaulting `canEdit` to true can make a correct read-only implementation look broken in a screenshot.                                                         |
| Keep re-checks on the same artifact                           | A follow-up check on the same PR updates the same link instead of producing a new report each time, so anyone with the tab open sees the latest result.                                                                              |

## Common Questions [#common-questions]

<Accordions type="single">
  <Accordion title="What happens if the hosted preview is behind a login wall?">
    The teammate falls back to a connected device set up under **Settings → Devices**, provided the Engine's **Runs on** field points to that device for this kind of work.
  </Accordion>

  <Accordion title="Can this teammate merge the PR or push code?">
    No. Merging the PR, pushing to or rewriting the branch, changing shared preview configuration, publishing to production, and requesting or expanding repo write access always wait for a human.
  </Accordion>

  <Accordion title="Why three separate results instead of one 'looks good'?">
    Visual evidence and implementation correctness can diverge — a fixture defaulting `canEdit` to true can make a correct read-only implementation look broken in a screenshot even though the code and tests are fine. Splitting visual, frontend implementation, and end-to-end catches that gap instead of hiding it.
  </Accordion>

  <Accordion title="What happens if verification can't be completed?">
    The teammate stops and names the specific blocker — a login wall, a build failure, a fixture mismatch, a missing dependency, or a backend that isn't running — instead of guessing.
  </Accordion>

  <Accordion title="Does a re-check produce a new report?">
    No. It updates the same Artifact link, so anyone who already has it open sees the latest result on refresh. An optional PR watcher can also trigger re-verification automatically when CI, the preview, or the head commit changes.
  </Accordion>
</Accordions>

<Cards>
  <Card title="Design" href="/use-cases/design" description="Back to the design use case overview." />

  <Card title="Catch UI feedback and ship the fix" href="/use-cases/design/usability-review" description="For UI feedback that hasn't turned into a PR yet." />

  <Card title="Connect GitHub" href="/connect/connect-tools-to-ai-teammates/connect-github-to-ai-teammates" description="Grant repository access to the teammates that need it." />
</Cards>
