Skip to content

Daily

Catch visual changes on your key pages every day

Each page in your sheet is compared with how it looked before, and real visual changes become Linear issues for your team.

Runs
Daily
Apps
Google Sheets, Linear
AI
Yes, uses the built-in AI allowance
Access
Sheets read; Linear write

Send this to your assistant

Create a ClickRuntime automation: every day, take a screenshot of each URL in my Pages sheet, compare it with the last approved screenshot using AI, and create a Linear issue when something has visibly changed.

Paste it into your assistant. It tells you what it will send or change before it runs live.

First time? Adding ClickRuntime to your assistant takes about two minutes.

Why use it

Why teams use this automation

A web team ships several times a week. Automated tests check that pages load and buttons work, but nobody notices when a CSS change pushes the pricing table under the footer or a banner covers the signup button on the landing page. These problems tend to be found by customers or by the marketing team days later, after traffic has already been lost.

This automation looks at each important page once a day, compares it with the last known good version and opens a Linear issue only when something has visibly changed in a way worth checking. Your team gets a short, reviewable list instead of a manual click-through of every page.

What you get out of it

  • Layout breaks are found the next morning

    A broken page is reported within a day of the change that caused it. That makes the cause easy to find, because only a few deploys need checking.

  • Only meaningful changes become issues

    AI compares the two screenshots and ignores small differences such as a rotating testimonial or a new date. Your backlog is not filled with noise from pages that change on purpose.

  • The page list lives in a sheet

    Marketing, design and engineering can all add pages they care about without touching code. A new campaign page is covered as soon as its row is added.

  • Issues arrive where the work happens

    Each finding becomes a Linear issue with the page and a description of what changed. It can be assigned, prioritised and closed like any other bug.

How it works

What happens, step by step

  1. Every day, ClickRuntime reads the list of pages from your Google Sheet.

  2. A fresh screenshot of each page is taken and set next to the last approved one.

  3. AI compares the two images and decides whether anything has visibly changed in a way that matters.

  4. For each real change, an issue is created in Linear with the page address and a short description of the difference.

  5. Pages that already have an open issue are not reported again until it is closed.

Before it runs live

  • Connect your Google Sheets account and pick the spreadsheets it may use
  • Connect Linear

What you get

RunsDaily
Catch visual changes on your key pages every daytoday, 9:00Succeeded
Linear · Web teamVisual change on https://northwind.example/pricing: the plan comparison table now overlaps the footer on desktop.

Build your own

Need it to work differently?

This template is a starting point. Copy the prompt and change it, or describe a different automation from scratch, with your own conditions, more apps or an AI step. Your assistant writes it, tests it and runs it on ClickRuntime.
  • Your own rules

    Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.

  • Any number of apps

    One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.

  • AI where it helps

    Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.

  • On a schedule or on each event

    Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.

Changes you can ask for

  • Run it at a different time, more or less often, or only on weekdays
  • Change what the AI looks for, or how it writes the result
  • Add another app, for example also send it to Slack
  • Combine it with other Google Sheets and Linear steps into one automation

Under the hood

The code that runs this automation

This is the Python script that runs each time the automation starts. Your AI assistant writes it for you when you send the prompt, and you allow each step in your assistant. To change how the automation works, describe the change to your assistant and it updates the script for you. For every function it can use, see the script reference.
visual_regression_checks_for_urls_in_a_sheet.pyexample
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, credentials, http, ai, state, log

SHEET_ID = "your-spreadsheet-id"
LINEAR_TEAM_ID = "your-team-id"
SHOT_API = "https://api.screenshot-service.example/v1/compare"

@on_trigger
def run(event):
    sheets = build("sheets", "v4", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False)
    urls = [r[0] for r in sheets.spreadsheets().values().get(spreadsheetId=SHEET_ID, range="Pages!A2:A")
            .execute().get("values", []) if r]
    open_issues = state.get("open") or {}
    created = 0
    for url in urls:
        if url in open_issues:
            continue
        diff = http.post(SHOT_API, json={"url": url}, headers={"Authorization": credentials.secret("SCREENSHOT_API_KEY")}).json()
        try:
            verdict = ai.generate(f"Visual differences found on {url}:\n{diff.get('summary', '')[:1500]}\n"
                                  "Ignore dates, counters and rotating images. Reply 'none' or one sentence on what broke.",
                                  max_output_tokens=80).text.strip()
        except ai.AIError as e:
            log.warning("AI unavailable", {"code": e.code})
            break
        if verdict.lower().startswith("none"):
            continue
        http.post("https://api.linear.app/graphql", headers={"Authorization": credentials.secret("LINEAR_API_KEY")},
                  json={"query": "mutation($i:IssueCreateInput!){issueCreate(input:$i){success}}",
                        "variables": {"i": {"teamId": LINEAR_TEAM_ID, "title": f"Visual change on {url}", "description": verdict}}})
        open_issues[url] = True
        created += 1
    state.set("open", open_issues)
    return {"checked": len(urls), "issues": created}

FAQ

Common questions

Where do the screenshots come from?
A screenshot service captures each page in a standard browser size, and the images are kept in your Google Drive. The first run for a page saves it as the baseline that later runs compare against.
How do I accept an intended change as the new baseline?
Close the Linear issue as expected and the latest screenshot becomes the new baseline for that page. Later runs then compare against the updated design.
Will dynamic content cause false alerts?
The comparison is told to ignore content that changes by design, such as dates, counters and rotating images. For pages that change heavily every day, you can mark a row to skip the check.
What permissions does it need?
Sheets read; Linear write. Nothing else in your accounts is used.
Does it need AI?
Yes. It uses ClickRuntime's built-in AI, so you don't need an OpenAI or Anthropic key. Every plan includes a monthly AI allowance.
How many runs does it use?
One run each time it runs (daily). Checks that find nothing to do and stop right away aren't counted.
Can I change how it works?
Yes. Describe the change to your AI assistant, for example a different schedule, channel or filter. It updates the automation, tests it and tells you what changed.

Set up “Catch visual changes on your key pages every day” from your assistant

Copy the prompt above, or connect your assistant first. Free plan, no credit card.