Getting started
What QAmeleon does
QAmeleon is a QA engineer that runs in your own CI. It checks your dev app every weekday morning and after every deploy, reviews the tickets waiting for QA, and raises what it finds on your board with steps to reproduce.
Pages, API shapes, speed, sign-in, who can see what, and accessibility. A one-screen summary goes where you choose; the full report lands in your console and on your board.
It runs each ticket's "How to verify manually" steps on dev and judges the change five ways: UI, UX, Regression, Old Man Testing and Automation.
Each real bug becomes its own ticket with steps to reproduce, expected, actual and how to verify. Never raised twice.
Security findings, critical findings and anything odd in a ticket wait for a person. A pause button stops all publishing at once.
The morning and deploy checks run on your GitHub Actions. Reviews you start run on your machine. Both use your own Anthropic key, and your code, tickets and pages never reach us.
Getting started
Before you start
Have these ready and setup runs straight through in about ten minutes.
| You need | Why |
|---|---|
| Node.js 22 or newer | QAmeleon runs on Node, on your machine for setup and in CI after. |
| The GitHub CLI, signed in | Install it from cli.github.com and run gh auth login. Setup uses your login to open a pull request and save secrets. You need admin access to the repository, so setup can save its secrets. |
| Your QAmeleon access key | It is in your invite email. You install QAmeleon with it, and setup asks for it once more at the end to save it to your repository, so your CI can fetch QAmeleon each morning. Keep it to hand. |
| A browser for QAmeleon | Run npx playwright install chromium once. Setup uses it to look at your app and run the first dry run. |
| Claude Code | Run npm install -g @anthropic-ai/claude-code --allow-scripts=@anthropic-ai/claude-code. Reviews you start from setup or the console run on your machine with it. |
| A repository on GitHub with Actions | QAmeleon adds one workflow and runs there. GitLab is coming soon. |
| Your dev app, running | The address of a dev or test environment. Never production. |
| Two test accounts in different customers | So it can prove one customer cannot see another's data. A third, borrowed account with real data is optional and stays look only. A public site with no sign-in needs none. |
| A board: Jira, Trello or Notion | For Jira, an API token. For Trello, an API key and token. For Notion, an integration secret. You will pick three columns. |
| An Anthropic API key | Ticket reviews run on it. We suggest a separate workspace with a spend limit. The morning and deploy checks cost nothing. |
Whenever setup needs a secret, it asks in the terminal with a hidden prompt and saves it straight to your repository's GitHub secrets. You never paste a secret into a browser or a file.
Getting started
Open setup
- Install QAmeleon with the commands in your invite email: the first downloads QAmeleon with your access key, the second installs that file. They work with any npm, including npm 12. The key is yours alone, so keep it to yourself.
- Open a terminal in your app's repository folder and run:
$ qameleon setup
- Your browser opens the setup page. It is served from your own machine only, with a one-time key, so nobody else can reach it.
- Keep the terminal open beside it. When setup needs a password or token, an amber box says Your turn, in the terminal. Type it there, not in the browser.
The page has three parts: the steps on the left (Connect, Build, Loop), the current step in the middle, and QAmeleon on the right, who tells you what is happening and changes mood as it goes. A step unlocks once the one before it is done, and you can go back to any finished step from the left.
Every setup step has a command too. Run qameleon help for the list, or see Command line.
Setup
Welcome
The first screen says what is about to happen: connect your repo, your dev app and your board, then QAmeleon checks every build and reviews the tickets waiting for QA.
Three promises are on the screen, and they hold for the whole setup: it runs on your CI with your own Anthropic key, nothing is posted until you approve, and its writes are fenced so it never pays, publishes or deletes.
- Press Let's start.
Setup, Connect 1 of 4
Git: pick your repo
This is where QAmeleon will live. It adds one workflow so it runs in your own CI.
- Leave GitHub selected.
- Pick your repository from the list. The list shows every repository your GitHub login can push to.
- Read the box underneath: it lists the exact files QAmeleon will add in one pull request.
- Press Continue.
The pull request opens at the end of setup on a branch called qauto/setup. Running setup again updates the same pull request rather than opening a new one.
If the repository already runs QAmeleon, setup says so, because carrying on would replace its saved memory. Pick another repository, or carry on only if you mean to set it up again.
Setup, Connect 2 of 4
Product: point QAmeleon at your dev app
QAmeleon works out how your app signs in and where its API is. You only confirm.
- Type your dev app's address in Dev app address, for example
https://dev.yourapp.com. - If your app has no sign-in, like a marketing site or a blog, tick My app has no sign-in. QAmeleon then tests it as a visitor, signed out, and the Accounts step has nothing to ask.
- Press Have a look (or Enter). QAmeleon opens the app, finds the sign-in form and listens to the API calls.
- Check the list it found: sign-in page, API address, how the session is kept, the build file and your time zone.
- If something is missing, a red box says what, and a field appears for it: Sign-in page (for example
/account/login) or API host (for exampleapi.yourapp.com). Fill it in and press Have a look again. - When it is right, press Looks right.
To find the API, QAmeleon tries one sign-in with a made-up address ending in .invalid. If you get something wrong here, you can change it later from Settings in the console.
Setup, Connect 3 of 4
Accounts: add test accounts
Two accounts in different customers let QAmeleon check one customer cannot reach another's data. A borrowed account with real data unblocks deeper review steps. If you ticked My app has no sign-in, this step says no test accounts are needed: press Continue.
The screen lists the accounts it wants: an owner, a second customer, and an optional borrowed account. For each one, choose how QAmeleon may use it:
| Choice | What it means |
|---|---|
| Own data | A test account QAmeleon may create and delete its own test records in. Records are clearly named and cleaned up every run. |
| Look only | Every write is blocked, with no exceptions. Use it for an account with real data that you are lending. |
- Set Own data or Look only on each account. At least one account needs its own data.
- Press Add passwords and check.
- In the terminal, type each account's email and password when asked. Skip an optional account by pressing Enter.
- QAmeleon signs in with each one to prove it works. Each account shows Signed in, Skipped or Not signed in.
- When they all work, press Continue.
The red box names the account and why. Press the button again: it asks only for the account that failed. Nothing is saved until every account signs in.
Setup, Connect 4 of 4
Board: connect your board
Tell QAmeleon where tickets wait for QA, where to put what it finds, and where verified passes go.
Jira
- Choose Jira.
- Fill in Jira address (for example
yourcompany.atlassian.net), Jira account email and Project key (for exampleAPP). - Press Load columns. In the terminal, type the API token for that email. Create one at id.atlassian.com, Security, API tokens.
Trello
- Choose Trello.
- Paste the Trello board address (for example
https://trello.com/b/AbCd1234/my-board). - Give a Short key for cards, for example
APP. Cards are then named APP-12, from their number on the board. - Press Load columns. In the terminal, type your Trello API key and then your token. Both come from trello.com/power-ups/admin, under your Power-Up's API key.
Notion
- Choose Notion.
- In Notion, open the database, choose ••• then Connections, and add your QAmeleon integration. Then paste the Notion database address.
- Leave Short key for tickets empty to use the prefix of the database's Unique ID property, or type one, for example
APP. - Press Load columns. In the terminal, type the integration secret from notion.so/my-integrations.
The database needs a Status property, whose options become the columns, and a Unique ID property, which names the tickets.
Pick the three columns
| Field | Pick |
|---|---|
| Tickets wait for QA in | The column developers move tickets to when they are ready for testing, for example "Ready for QA". |
| Put findings in | A triage column for the bugs QAmeleon raises, for example "QAmeleon found". A ticket whose own steps failed comes back here too, with its bugs linked, so a developer picks it up. |
| Move verified passes to | Where a ticket goes when every step passed, for example "Passed QA". QAmeleon only moves a ticket from the review column to this one, and only when every step passed. |
- Press Continue. The token is saved to your GitHub secrets.
Your own links to the guide for connecting any other board. Slack, Teams, email and Datadog are not set up here: you add them in the console, under Connections.
Setup, Build
First run: the dry run
QAmeleon checks everything and posts nothing. You approve the result as the baseline every later run is compared against.
- Press Start dry run. A list shows each check as it runs, with a tick when done. It takes about a minute.
- Read the four numbers: checks passed, serious findings, minor findings and test records left behind (this should be 0).
- Read any findings underneath. Each has a severity and what QAmeleon saw.
- Press Approve as baseline. Or Run again if you fixed something first.
The baseline is only the starting point. Access and security checks run again every morning and keep reporting a problem until it is fixed. Page issues from this first scan become the starting point, so raise any you want fixed now.
Setup, Loop
Review and refine
The loop is on. This screen shows what now runs on its own, and offers to review the tickets already waiting.
The morning check, in your time zone. Report on the board and in your console.
Checks the new build on dev. Have your deploy pipeline send a repository_dispatch event called deployed to this repository after each deploy.
Reviews tickets when you ask.
Bugs land here with repro steps.
Review the first batch
- Check the list of tickets waiting and the cost estimate under it. A review usually costs between $0.30 and $0.65 a ticket on your Anthropic key.
- Press Review 3 tickets (the number is how many are waiting). The first time, the terminal asks for your Anthropic API key. It is saved for CI.
- Watch each ticket go from Waiting to Reviewing to Reviewed. Each takes a few minutes, and the line under it says what QAmeleon is doing right now.
- Read the result on each ticket, then press Approve and publish. Or Not now: nothing is touched.
Merge, then open your console
- Press Merge pull request. If your repository does not have your QAmeleon access key yet, the terminal asks for it first, checks it and saves it as a secret. Merging adds the workflow and your settings to your main branch, which switches on the morning check. Nothing else in your code changes.
- Rather merge it yourself on GitHub? Do that, then press I've merged it, check again.
- Press Open your console. Setup is done.
Run qameleon in your repository folder. It opens the console once setup is done, and setup in a folder that is not connected yet.
The console
Opening the console
The console is home after setup. Like setup, it runs on your own machine and opens in your browser.
The menu on the left has eight pages: Today, Morning report, Queue, Waiting for you, History, Connections, Controls and Settings. Queue and Waiting for you show a count; the Waiting count turns amber when something needs you. QAmeleon sits on the right and says, in one line, what matters on the page you are on.
The console shares memory with CI, so a pause or an approval you make here reaches the next CI run.
Console
Today
The front page: is QAmeleon publishing, does anything need you, and how did this morning go.
What you see
- The banner says how publishing stands: QAmeleon publishes on its own (green), Approval mode or Tightened (amber), or Paused (red), with Go to Controls when publishing is paused or tightened.
- Four cards: Waiting for you, the number of tickets in your review column, the last 24 hours (published, held, bugs raised and cost), and the share of findings your team accepted.
- Rejected findings: a bar showing how many findings people rejected, with an amber mark at the limit. Above it, QAmeleon stops publishing on its own.
- This morning: the morning check's result with Read it, the build on dev and when it was deployed, and the last batch.
What to do
Click a card to go to that page. If Waiting for you is above 0, start there.
Console
Morning report
The latest morning or deploy check, wherever it ran, plus the last runs.
- The title is the verdict: Nothing to do (green), Worth a look (amber) or Needs attention (red). The banner under it names the check, when it ran and the one-line summary.
- Recent runs lists the last seven, each with its colour and summary.
- The full report follows: builds, API changes, test results, speed, access checks, page scans, and what the run wrote on dev (always its own test data, with "nothing left behind").
Before the first morning check runs, the page says No report yet. See Reading the results for what each colour means.
Console
Queue
The tickets in your review column. Pick some and QAmeleon reviews them on dev.
- Press Refresh if you moved cards in since the page was read.
- Pick the tickets to review, or press Pick all. Up to 10 go in one batch. Each ticket shows how many steps it has to verify (or that it will be reviewed against its description) and when it was last reviewed.
- Check the estimated cost at the bottom, worked out from your board's past reviews.
- Press Review 3 tickets (the number is how many you picked). Each ticket runs in its own session behind the write fence, and the list shows Waiting, Reviewing and Reviewed.
- When the batch is done, the page shows what was published by QAmeleon (with any bugs raised and tickets moved) and what was held for a person, with the cost.
- If anything was held, press Go to Waiting for you. Otherwise Back to the queue.
Reviews still run, and every one waits for you on Waiting for you.
Console
Waiting for you
Every review a guard held, each with the reason and what accepting it means. Guards cannot be switched off, only accepted one review at a time, by name.
What each card shows
- The ticket, and a chip for each guard that held it.
- A summary, how many steps passed, failed or were blocked, when it ran and what it cost.
- What the guard means in plain words, the findings with their evidence, and any flagged lines from the ticket, shown as text and never followed.
What to do
- Type Your name. Approvals are recorded on the ticket under it.
- Read the card. Tick each box it asks for, for example "I have checked the evidence and agree it is critical".
- Press the card's button:
- Approve and publish puts the review on the board.
- Run again appears when nothing was reviewed yet, for example when the app was down.
- Sign off and move appears when a review passed but a hold label asked for a person to sign it off.
- If reviews were held only by a pause or tightening that is now over, press Publish through the guards at the top. Anything another guard holds stays.
See What gets held, and why for every guard.
Console
History
Everything QAmeleon did and who approved what, newest first.
Each batch shows when it ran, who started it and what it cost, then a line per ticket: Published (with any bugs raised and their severity, and where the ticket moved) or Held (with the guards). Every pause, resume, reset, approval and sign-off is there too, with the person's name.
Console
Connections
Where the report goes. Every morning check and every deploy check is sent to each place switched on here, from your own CI.
Add a place to send it
- Under Add a place to send it, choose Slack, Microsoft Teams, Email, Datadog or Any webhook.
- Fill in any fields it asks for (email and Datadog have some; the others have none).
- Press Save and type the secrets, then type the address or key in the terminal that runs the console. It goes straight to your repository's GitHub secrets.
- Press Send a test on its row. Check it arrived.
- Commit
qa.config.json. The amber banner reminds you: until it is committed, the morning check in CI still sends to the old list.
Each row
A row shows the destination, where it posts, and a chip: On, Off or Needs a secret. Use Switch off or Switch on to pause one, Send a test to try it, and Remove (then Remove it to confirm) to delete it.
Step by step for each one: Slack, Teams, Email, Datadog, Any webhook.
Console
Controls
Stop, start and reset. Every change is recorded with a name.
- Type Your name.
- Kill switch. Press Pause publishing to stop all publishing at once. Reviews in flight still finish and wait for you. Press Resume publishing to turn it back on.
- Automatic tightening. The panel shows how many recent findings were rejected. Above the limit, QAmeleon stops publishing on its own and asks first. Read what was rejected, then press Reset.
- The guards. The list at the bottom shows every guard, always on, and whether publishing is in auto or approval mode.
Add the label qauto-rejected to a finding that is wrong or not a bug. Moving a finding out of the findings column without that label counts as accepted. Once five findings are triaged, more than one in five rejected stops QAmeleon publishing on its own.
Console
Settings
What QAmeleon is connected to, and how to change it.
- Repository, app and board: the repository, the board and project, and the apps it tests.
- Change what is connected: Open setup opens the setup wizard again, starting from what is connected now. Use it to connect another repository, point at a different app or API, change the test accounts, or move to another board. Changes reach CI through a pull request, as the first time.
- Where the report goes: Go to Connections.
Send the report
Slack
The one-screen summary in a channel, every morning and after every deploy.
1. Make a Slack webhook
- Go to api.slack.com/apps and press Create New App, then From scratch. Call it QAmeleon and pick your workspace.
- In the app's menu, open Incoming Webhooks and switch Activate Incoming Webhooks on.
- Press Add New Webhook to Workspace, pick the channel (for example
#qa) and press Allow. - Copy the webhook address. It starts with
https://hooks.slack.com/services/. Treat it like a password: anyone with it can post to that channel.
2. Add it in QAmeleon
- In the console, open Connections and press Slack.
- Press Save and type the secrets.
- In the terminal, paste the webhook address when asked. It is hidden as you type and saved as
QA_SLACK_WEBHOOK_URL. - Press Send a test. A test message appears in the channel.
- Commit
qa.config.json.
Send the report
Microsoft Teams
The summary in a Teams channel, through a Workflows webhook.
1. Make a Teams workflow
- In Teams, open the channel, press More options (the three dots) next to it and choose Workflows.
- Pick the template Post to a channel when a webhook request is received, name it QAmeleon, and confirm the team and channel.
- Copy the address it gives you at the end.
2. Add it in QAmeleon
- In Connections, press Microsoft Teams, then Save and type the secrets.
- Paste the address in the terminal. It is saved as
QA_TEAMS_WEBHOOK_URL. - Press Send a test, then commit
qa.config.json.
Send the report
The summary and the full report by email, sent through your own mail server.
- In Connections, press Email.
- Fill in Send to (one or more addresses, separated by commas), Mail server (for example
smtp.office365.com), and optionally From and Port (587 is usual). - Press Save and type the secrets. In the terminal, type the mail server's sign-in name, then its password (hidden). They are saved as
QA_SMTP_USERandQA_SMTP_PASSWORD. - Press Send a test, then commit
qa.config.json.
Some providers need SMTP sign-in switched on for the mailbox, or an app password instead of the normal one. Your mail admin can tell you which.
Send the report
Datadog
An event for every run, plus numbers to graph: tests failed, sign-in time and open findings.
- In Datadog, open Organization Settings, then API Keys, and create a key called QAmeleon. Copy it.
- In Connections, press Datadog.
- Choose your Datadog site: the one in your Datadog address, for example
datadoghq.eu. Optionally add Extra tags such asteam:web, env:dev. - Press Save and type the secrets and paste the API key in the terminal. It is saved as
QA_DATADOG_API_KEY. - Press Send a test, then commit
qa.config.json.
Send the report
Any webhook
The full report as JSON, for Zapier, Make, n8n or your own tool.
- Create a webhook trigger in your tool and copy its address. It must start with
https://. - In Connections, press Any webhook, then Save and type the secrets.
- Paste the address in the terminal. It is saved as
QA_REPORT_WEBHOOK_URL. - Press Send a test and check your tool received it, then commit
qa.config.json.
Reference
Reading the results
QAmeleon changes colour with the result, in the report, the review message and on your board. His face changes too, so you can read it at a glance in any colour.
| Colour | Means | Do |
|---|---|---|
| Green, nothing to do | Every check passed. | Nothing. |
| Amber, worth a look | Something changed, for example a new API field, or a review is waiting for a person. | Read the top line, then check it was meant. |
| Red, needs attention | A check or a step failed, and which deploy did it. | Read the report. Bugs from reviews are already on your board. |
Severity of a finding
| Severity | When |
|---|---|
| Critical | Only four cases: another account's data is reachable, data the customer already had is destroyed or corrupted, sign-in or payment is broken, or a feature nobody can use. Always waits for a person. |
| Serious | A normal user cannot finish what they came to do, or is shown a wrong result with nothing to make them doubt it. For example, a change that does not save. |
| Moderate | It works, but it misleads or gets in the way, for example a missing undo, or a limit shown only after the work is done. |
| Minor | Polish. Minor findings go on one polish ticket per reviewed ticket, not one each. |
| Note | Worth knowing, nothing to fix. |
QAmeleon sets the severity from what the problem does to the customer, so the same problem gets the same severity on every ticket. A bug an earlier review rated keeps that rating. A review that would change it waits for a person.
Step results in a review
Each "How to verify manually" step is marked pass, fail, blocked (it says exactly what would unblock it, often a test account or some data) or Needs a person (it needs access QAmeleon does not have, such as a test card or cloud logs). A ticket moves on only when every step passed. If any step failed, it goes back to your findings column. If steps were only blocked, it stays where it is until they can be checked.
Reference
What gets held, and why
QAmeleon publishes on its own unless one of these holds the review for a person. They are always on. You can add hold labels, not remove guards.
| Shown as | Why it waits |
|---|---|
| Security finding | A person checks it before it goes on a board many people can read. |
| Critical finding | The most costly thing to get wrong, so a person confirms it. |
| A step about money | A step about paying or being charged needs a person. |
| Lines aimed at the reviewer | Someone wrote instructions to QAmeleon in the ticket. They were not followed. |
| The fence stopped something | The review tried a write or a site it is not allowed to. |
| Hold label on the ticket | Someone asked for a person to sign this one off. |
| Wrong build on the test site | The ticket names a fix build dev is not serving yet. Nothing was reviewed and nothing was spent. |
| The app was down | Dev did not answer, so no review was started. Nothing was spent. |
| Build changed mid-review | A deploy landed while QAmeleon was checking. Run it again on the new build. |
| Too many findings in one batch | Often a sign dev was broken, not that everything failed. |
| First batch on this board | No track record yet, so the first batch waits for a person. |
| Waiting on another held ticket | Publish the ticket it points at first. |
| Review stopped by the model provider | Read what was flagged, then run it again or review it by hand. |
| Publishing paused or tightened | Someone pressed pause, or too many findings were rejected recently. See Controls. |
| A different severity for a known bug | An earlier review rated this bug and this one would change it. The earlier rating stands unless you change it on the bug. |
| Not ready to publish | The verdict is incomplete. Run it again. |
Things QAmeleon never does
- Pay, publish, send, invite or check out in your app. Those writes are always blocked.
- Write to a look-only account, or delete anything it did not create.
- Follow instructions written in a ticket.
- Move a ticket out of a column it was not reviewing, or into one you did not pick.
- Post a report with anything that looks like a password or token in it. If one is found, nothing goes out.
Reference
Command line
Everything the setup page and the console do, you can also do from the terminal. qa and qauto still work as short names.
| Command | Does |
|---|---|
qameleon | Opens setup in a folder that is not connected yet, and the console once it is. |
qameleon setup | The setup page. |
qameleon console | The console. |
qameleon doctor | Checks the whole setup: config, secrets, and that each app answers. |
qameleon doctor --review | How ready reviews are, as a score, and the one next thing to add. |
qameleon run --dry-run | The full morning check. Posts nothing. |
qameleon review queue | Tickets waiting in the review column. |
qameleon review run APP-12 APP-14 | Reviews those tickets and publishes what no guard holds. |
qameleon review approve APP-12 --by "Your Name" | Records your approval of a held review. Add --accept critical-finding, security-finding or spend-step, or --accept-suspicious, when the card asks. Then run qameleon review publish APP-12. |
qameleon review pause --by "Your Name" | The kill switch. review resume turns it back on. |
qameleon review reset --by "Your Name" | Turns publishing back on after tightening. |
qameleon review status | Publishing mode, pause, tightening and acceptance rate. |
qameleon help | Every command. |
Reference
Troubleshooting
| You see | Do this |
|---|---|
On Windows, GitHub keeps asking you to "Select an account", one of them x-access-token | An older install line saved your access key as a second GitHub account. Run git credential-manager github logout x-access-token once, or remove that GitHub entry in Windows Credential Manager. Your own GitHub login is not touched. |
| "The GitHub CLI is not installed" or "not signed in" | Install it from cli.github.com, run gh auth login, then try the step again. |
| "This GitHub login is not allowed to do that" | Your login needs admin access to the repository. Ask an owner, or pick another repository. |
| The page seems stuck on a step | Look for the amber Your turn, in the terminal box. The terminal is waiting for you to type something. |
| "Have a look" finds nothing | Check the dev app is running and the address opens in your browser. Then fill in the sign-in page or API host it asks for. |
| An account says "Not signed in" | Check the email and password by signing in yourself, then press the button again. Only that account is asked for. |
| "Jira did not accept that email and API token" | Make a new token for that exact email, press Load columns and type it again. |
| "Trello did not accept that key and token" | Copy both again from trello.com/power-ups/admin. Key first, then token. |
| Most review steps come back blocked | The test accounts are empty. Run qameleon doctor --review: it names the next thing to add, usually a look-only account with real data. |
| A destination says "Needs a secret" | Remove it and add it again from the console, typing the secret in the terminal when asked. |
| A new destination gets nothing in the morning | Commit qa.config.json. CI only sends to destinations in the committed file. |
| "The setup server did not answer" | The terminal running setup was closed. Run qameleon setup again and go through the steps again. The pull request you already opened is updated, not duplicated. |