Skip to content
BridgeDocs
Qiksy Bridge · Documentation

The browser, readable by your agent

Install the extension, wire the MCP bridge into your coding agent, and let it read what actually happened in the tab — findings, selectors, failing responses — instead of your description of it.

What Qiksy is

A manual-QA sidekick that lives in the browser you already test in — and hands everything it sees to your coding agent.

Qiksy watches the page while you use it: console and JavaScript errors, failed requests with the server’s actual error body, accessibility and markup problems, form submits that go nowhere. It fills forms with realistic data, keeps isolated logins side by side in one window, and turns a session into a paste-ready report.

The part that matters for developers is the bridge: an MCP server that exposes that live state to Claude Code, Cursor, Cline, Windsurf, Zed or VS Code. You say “fix what Qiksy found on this page” and the agent has the findings, the selectors and the failing responses — from the session you are already logged into.

Worth knowingThe distinction worth keeping in mind: Qiksy never launches, switches or steals focus from a browser. It works inside your existing tab — including a background one — which is what separates it from a driver that pops a fresh window every run.

What it does not do

By default it senses and reports; it does not click, type, submit or navigate the app under test. That boundary is deliberate — it is what makes a tool that watches other people’s applications trustworthy. There are exactly two knowing exceptions, and both start with a press of yours: a scenario you recorded yourself, which replays that flow and can follow it across pages and sites (see Scenarios), and Agent control, which hands the clicking to your own coding agent and is off until you turn it on (see Agent control).

Installing the extension

  1. 1Install from the Chrome Web Store.
  2. 2Pin it to the toolbar — you will open the panel often.
  3. 3Open the site you are testing. The toolbar icon opens the popup — settings, the per-site switch, the licence and the bridge toggle. The working panel is opened from the page itself: the round Q button Qiksy injects, or Alt+Shift+Q.

Nothing to configure, no account, no key. The free tier is usable on its own — the panel, audits, form filling and isolated logins all work without a licence. The session report and the MCP bridge are Pro (see Plans).

Permissions, and why each exists

PermissionWhy
Access to the sites you visit (<all_urls>)Qiksy has to work on whatever you are testing — a staging host nobody can enumerate in advance. The per-site switch in the popup decides where it actually runs.
scriptingInjects the panel and reads the DOM: selectors, form fields, ARIA state.
webRequestA failed request is only useful with its status and response body — the difference between “something broke” and “the API says the token expired”.
cookiesIsolated logins only. Keeping several sessions apart means intercepting the site’s cookies, session cookies included. This one is serious enough that the extension asks for its own explicit confirmation the first time, naming exactly what it touches — it is never silently on.
declarativeNetRequestKeeps each isolated login’s requests carrying its own identity instead of the browser’s shared one.
storage, unlimitedStorageYour settings, the licence and the current session’s findings — locally.
contextMenus, alarmsThe right-click entry points and the timers behind licence checks and session upkeep.
CarefulQiksy reads what the tab shows you and keeps it local. It is not a telemetry product — findings leave your machine only when you export them, or when your own agent asks for them over the local bridge.

The panel

Everything Qiksy noticed on this page, ranked, each with the selector you need to act on it.

Audit

One pass over the live page: console errors, uncaught exceptions, failed and slow requests, accessibility problems, markup that will bite (duplicate ids, labels pointing nowhere, inputs with no name), and forms whose submit does not go anywhere.

Every finding carries a severity, a CSS selector and the detail behind it. Selectors are the whole point — a finding you cannot locate is trivia.

Smart form fill

Qiksy reads the form — types, labels, patterns, required flags — and fills it with data that is plausible rather than random, so validation behaves the way it will for a real user. Fill one field or the whole form; custom widgets and multi-step flows are handled field by field.

Isolated logins

Open the same application as several users in one window, each tab with its own cookies, localStorage, IndexedDB and Cache Storage. Admin next to customer, seller next to buyer — no incognito windows, no separate browser profiles, no logging out. They live in the Logins tab of the panel: + Isolated tab for a fresh empty session, or on a saved login to open that one isolated. The first time, it asks for its own confirmation — cookies are what isolation moves, so that prompt is separate from every other switch.

Worth knowingIsolation is about identity, not focus. Sessions stay independent in the background; a browser only ever renders one tab actively, so an agent drives one at a time.

Your language

The panel and the popup speak seven languages — English, Deutsch, Español, Polski, Português, Русский, Українська. On the first run Qiksy takes the one your browser is in; Language in the popup overrides that, which is the case in QA more often than elsewhere — a machine set up in one language, a team that works in another.

Worth knowingFindings and bug reports stay in English whatever the panel is set to. They get pasted into a tracker, and the person who fixes the bug is often in another country — a defect described in a language they do not read is a defect nobody fixes.

Exploratory tour

A checklist generated from what the page actually contains — the flows worth trying here, not a generic list. Useful when you inherit a feature and have no idea where the soft spots are.

Report

The session as something a human can read and a ticket can hold: what was tested, what broke, the repro steps, the selectors, the failing responses. Paste-ready.

Scenarios — record a flow once, replay it later

The form you fill twenty times a week, done by hand once and pressed once thereafter.

Press Record in the Scenarios tab and fill the form the way you normally would — by hand, with ⚡ Fill, or both. Press Stop, give it a name, and it is saved for this site. Afterwards replays it: the values go back into the fields they came from, the step’s own Next is pressed, and the run stops where you would stop.

It follows the route you walked

A flow is rarely one page. A recording keeps the page each step happened on, so a replay follows the same route — the next step of a wizard, a sign-in hand-off, a payment page on somebody else’s domain — in the same tab. At every page boundary it stops and waits for Continue: the page has just loaded, and typing into an application because storage said so is the one thing this product does not do.

Worth knowingIt never guesses past a change. The first field the page no longer has ends the run, and the verdict NAMES that field rather than reporting a number — a green “Done 8/8” over a form holding five values is worse than a plain failure.

Editing the data, not the recording

{ } opens the run’s data as a plain list of fields — change an email, a date, a company name and run it again; 🎲 refills the lot with fresh plausible values. So one recording covers “the same flow with different data”, which is most of what a regression pass actually is. An upload field can be given a file of your own, kept in the browser and used on every run.

A set, not a pile

Scenarios group by project and tags, and a whole project runs as one set with a single answer about the group. Export writes them to a file a colleague can import.

What is deliberately NOT recorded

Passwords and card numbers are recorded as fields, never as values — a scenario is a document that can be exported, mailed and put in a repository, and a saved password would ride along. The replay stops at such a field and asks you to type it.

CarefulAn imported scenario is stripped of every address that leaves its own site before it can run. A file someone sends you is a document that can move your browser, so the addresses it may move it to are the ones you already trust.

Where it sits

The Scenarios tab of the panel, and it is a Pro feature (free during the trial). Your agent can read, run and write them through the bridge as well.

The MCP bridge

Switch the bridge on in the extension, paste one block into your agent’s config. No clone, no local path, no version to pin.

agent  ⟷ (MCP over stdio)  ⟷  qiksy-mcp  ⟷ (WebSocket @ 127.0.0.1)  ⟷  extension

The extension is the WebSocket client — a service worker cannot listen on a socket — and the bridge is the server, bound to loopback only. Nothing is reachable from outside your machine.

First: switch the bridge on in the extension

The extension side is off until you turn it on, and the two halves authenticate to each other with a shared token. Do this before touching your agent’s config, or the bridge will sit silent with nothing to explain why.

  1. 1Open the toolbar popup → Agent bridge · MCP and switch it On.
  2. 2Accept the one-time consent prompt. Until you do, the bridge reports blocked and refuses to connect.
  3. 3Press Generate to mint a token, then 📋 Copy agent config — that gives you the exact block for your editor, token and port already filled in.
Worth knowingThe status line under the toggle (🟢 / 🟡 / 🔴) is the first place to look when something does not connect: off, connecting, waiting, rejected, lapsed, blocked, replaced.

Two ways in — pick one

Either hand the whole job to your assistant, or place the config yourself. Both end in the same place; neither needs the other.

A. Let Claude do it

Press 📋 Copy agent config (JSON) in the popup, then paste this into Claude (Claude Code, Cursor, whatever you use) together with the copied block. It knows where its own config lives.

Set up the Qiksy browser bridge for me. Below is the MCP server config from the
Qiksy extension popup. Do this, and tell me if a step needs me:

1. Work out which MCP client I am using and where ITS config file is (Claude Code:
   .mcp.json in the project or "claude mcp add"; Cursor: ~/.cursor/mcp.json;
   Windsurf: ~/.codeium/windsurf/mcp_config.json; VS Code: .vscode/mcp.json;
   Claude Desktop: the claude_desktop_config.json for this OS; Zed: settings.json
   under "context_servers").
2. Merge the "qiksy" server into it WITHOUT dropping servers that are already there.
   Keep the token exactly as given — it must match the extension.
3. Tell me to restart / reload the client, then verify by calling qa_status and show
   me the result. If it says the extension is not connected, tell me to switch the
   bridge On in the Qiksy popup — do not try another browser tool, there is none.

<paste the JSON from the popup here>

B. Place it yourself

The config below is the same for every client — only the file it goes in differs. Merge it in; do not overwrite servers you already have.

ClientWhere the file lives
Claude CodeRun the command below — or edit .mcp.json in the project root (shared with the repo) / ~/.claude.json (just you).
Cursor~/.cursor/mcp.json for every project, or .cursor/mcp.json inside one.
Windsurf~/.codeium/windsurf/mcp_config.json
VS Code.vscode/mcp.json in the workspace.
Claude DesktopmacOS: ~/Library/Application Support/Claude/claude_desktop_config.json · Windows: %APPDATA%\Claude\claude_desktop_config.json
Zed~/.config/zed/settings.json, under context_servers.
Worth knowingAfter editing, restart the client — MCP servers are read at start-up, so a saved file alone changes nothing. Then ask the agent for qa_status: a URL and three counts means it worked.

Claude Code

claude mcp add --transport stdio qiksy \
  --env QIKSY_MCP_TOKEN=YOUR_TOKEN \
  -- npx qiksy-mcp --port 7333
Worth knowingOn Windows PowerShell the backslashes above are a Unix line-continuation and will break the command — put it on one line, or use a backtick (`) at each line end.

Claude Desktop, Cursor, Windsurf

{ "mcpServers": { "qiksy": {
  "command": "npx",
  "args": ["qiksy-mcp", "--port", "7333"],
  "env": { "QIKSY_MCP_TOKEN": "YOUR_TOKEN" }
} } }

Zed

{ "context_servers": { "qiksy": {
  "source": "custom",
  "command": "npx",
  "args": ["qiksy-mcp", "--port", "7333"],
  "env": { "QIKSY_MCP_TOKEN": "YOUR_TOKEN" }
} } }

VS Code

{ "servers": { "qiksy": {
  "type": "stdio",
  "command": "npx",
  "args": ["qiksy-mcp", "--port", "7333"],
  "env": { "QIKSY_MCP_TOKEN": "YOUR_TOKEN" }
} } }
CarefulThe token is not optional. Without QIKSY_MCP_TOKEN the bridge closes every connection with auth failed before any data moves, and the extension will not dial out either — you get silence, not an error naming the cause. Use the same value the popup generated, and the same port on both sides.

The package is qiksy-mcp on npm, versioned in lockstep with the extension. npx always fetches the current build, so there is no version to keep in step by hand. Node 18 or newer.

CarefulThe bridge as a whole is a Pro surface. The extension’s free tier stays fully usable, but the socket refuses to connect without a valid licence or an active trial — when a trial lapses, every tool fails with a message saying so, qa_export included. Do not design a free-tier integration around the read-only tools.

Several agent windows, one browser

Open a second editor window on the same project — or a third — and they all reach the same browser through the same toggle. There is nothing to configure: no second port, no second token, no switching in the popup.

Each window starts its own copy of qiksy-mcp, but only one process can own the loopback port. The first to take it holds the extension’s socket; the others notice, dial it with the same token and relay through it. Close that window and the rest take the port over on their own — the extension reconnects without being told.

Worth knowingReading is safe from every window. When two agents drive, give each its own tab — pass the tabId from qa_tabs, or let each open its own isolated login with qa_open_isolated. Two agents clicking in the same active tab will fight over it.

Your agent is briefed for you

You do not have to explain Qiksy to your agent, or paste rules into a project file. The bridge hands it a short operating manual the moment it connects: which tools read and which act on the page, that a snapshot is an accessibility tree rather than a screenshot, how to address a specific tab, and which two failures are yours to fix rather than its to retry. Nothing to configure — it arrives with the connection.

Checking it works

Open a page with the extension active, then ask the agent to call qa_status. You should get the URL and the current error, warning and form counts. If it reports no connection, see Troubleshooting.

Brief your agent, once

Paste one prompt. Your assistant sets the bridge up and writes a short guide into the project, so every session after this one already knows what Qiksy can and cannot do.

An assistant that has never met Qiksy will guess: it will look for screenshots that do not exist, try to run JavaScript that is refused by design, and give up on "not connected" instead of telling you to flip a switch. One paste fixes that for the whole project — the guide lands in your repo and is read on every future session.

The prompt

Set up the Qiksy browser bridge for this project, then leave a guide behind for future sessions.

1. Check whether the Qiksy MCP server is already configured for you. If it is not, add it:
   claude mcp add --transport stdio qiksy --env QIKSY_MCP_TOKEN=<TOKEN> -- npx qiksy-mcp --port 7333
   I will give you the token — it comes from the Qiksy extension popup (Agent bridge · MCP → On → Generate),
   or from pressing "Connect this browser" in a Qiksy web app. Ask me for it; never invent one.

2. Verify the connection by calling qa_status. If it answers "Qiksy extension is not connected",
   tell me to switch the bridge on in the extension popup and stop — do not substitute another
   browser tool, there is none.

3. Write .claude/qiksy-bridge.md in this project (create the folder if needed) describing, for
   whoever works here next:
   - what the bridge is: it drives the browser I already have open, in the tab I am looking at,
     and never launches, focuses or steals a window;
   - the tools you actually have, grouped: read-only (qa_tabs, qa_status, qa_snapshot, qa_read,
     qa_styles, qa_storage, qa_findings, qa_export, qa_screenshot, qa_wait_for), Qiksy's own surfaces
     (qa_open_panel, qa_run_audit, qa_tour, qa_report, qa_spotlight), and agent control which needs
     Qiksy Pro plus a one-time consent
     (qa_click, qa_type, qa_type_many, qa_press, qa_upload, qa_wait_ready, qa_navigate, qa_reload,
     qa_open_isolated, qa_close_tab, qa_mock — answering a request from a rule instead of the
     server, for the failure paths a live backend will not produce — and qa_storage's write ops);
   - how to WAIT: qa_wait_for takes one condition — appears / disappears / enabled / text / textGone /
     countOf / announced / urlContains — and returns the moment it comes true, or says what it saw at
     the deadline. Use it instead of polling qa_snapshot, which renumbers every ref each time;
   - how to target things: refs from a fresh qa_snapshot beat CSS selectors, and refs go stale after
     a re-render, so snapshot again after qa_wait_ready;
   - what it cannot do, so nobody wastes a turn trying: no arbitrary JavaScript — every verb is a
     closed vocabulary, you name an element and never a program. SCREENSHOTS ARE AVAILABLE now
     (qa_screenshot, page or one element, with the panel hidden and password and card fields covered),
     with one real condition: the browser photographs the window's ACTIVE tab, so a background tab
     cannot be photographed and Qiksy refuses rather than handing over a page you did not ask about.
     Styles, element geometry and web storage are available too
     (qa_styles, qa_snapshot geometry:true, qa_storage) — they were once listed here as impossible,
     which was a wrong inference from the no-eval rule. Still out of reach: anything inside an iframe
     (payment forms included), captchas, and qa_navigate stays on the site under test;
   - that a click ANSWERS with what changed once the page settles, so an action does not need a
     follow-up snapshot to find out whether it did anything;
   - that qa_report takes a `path` and should always be given one — the report is a self-contained
     HTML document with embedded screenshots and belongs in a file, not in the conversation;
   - one line on what to do when it says it is not connected: tell the human, do not switch tools.

4. Show me the file when it is written, and keep it updated if the bridge gains or loses tools.
Worth knowingPrefer to skip the round trip? Copy mcp/AGENT-GUIDE.md from the package straight into your project — it is the same guide, already written.

Why a file in the repo, not just a chat message

A chat message lasts one session. Project files are read at the start of every session by Claude Code, Cursor and the rest — so the next person to open the repo gets an assistant that already knows a snapshot is a tree, that acting needs consent, and that "not connected" is a switch in the popup rather than a dead end.

The five switches, and which ones are per-tab

Everything Qiksy does is off until you turn it on, and the switches answer different questions. Two of them are global, one is per site, one is PER TAB — and the per-tab one is the step people miss.

They all live in the toolbar popup, top to bottom, in the order you actually turn them on. Nothing here is a preference: each one widens what Qiksy is allowed to do, which is why none of them is on by default.

SwitchScopeWhat it decides
Show QiksyEverywhereWhether you SEE Qiksy — the round Q button and the panel. It hides them and nothing else: the page is still watched and the agent bridge still answers, on every tab. Since 1.8.1.
On this sitePer siteWhether Qiksy runs on this origin — this is the real off switch, and the one that makes a disabled Qiksy observe nothing. Changing it reloads the tab. Use it to keep Qiksy out of a site you are not testing.
Agent drives this tabPer tabWhether this tab is in the agent’s session. This is the one to turn on for every tab you want driven — see below.
Agent controlOnce, globallyWhether the agent may ACT at all — click, type, submit, write storage, attach files. Shows the full disclosure and asks you to confirm. Turning it off drops the consent, so turning it back on asks again.
Agent bridge · MCPOnce, globallyThe loopback connection to the program you run (your coding agent). Generates the token you paste into its config.

Working with Qiksy out of sight

Turn Show Qiksy off and the round Q button and the panel disappear from every page — while findings keep being collected, the session keeps recording, and your agent keeps reading and driving through the bridge exactly as before. Nothing to re-enable per tab, and a tab opened afterwards is in the same state: connected, invisible. It is the setup for demos, screenshots, screen shares, and any page whose own bottom-right corner you need free. Flip it back on and the button is there again, no reload.

Worth knowingHidden is not off. If you want Qiksy to genuinely stop — no watchers, no bridge, nothing of ours on the page — that is On this site, which returns before any of it loads.

Why “Agent drives this tab” is per tab

The agent’s session is a SET of tabs you opt into, not “whatever tab is in front”. That is deliberate, and it buys three things at once: the agent keeps a page while you look at something else, work continues in a background tab, and several tabs can be driven at once — a form here, the mail with the sign-in code there.

It is also the stricter of the two designs. Before, merely focusing a tab put it in reach; now a tab is in reach only if you deliberately put it there. “Qiksy acts only where you enabled it” stops being a description of a default and becomes a gesture with a record.

  • Turn it on for each tab you want the agent to work in — the popup switch, or right-click the page → “Qiksy — test this tab”.
  • A tab opened BY an attached tab joins automatically. That is how a sign-in hand-off to Microsoft or Google stays in the flow: the provider’s tab appears on its own, mid-run, and would otherwise be outside the session at exactly the moment it matters.
  • Attach nothing at all and Qiksy falls back to the tab you are on, so a quick one-tab job needs no setup.
  • Ask the agent qa_tabs at any time to see the session as it sees it.
CarefulReloading or updating the extension clears the list. Tab ids only mean something while the browser session lasts, and a stale id could name a tab that is now something else entirely — so the set is deliberately not persisted. After an update, attach your tabs again; the popup shows how many are in the session.

The order that works

  1. 1Install and pin. Show Qiksy is already on.
  2. 2Open the app you are testing — leave On this site on.
  3. 3Turn on Agent bridge · MCP, press Generate, copy the config block, paste it into your agent, restart it. The popup line goes green when the agent connects.
  4. 4Turn on Agent control and read the disclosure — this is the switch that lets a program act under your login.
  5. 5Turn on Agent drives this tab on each tab you want driven. Ask the agent to run qa_tabs and confirm it sees them.
Worth knowingThree failures that are not the agent’s to fix, and each names its own cause. “Extension is not connected” = the bridge toggle is off, or its token/port differ from the agent’s config. “consent-required” = Agent control is off. “consent-required-isolation” = the separate isolated-login confirmation has not been accepted — panel → Logins → + Isolated tab, once. “out-of-scope” is a fourth, and a different animal: the tab is simply not in the session, so turn on Agent drives this tab there. All of them are yours to clear; a good agent will name the switch and stop rather than working around it.

One file you can attach to the ticket

Qiksy records the session as you test it, then hands you a single self-contained HTML document — screenshots embedded, nothing to unzip, nothing that phones home.

The hard part of manual QA is rarely the finding. It is the twenty minutes afterwards spent turning “it broke when I saved” into something a developer can act on: which build, which steps, what the server actually answered, a screenshot that shows the state rather than the aftermath. Qiksy is watching all of that anyway, so the report is assembly, not authorship.

What is in it

  • Coverage — the pages visited, and what was exercised on each.
  • Every finding with its selector, grouped by severity: console and JS errors, failed requests with the server's own error body, accessibility and markup defects, and speed & stability measurements.
  • The steps, in order, with a screenshot per step. Password and card fields are masked before capture.
  • Environment — browser, viewport, the build under test.

Make it answer the ticket

Give the report a spec — the story and your verdict on each acceptance criterion — and it leads with those, rendered next to the evidence Qiksy gathered itself. You supply the judgement, because you are the one who read the requirement; Qiksy supplies the proof. That is the difference between a log and a deliverable.

Worth knowingThrough the bridge, always pass path: the file routinely runs to hundreds of kilobytes because the screenshots are inside it, and the agent gets back a receipt rather than the bytes. From the panel it downloads, and opens in a tab from the download bar.
Worth knowingIt is a single file on purpose. No account, no link, no upload — you attach it to the ticket, or you delete it. Nothing about a report leaves your machine unless you send it.

Tool reference

Thirty-six tools. Every one accepts an optional tabId (from qa_tabs); without it they act on the tabs you attached to the agent session, or the active tab if you attached none.

Reading the page

ToolWhat it returns
qa_tabsEvery tab Qiksy can read, including which are isolated logins (isolatedSession = the login name). The tabId you pass to everything else comes from here.
qa_statusURL, error / warning / form counts, and the isolated-login name if any.
qa_readThe RENDERED text of the page or one element. Use it whenever the answer is longer than a label — qa_snapshot caps names at 80 characters, so a one-time code in a mail tab or a full error paragraph is invisible to it.
qa_stylesComputed styles, the element's box in CSS pixels, and the CSS custom properties in scope. “color: rgb(37,99,235)” says what is drawn; “--accent: #2563EB” says which token it came from — and only the second one is a bug report. This is how a build gets checked against a design without a screenshot.
qa_storageThe app's localStorage / sessionStorage. Reading is free; op: set | remove | clear needs Agent control, because changing a stored token changes what the app does.
qa_screenshotA real picture of the page, or of one element (ref / selector). The Qiksy panel is hidden and password and card fields are covered before the frame is taken, so a shot pasted into a ticket carries no secret; path writes the PNG to a file instead of spending context on base64. One condition, and it is the browser's, not ours: it photographs the window's active tab, so a background tab cannot be photographed — Qiksy refuses rather than quietly handing you a different page.
qa_wait_forWait for one named condition and return the moment it is true: appears / disappears / enabled / text / textGone / countOf / announced / urlContains. Use it for anything whose answer lands later than a click settles — a slow save, a confirmation, a button that ungreys when validation finishes. On timeout it reports what it saw (how many matched, the nearest names on the page), so a wait that failed on a typo says so. Waiting is reading: no Pro, no consent.
qa_findingsFindings with selectors and detail. severity = all | error | warning.
qa_snapshotWhole-page accessibility snapshot with stable ref handles — the map an agent needs before acting. Narrow it on a big app: fields_only for the form controls, roles, match by name, within for one dialog or wizard step, format: "tree" for half the bytes. Filtering never invalidates a ref.
qa_exportThe full qa-export/v1 bundle: findings, forms, network, repro steps.
qa_tourThe exploratory checklist for this page.
qa_reportGenerates the session report; spec shapes what goes in.

Driving Qiksy’s own surfaces

ToolWhat it does
qa_open_panelOpens or closes the panel, optionally on a given tab of it.
qa_run_auditRe-runs the audit on the page as it is right now.
qa_axeRuns the bundled axe-core engine — the same rule set that powers Lighthouse — on the live DOM: hundreds of WCAG A/AA checks on top of the audit's own, narrowed to WCAG-tagged rules so every violation maps to a criterion, each with impact, tags, a help link and the offending selectors. Entirely local: the engine ships inside the extension and nothing leaves the page.
qa_spotlightHighlights an element in the page by selector or ref — the fastest way for an agent to show you what it means.
qa_focus_tabBrings a tab in front of you — activates it and raises its window — so a walkthrough happens where you are actually looking. The one verb that deliberately takes your attention, so it is scoped to the app under test and its isolated logins, and it is meant for “show me”, not for the agent's own convenience. Pair it with qa_spotlight: the label is what turns a run of clicks into “step 3 of 6”.
qa_wait_readyWaits for the page to settle before the next step.

Agent control (Pro, opt-in)

ToolWhat it does
qa_clickClicks an element by selector or ref.
qa_typeSets a field to a value — any kind of field. It is the extension’s own fill engine, not a keystroke emulator, so the same call handles a text input, a native <select>, a checkbox, a slider, rich text, and the controls that look like they need clicking: Radix/shadcn, MUI, Ant and react-select dropdowns, typeahead comboboxes, popup date and time pickers. It opens the popover, picks the option matching your value, and verifies the trigger changed.
qa_type_manyFills a whole form — or one step of a wizard — in one call: a list of {ref | selector, value}. Every widget kind above goes in the same batch, which is the normal use and not an edge case. Prefer ref: a form built from a repeated component gives several inputs the identical selector, and a batch of selectors would pour every value into the first match.
qa_fill_jsonFills a form from a plain { "Field label": "value" } object — the same JSON the panel’s { } editor and ⚡Fill button use. It takes its own snapshot, resolves the labels and hands everything to the batch filler, so an agent that already knows the data spends one call and never thinks in refs. Keys that match nothing come back with the page’s real field names. dry_run checks a dataset against a page without filling it.
qa_pick_dateSets an exact date in one call, whatever component library owns the calendar. It types the date first, and only if that does not stick does it open the picker and steer it — MUI’s year view, Ant’s header year, react-datepicker’s dropdowns, bare arrows otherwise — then clicks the day. Needed because some date fields cannot be written to at all: MUI X’s is three sections the component rebuilds from its own state.
qa_pick_pathOne call for a value spread across levels — a cascader (country → region → city), a drill-down, a chain of submenus. Each level is clicked on a fresh snapshot, because opening a level is what re-renders the popup.
qa_probeAnswers what kind of widget is this, and how do I drive it — for the one control that refused a value. It judges by shape first (role, tag, name, state, neighbours), which settles a sectioned date field, a file input, a switch or a slider without touching the page; when the shape says nothing — a widget hand-rolled from <div>s has no role, no name and no state — it clicks once, reads what the page did, and presses Escape to put it back. The verdict that saves the most time is “it opened and the accessibility tree gained nothing”: that means role-less markup in a portal, and the parts have to be addressed by CSS selector.
qa_uploadAttaches a file to an upload field — a real file by path, bytes as base64, or a hostile fixture built in the page (empty, 12MB oversize, wrong-type, corrupt, unicode name, unsanitised SVG…). files takes several at once, one round trip for the step.
qa_pressSends a key, optionally to a specific element. The reply carries focus — the element that ACTUALLY holds focus after the key (name, role, selector, box) — and announced: what the page's live regions spoke, or null if they stayed silent.
qa_focus_walkThe keyboard route as one call: presses Tab repeatedly, records where focus really lands, and compares the trail against what the accessibility tree claims is interactive. Reports the controls a keyboard user can never reach (the classic div-button), suspected focus traps, and stops where focus jumps against the layout — the 2.4.3 candidates.
qa_navigateNavigates the tab — within the site under test only. A hop to another domain (an external SSO, a payment provider, a docs link) is refused as out-of-scope.
qa_open_isolatedOpens a URL as a fresh isolated login — same-site only, and behind a separate consent of its own (see Agent control).
qa_close_tabCloses a tab it opened.
qa_reloadReloads the tab as it stands — no URL to pass — and waits until the page is loaded and Qiksy is live in the new document. The browser performs it, not the page's own script, so it works even when that script is already dead, which is exactly the case a reload is for. bypassCache gives the hard reload.
qa_mockAnswers one of the page’s requests from a rule instead of the server: a 500, an empty list, a payload missing a field, a 30-second delay, a dropped connection. This is how the failure branches get tested at all — a working backend will not produce them on demand. url is a substring or /regex/; times: 1 mocks the first call and lets the retry through, which is the only way to prove a retry retries. A rule belongs to one tab, survives its reloads, and is gone when it closes. It covers the page’s own fetch/XHR in the top frame — not the document, subresources, WebSocket or iframes. Every mocked answer is marked (mocked) in the session, the HAR and the report, so an invented response is never reported as the server’s. op: "list" is free; setting one needs Agent control.
Worth knowingTargets are a selector or a ref from qa_snapshot. Prefer ref: it survives the re-render that invalidates a hand-written selector, which is the usual reason a scripted step fails on the second run.

Recipes — the second run is the cheap one

A long form is expensive to work out once and should not be worked out twice. These three keep the flow on your machine as a JSON file, written in the field names a person would read — refs die with their snapshot, names do not.

ToolWhat it does
qa_recipe_saveWrites what the agent just filled, uploaded and clicked to ~/.qiksy/recipes/<name>.json, folded into steps (a click after a group of fills is what ends a step). Local only — no browser, no Pro.
qa_recipe_listThe saved flows for this host: steps, field count, the first step’s field names. One call at the start of a form-heavy task.
qa_recipe_applyReplays a recipe against the page as it is now — one call per step, matching by name, with values to swap the data and dry_run to check the recipe still fits before touching anything. Needs Agent control, since it fills and clicks.
Worth knowingThe recipe is a file you own: readable, editable and deletable by hand, at the path qa_recipe_save returns. Nothing about it is uploaded, and QIKSY_RECIPES_DIR moves the folder if you would rather keep them with the project.

Agent control

Letting the agent act inside the session you are already logged into — off by default, and deliberately hard to enable by accident.

Everything above senses. Agent control acts: click, type, fill a form, press a key, navigate, open an isolated login. It exists because the valuable session is the one you are already authenticated in — the state a cold automated browser cannot reach without you handing it credentials.

Turning it on

  1. 1Requires Pro.
  2. 2Open the panelToolsAgent control. It is a card there, not a setting in the popup — off on a fresh install and off until you turn it on.
  3. 3Confirm the prompt it shows. It names what you are enabling; it is not a checkbox you can pass over.
CarefulOpening an isolated login (qa_open_isolated) needs a third confirmation that Agent control does not cover. Multi-login intercepts the site’s cookies, session cookies included, so it asks separately. With Pro and Agent control both on, that call still refuses until you accept it — the call answers consent-required-isolation and the switch is panel → Logins → + Isolated tab, accepted once. You never have to open an isolated login to let an agent work: a normal tab with Agent drives this tab on is enough, and isolation is only for running a second identity beside the first.

The rules it operates under

  • It acts on one active tab at a time. Isolated logins keep separate identities, but a browser renders one tab actively, so parallel driving of several sessions is not offered — the honest limit, stated rather than worked around.
  • It never opens arbitrary HTML or evaluates code you did not ship. Actions come from a closed vocabulary — the tools above and nothing else.
  • It is scoped to the tab you point it at. There is no “go find the page” mode.
CarefulUse it on applications you are authorised to test. It acts with your session’s privileges — an agent clicking “delete” in an admin panel deletes exactly as you would.

A working session

What this looks like in practice, from opening a page to a fix in the editor.

  1. 1Open the feature you are testing and use it like a person would. Qiksy watches while you do.
  2. 2Open the panel. Run the audit. What broke is already listed with its selector.
  3. 3Fill the form with smart fill instead of typing test data by hand — validation then behaves like it will for a real user.
  4. 4Ask your agent: “read what Qiksy found on this tab and fix it.” It calls qa_findings, gets the selectors and the failing responses, and works from the real state instead of your description of it.
  5. 5Generate the report for the ticket — repro steps, findings and responses, paste-ready.

Prompts that work well

Read the Qiksy findings on the active tab and fix the errors in this repo.

Take a qa_snapshot, then fill the checkout form with valid data and tell me
what validation fires.

Compare qa_status across my isolated logins — does the admin see something
the customer should not?

The pattern that pays off: let the agent read the browser state rather than describing it yourself. Everything you would have paraphrased — the exact error, the selector, the response body — it can fetch precisely.

Free and Pro

FreePro
Panel, audits, findings with selectorsYesYes
Smart form fillYesYes
Isolated loginsYesYes
Export (qa-export/v1 bundle)YesYes
Session report (History tab)Yes
MCP bridge (all thirty-two tools)Yes
Agent controlYes, opt-in

Pro is $49 for a year, one payment — no stored card, no automatic renewal. Every new install gets a 28-day trial of Pro; when it lapses the extension keeps working, the bridge stops.

The licence is an offline key: the signature validates on your machine, so losing your network never loses your Pro. One thing is asked of our server, and only for a paid key — a key opens three installations, which no single installation can count by itself: when you paste a key, and once a day after, Qiksy sends the key and a random number it made up for this installation, and reads back one answer. No page data goes with it, and if the answer never arrives you keep working.

Troubleshooting

Read the message — each failure names its own cause

What the agent reportsWhat it actually means
“Qiksy extension is not connected”The bridge toggle in the popup is off, or its token/port differ from the server’s. This is the only failure that is fixed in the popup — switch it on and the agent reconnects by itself.
“Port … is held by something this bridge cannot share it with”Another process owns the loopback port: a bridge running a different token, or a qiksy-mcp older than 1.1.0. The extension is fine and the popup is not the place to look — restart or update whatever holds the port, or give this window its own --port.
“The agent window that owned this bridge just dropped”The editor window that held the port closed. The remaining ones take it over within a second or two — retry the call once.
Pro / consent requiredA tool that acts on the page needs a licence (or trial) and the one-time “Agent control” confirmation in the popup. Read-only tools are unaffected.
  • The bridge talks to a running extension in an open tab, not to a background service.
  • Restart the MCP client after adding the server; most only read their configuration at startup.
  • Both halves should be 1.1.0 or newer. Nothing to pin by hand: npx qiksy-mcp fetches the current build, and the extension updates itself from the Web Store.

Findings look empty on a page that is clearly broken

Errors are collected as they happen. If the extension was installed or the panel opened after the failure, reload the page and reproduce — then it is captured with its request and response.

A selector that worked once now fails

The page re-rendered. Take a fresh qa_snapshot and target by ref instead — refs are handles into the current snapshot rather than guesses about the markup.

Nothing happens on chrome:// pages

Chrome does not let any extension read its own internal pages, the Web Store, or another extension’s pages. That is a browser rule, not a Qiksy limitation.

What’s new

Every shipped version, newest first — what changed and whether it needs anything from you.

Worth knowingThis page lives on the web on purpose. The release notes used to be a page inside the extension, and ad blockers cut chrome-extension:// pages — people pressed “What’s new” and got a blank ERR_BLOCKED_BY_CLIENT. A normal page cannot be blocked that way, and it can be corrected without shipping a new build.

1.28.0 — it stopped restarting itself for no reason

  • “Qiksy was updated — reload the page” about an update that never happened. Qiksy installs a waiting update by itself instead of leaving it to Chrome’s own five-hour schedule, and the guard on that asked one question — is anything in flight? — and never the other one: is there anything to install? So on every browser start, and twice a day after that, a quiet browser got the extension restarted with nothing downloaded and nothing to put on. A restart kills the content script in every open tab and, unlike a real update, tells us nothing, so nothing takes those tabs over: five seconds later each one asks to be reloaded, and reloading fixes it until the next start.
  • Why it was one browser and not the other. A profile with an agent connected counts as BUSY, so the pointless restart was skipped there — the browser that looked healthy was being spared by an accident of the same bug. A second profile, opened and closed through the day, met it every time.
  • A restart now needs a downloaded version waiting. That is what Chrome tells us when it holds an update back because we are running, and it is the only thing worth interrupting every open tab for. Not knowing keeps its direction on each side: an unreadable session still counts as busy — a recording must never be cut short — while an unreadable mark counts as nothing pending, because a late update costs hours and a needless restart costs every open tab its panel.
  • No new permissions.

1.27.0 — the bridge introduces itself to the person, not only to the agent

  • Connect the bridge and it now tells YOU what it can do. Everything it said about itself was written for the agent — verb names, gates, refusal ladders. A person who had just pasted a token into a config file got nothing and was left guessing what they had bought, while every capability in that list had existed for months and had simply never been named to them. Ten short lines, plain words, and deliberately not one verb name: verbs are the agent’s business, a person needs the SHAPE of what can now be asked for.
  • In the language you chose in the panel. That is the one thing the server cannot work out by itself — it never sees your conversation. But you had already answered the question by picking a language, so the extension now sends it along with every summary; it is not a guess on the agent’s side either. With no language set, the agent still knows which one you write in, and the instruction says so as the fallback.
  • The agent’s own capability list caught up with the product. It carried neither screenshots, nor waiting, nor reload — all three shipped the same day and the list stayed yesterday’s.
  • No new permissions.

1.26.0 — so the corrected documentation actually shipped

  • Not a line of extension code changed; the number went up so the docs could move. The agent guide and the package README travel INSIDE the npm package, and the copy published an hour earlier still said “the bridge has no screenshots” — which had stopped being true that morning. A claim that flatters us is worse than a missing capability, so it had to be RELEASED, not merely corrected in the repository.
  • No new permissions.

1.25.0 — six corporate component kits, and the engine change they exposed

  • Kendo, Syncfusion, DevExtreme, SAP UI5, Fluent and jQuery UI. The registry’s 22 kits were a startup stack, while the person who pays for this usually sits in a bank’s or a logistics company’s internal admin. Every marker was measured on the library’s own demo rather than written from memory — a row selector written from memory lies silently: the list reads EMPTY, the engine falls back to “take the first row”, and a field asked for “Net 30” gets “Prepayment”.
  • jQuery UI is the one kit that needed the engine itself changed. It announces nothing: the menu is a ul.ui-autocomplete with an empty role, its rows have an empty role too, and the text sits a level lower again. The other 24 kits present as a listbox with options; this one presents as nothing, so its rows were invisible. The engine’s row selector now knows it — tied to .ui-autocomplete on purpose, because a bare .ui-menu-item is every jQuery UI menu on the page, the site’s own navigation included.
  • Two things each kit taught that could not have been guessed. Kendo re-uses its popup container instead of building a new one, so the container alone still matches ten minutes after the list closed — the marker demands the LIST. SAP UI5 puts the very same ul.sapMSelectList inline inside a CLOSED select, so the marker demands the popover. Fluent’s rows are buttons, not list items, so anything looking for an li finds nothing. DevExtreme virtualises long lists — there, “value not found” can mean “it is further down”.
  • AG Grid and Salesforce SLDS are deliberately absent. Their doc-site examples would not open under seven attempted routes across three pages, and a marker nobody has actually seen is exactly the “from memory” the rest of this guards against.
  • No new permissions.

1.24.0 — pixels, patience, and a file where the page has nowhere to put one

  • The bridge takes screenshots. “Measurements but no image” was written in the bridge’s description, in the agent instructions and in every session that repeated it — and it was true only of the BRIDGE. The product has photographed the screen since 0.1: step previews in History, the 📷 on a finding. What was missing was a verb that returns a picture AS a picture. It re-uses that same shot, so it inherits both of its properties: the Qiksy panel hides itself, and password and card fields are painted over BEFORE the frame is taken — a screenshot pasted into a ticket carries no secret. One real limit remains: the browser photographs the ACTIVE tab, so a background tab cannot be shot, and the extension refuses rather than quietly handing you whichever tab happened to be in front.
  • Waiting for an event instead of guessing. Every wait inside the extension is short and bounded — 350 ms of quiet, 2500 ms hard stop — and only on a click or a press. An order confirmation that arrives six seconds later was invisible to every verb, so the agent polled the page, and each poll RENUMBERS every reference it was holding. It now waits on the change itself, not on a timer, because Chrome clamps timers in a background tab and a background tab is the whole point of this product. Two conditions are missing on purpose: “until it goes quiet” is what every action already does, and “until the network goes quiet” would measure only the page’s own requests in the top frame — a number that means less than it says. On a timeout it reports what it SAW: how many matched, how many are visible, the nearest names, anything announced.
  • A file goes in where there is no file field at all. Some forms have nowhere to put one: the button opens the system window directly, and that window belongs to the operating system — outside the document, unreachable by any script, this extension included. The “Audio language” dialog in YouTube Studio is one of those, and an upload aimed at it silently went to the subtitle uploader instead, which is worse than a refusal. Now the page gets its answer BEFORE it opens the window. The normal route stays first always: a field is the honest place for a file.
  • And that interception is armed for exactly one call. Patching the page’s own prototypes is interference in somebody else’s application — a site with its own wrapper around a file field would break, and a tool that hunts for defects must not add any. The originals come back the moment the offer is withdrawn, including when the click threw. Proven on a third-party product: after withdrawal the prototype is compared against an untouched one and matches.
  • The recorder no longer treats anything with aria-expanded as the owner of a layer. That attribute sits on any expansion — an accordion, a collapsible sidebar, a tree row — and on the whole left navigation of YouTube Studio, because a hamburger folds it. So the owner of an open dialog came back as a 240×793 <nav>, which has no name, so the recorder fell through to its id, and then read three blocks of menu as the field’s values. A live recording came back as one step holding a menu.
  • A fill batch says what the form did next. A batch is a wizard step — the unit the agent actually works in — and “what happened after it” is exactly the question worth answering: a dependent list loaded, a section appeared, an error surfaced. One window per step, not per field, and it replaces the snapshot the agent would otherwise take next.
  • The conditions the page was read under. The most expensive class of defect — “it only reproduces for him” — is almost never about the browser. It is about forced-colours eating a background, reduced motion carrying state, a locale whose date format the parser rejects, a timezone that moved a deadline to yesterday. All of it was free to read and simply never asked for. Page zoom comes from the worker, because inside the page it can only be inferred, and every inference mixes page zoom with display scaling.
  • Library detection in one round trip instead of 51.
  • No new permissions.

1.23.0 — letters land in the field you clicked

  • Project and Tags accept typing. The scenario naming card does not let the browser type into its own fields: it collects every printable key from the window and appends it by hand, because a field with two writers loses exactly one character at the moment the page grabs the caret back. There was one writer, and it wrote into ONE field — the name. So on a page that fights for the caret, clicking “Project” and typing sent every letter into the NAME: the field being looked at did not change, and the name grew behind your back. Reported on YouTube Studio: “focus does not work, you cannot add anything to project or to tags at all.”
  • Both halves were needed, and either alone would have been useless. The defence against a stolen caret stood only on the name — it is now on all three fields; and the key collector writes into the field the cursor is in, rather than into the name always.
  • No new permissions.

1.22.0 — Pro wears the studio’s own mark

  • One crown instead of four different badges. The Pro mark had split into four: a violet gradient plate in the popup, a gold one in the panel header, a violet chip on every paid settings row and bare violet letters in the findings menu. Four versions of one thing read as four products, and not one of them looked paid. This is not a new drawing but the SAME crown and the same gold as everywhere else in Qiksy Studio — a similar crown would be a different mark, so the path was copied rather than redrawn.
  • Gold, not the accent colour, and that part matters. The accent says which SURFACE you are on, so a Pro badge painted in it changes colour between products and stops meaning one thing.
  • The trial chip keeps its green. A countdown is a STATE, not a mark, and gold on it would promise a crown that has not been bought.
  • No new permissions.

1.21.0 — an update no longer asks you to reload the page

  • The false “Qiksy was updated — reload the page” notice is gone. A minute after an update the worker adopts every open tab by itself, so there is nothing left to reload. The orphaned copy did not know that: its own poll removed the panel the NEW copy had just drawn — both hosts carry the same id — its own timer put the frozen host back, and on top of it all stood a notice that was no longer true. The dead copy now stops its own timers first, removes ITS OWN node by reference rather than by id, and only then, after a pause, asks whether anyone alive has adopted the tab. A heartbeat on the page answers, and only a script with a working extension connection can write it.
  • The round button grows slowly on hover. 420 ms on a curve with no bounce; it was 240 ms and still read as a jerk.
  • No new permissions.

1.20.0 — the mark on the toolbar icon is gone for good

  • The little square on the extension icon was ours, and nobody ever recognised it. It was asked about three times. Gold first — “what is that yellow square”. Recoloured so the glyph carried the colour instead of the fill — “what is that black square”. The problem was not the palette: Chrome draws a badge as a SOLID rectangle sized to its text, so a “small dot” does not exist on that surface in any colour, and at 16 px on a dark icon it is a square.
  • Nothing was lost. A new version is still announced by the banner in the panel and the note in the popup — places with room to say WHAT changed, both of which go away once read. The badge was a third copy of the same message and the only one that could not explain itself.
  • No new permissions.

1.19.0 — recording is red around the whole window, and the scenario buttons hold one shape

  • The recording frame is a warm red, and it goes all the way round. It used to be its own orange, matching nothing. Tying it to the error token was worse: that is the token Delete turns under the cursor, and a line around somebody’s whole application in the colour of deletion tells a lie about a healthy page. The red is now the tone of a camera’s tally lamp — recording is an “on” state, not a warning. Its right edge used to be hidden whenever the panel was docked, because the frame was drawn at full window width while the panel stood over one edge; the dock genuinely narrows the page, and the frame now narrows with it.
  • The scenario buttons stopped rearranging themselves per language. Four labelled buttons need 336 px in English and 370 in Russian, and the card gives 319 — so the row wrapped in a DIFFERENT PLACE in each of the seven dictionaries, and Polish landed at exactly 319 and did not wrap at all. A wrap that depends on the translation looks accidental in every language. The shape is now fixed: Run across the full width — the thing the card exists for — and three below it. The longest dictionary fits with 60 px to spare.
  • Delete keeps its icon and no word. An icon has no translation, it is the one thing that fits everywhere, a bin is the least ambiguous sign in an interface, and the press is undoable. Its name lives in the accessible label and the tooltip.
  • No new permissions.

1.18.0 — agent control is remembered per SITE

  • Switch it on once and the next tab of the same application connects itself. The “drive” consent was already asked once and kept; what was rebound every time was the TAB — and a tester spends the day on one application. The key is the ORIGIN, and that is the one thing separating this from “on everywhere”: collapsing it to the registered domain would mean a single deliberate gesture on a dev host silently opened the whole company network.
  • The badge on the icon carried the colour on its glyph. A short-lived attempt to make the “there is news” mark readable — Chrome fills a badge as a solid block, so gold on the background became a gold block. It was removed altogether in 1.20.0.
  • No new permissions.

1.17.0 — a page region is no longer a Next button

  • Two recorded steps came back with the whole main content area cast as “Next”. The run could not find it by name, the fallback by selector handed back the entire region, and the “is this an upload?” question asked whether there was a file input ANYWHERE inside it — and found somebody else’s, elsewhere on the page. The person was told to attach a file to a field they had never recorded.
  • The cause was one attribute read backwards. tabindex="-1" means the page has taken the element OUT of the keyboard order; most often it sits on the target of a “skip to content” link, which is to say on any accessible site. The recorder only asked whether the attribute was present, so a click on empty space — the way an open calendar is dismissed — became a step boundary. Four fixes: tabindex counts as a button only at 0 or above; a name equal to a block’s id is not a name; the selector fallback must return a control; and the upload question is asked about the control itself, not about everything beneath it.
  • No new permissions.

1.16.0 — the lightning bolt is back where it belongs

  • The icon. It was rotated in a passing edit on 29 August and 1.15.0 carried that to the store: at 16 px the bolt stopped being the tail of the Q, leaving a ring with an empty notch and a yellow smudge beside it. The exact four files from 1.13.0 are back, byte for byte, so the store page matches again. It slipped through because the two packages were compared by their FILE LIST rather than by their bytes.
  • The scenario card stopped overflowing. Its “steps · pages · host” line was fixed-size, which was right while it held two short counters and wrong once a long host was appended. Letting it shrink was worse — both halves shrank and produced two ellipses and not one readable fact — so it is two lines now, each with its own room. And “1 steps” is gone: a separate key for the singular in seven languages is cheaper and more honest than a declension engine for the one counter that is ever 1.
  • No new permissions.

1.15.0 — you can see that recording is on from anywhere on the screen

  • A frame around the window while recording. Until now the only sign was a pill INSIDE the panel — exactly where a person is not looking: they are in the application, filling a form, with the panel closed or off to the side. A recording nobody can see gets left on for an hour, and then the scenario is named after everything that happened to occur. A frame at the edge of the window cannot be missed and cannot be mistaken for part of the application. It never takes a click, never moves the page, and lives inside our own host — so the screenshot code that hides our interface keeps it out of pictures, and full screen takes it away along with everything else of ours.
  • The recording colour is its own token and deliberately not the accent. The accent changes with the theme and with your choice, and a warning that can be repainted into furniture stops warning.
  • No new permissions.

1.14.0 — scenarios that survive a real application

  • A standing panel is no longer mistaken for an open menu. A popup used to be recognised by how it is drawn — positioned, above the page, big enough for choices — and a work-item panel in Jira answers yes to all of it while never having opened. One click inside it produced three separate lies in the same recording: the field took the name of a sprint chip nearby, the value typed into it was thrown away as "already recorded by whoever owns the layer", and the panel’s own rows were written down as the rows of a menu. A layer now counts only if it was NOT on screen when the press began.
  • A run begins where it was recorded. The starting page was stored and never used, so Run filled whatever happened to be on screen — invisible on the recorded page, and on any other one it failed on step one looking for controls that were never there. It goes to the recorded page first, matching by page rather than by exact address so a live session is not swapped for the dead one written down, and only within the host shown under the scenario’s name.
  • A field inside a frame is named, not silently missed. Qiksy runs in the top document only — a deliberate permission decision. Anything inside an <iframe> (most payment boxes, some embedded editors) is therefore unreachable, and until now that was silent: nothing recorded, and a run that stopped blamed the page. Recording says it the moment the frame takes focus; a stopped run says which wall it hit.
  • The update notice tells you about THIS release. It said "Updated to v1.13.0" and then listed 1.12.0’s changes. The teaser is now tied to a version, the build fails if they disagree, and the panel falls back to a neutral line rather than repeating another release’s news. The extension also installs a waiting update itself — but never while a recording, a scenario or an agent is in flight.
  • No new permissions.

1.13.0 — scenarios, and four things that lied about their own work

  • Scenarios. Record a form flow once and replay it with one press — across the wizard’s steps, across pages, and across sites. It stops at every page boundary and waits for you, stops at the first field the page no longer has and NAMES it, and records passwords and card numbers as fields rather than values. See Scenarios.
  • A menu with no library behind it is drivable now. Rows used to be found by class name, so a picker built from anonymous divs — most hand-rolled ones — read as an empty list and the widget was reported as “did not respond”. A row is now recognised by shape: a leaf of the layer that just opened, and there is more than one of them.
  • A read-only box that opens a list is a control, not a caption. Everything read-only was dropped by the scanner, which is right for a displayed account number and wrong for the commonest way the web builds a select. The field was skipped SILENTLY and the form still counted complete.
  • “Filled 2 · skipped 2” now names the two. A count you cannot act on, in front of a form you have to submit, is how a person takes a half-filled form for a finished one.
  • Validate stopped clearing fields it never checked. It looked for a red line “near” the field, and “near” could be the wrapper around the whole form — so one field’s genuine error vouched for its neighbours and a form with two unguarded fields came back silent. A false all-clear is the worst direction for a check.
  • The bridge’s fast pick takes the row from THIS control’s list. With a suggest box left open elsewhere, an exact match there beat the right match here — the value went to a field nobody named.
  • No new permissions.

1.12.0 — the panel finishes the sentence

  • The language switch now reaches the whole panel. 1.11.0 translated the titles and left the explanations: every hover tip, the paragraph under each tool, the empty states, the toasts and the placeholders stayed English — so a Spanish tester got a Spanish panel that explained itself in English. 171 strings moved into the dictionary, and a test now reads the SOURCE rather than the dictionary, because the one thing a completeness check cannot see is a string that was never a key.
  • Your app’s language, not ours. Four word lists decide what sends a form, what closes a modal, which dropdown rows are placeholders and which field wants a date — and they knew English and Russian. On a German or Spanish form the tool could not find the page’s own Save button, silently, because from outside that looks like “this page has no form”. All four now cover the seven shipping languages.
  • A calmer panel. Twenty-five muted accent colours instead of eight saturated ones, and the colour you pick now tints the whole sheet rather than four controls. The light theme is warm paper instead of blue-white, and its shadows are a hint rather than a hole; the dark theme is a neutral grey. The default is still the grey that asks nothing of you.
  • Our own contrast, measured. The most muted text on the light theme sat at 3.4:1 — under the 4.5 this tool flags on other people’s pages. Fixed, in the two places it appeared.
  • Findings, session notes and the client report stay English by design. No new permissions.

1.11.0 — the panel speaks your language

  • Seven languages, in the panel itself. English, Deutsch, Español, Polski, Português, Русский, Українська. Qiksy picks yours from the browser the first time it runs; the popup has a switch when your machine is in one language and your team works in another.
  • Findings stay in English on purpose. They are copied into a ticket that a developer in another country reads, so the tool is translated and its output is not — the same split DevTools makes.
  • Field recognition learned four more languages. A label that says Kod pocztowy, Firmenname, Teléfono or Sobrenome is now understood as a postcode, a company, a phone and a surname. And a bug that had been there from the start: plain Russian Имя was never recognised, because a JavaScript word boundary only knows the Latin alphabet.
  • Two false failures fixed. A consent checkbox whose label contains the word “terms” was being sent down the dropdown route and then reported as unfilled — while the box was, in fact, ticked. And a hand-rolled combobox that shows its value as plain text was called wrong and “repaired”, which wrote text into a element that cannot hold it. Both now judge by what is on the screen.
  • No new permissions.

1.6.0 — the accessibility audit stack

  • axe-core, inside. The industry-standard accessibility rule engine — the one under Lighthouse — now ships bundled in the extension and runs locally via qa_axe: hundreds of WCAG A/AA rules, every violation with impact, WCAG tags and the offending selectors. Nothing leaves the page.
  • The keyboard route, walked for real. qa_focus_walk presses Tab step by step and reports where focus actually lands: the controls a keyboard user can never reach, suspected focus traps, and focus jumps that fight the layout. Every qa_press reply now names the element that truly holds focus.
  • Silent toasts are a finding now. After every click the bridge watches the page's live regions and reports announced — a toast that appeared for the eyes and said nothing to a screen reader (WCAG 4.1.3) is caught by machine, not by luck.
  • Popup polish: a custom scrollbar and softer rows.
  • No new permissions. Everything above is local analysis over the existing loopback bridge.

1.3.0 – 1.5.0 — the fill engine stopped guessing

  • A select takes the option you NAMED — exact, then prefix, then contains — and refuses with the real list instead of grabbing the first row; a multi-select counts its chips instead of trusting class names.
  • A form that grows while it is being filled (gated sub-forms) is refilled as it grows; the fast raw route writes parseable values (dates, times, ranges) in tenths of a second instead of driving the popup.
  • Ant Design range pickers, time pickers, cascaders and trees driven reliably; qa_pick_range types both ends and verifies each against its own input.
  • The manual ⚡Fill narrates on its card instead of drawing rings over every field.

1.2.0 — connect your browser with one button

  • Pairing from the Qiksy web app. Qiksy Route (and the studio) can now ASK the extension to connect: press Connect this browser in its settings and the extension opens its own confirmation page naming the site, the local port and exactly what is granted. Only your click there enables anything — a website can never switch it on by itself.
  • No token to copy on that path. The manual popup route stays for everyone who prefers it, and for clients we do not ship.
  • The confirmation is honest. It checks your licence before promising anything, its buttons disappear once answered (so a refusal cannot be undone by a stray click), and only our own origins may ask, at most one dialog every few seconds.
  • Windows and Linux fixes in the local engine (qiksy@1.6.1): PATH is no longer mangled on Windows, stop can no longer kill an unrelated program that happens to use a similar port, and machines without lsof (containers, slim servers) are handled.
  • The bridge package (qiksy-mcp@1.2.0) now carries AGENT-GUIDE.md — drop it into a project and any assistant knows the tools and the limits.

1.1.x — many agent windows, one browser

  • Open a second or third editor window and they all reach the same browser through the same toggle: the first process holds the port, the rest relay through it. Nothing to configure, no second token.
  • Whole-page accessibility snapshot (qa_snapshot) with stable refs, so an agent can target a control that no CSS selector describes uniquely.
  • Agent control (Pro): click, type, press, navigate, open an isolated login — behind a licence and a separate one-time consent, re-checked on every call.

1.0.x — the first public build

  • Form scanning and one-click fill (valid / edge / invalid), live findings, page audit, spotlight, copy-as-bug.
  • Multi-login isolation — several sessions on one domain, in one browser.
  • The MCP bridge: your own coding agent reads findings, forms and network from the page you are looking at.