zerocheck 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -65
- package/dist/index.js +41 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,57 +1,58 @@
|
|
|
1
1
|
# Zerocheck
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Zerocheck is an AI QA engineer that tests your app end to end. Verify critical flows and find bugs with a prompt.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This is the Zerocheck CLI.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Have these ready:
|
|
7
|
+
```yaml
|
|
8
|
+
# zerocheck/tests/discount-code.yaml
|
|
9
|
+
version: zerocheck/v1
|
|
10
|
+
name: Discount code reaches confirmation
|
|
11
|
+
blocks_merge: true
|
|
12
|
+
steps:
|
|
13
|
+
- Navigate to /cart
|
|
14
|
+
- Enter "SPRING20" into "Discount code"
|
|
15
|
+
- Click "Apply"
|
|
16
|
+
- Verify text "Discount applied" is visible
|
|
17
|
+
- Enter "4242424242424242" into "Card number"
|
|
18
|
+
- Click "Place order"
|
|
19
|
+
- Verify text "Order confirmed" is visible
|
|
20
|
+
```
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
- **Your instance URL** and account access, supplied during onboarding.
|
|
25
|
-
- **Your project files:** `zerocheck.yaml` with the correct project, environment and app URL, plus at least one saved YAML test in its configured test directory. We set up these files with you during onboarding.
|
|
26
|
-
- **A running app** reachable from your machine, with the test accounts and credential variables your tests need.
|
|
22
|
+
The CLI runs YAML tests like this one in a Chromium browser on your machine or a CI runner. Your dedicated Zerocheck instance reads each test, makes the model calls and keeps the results. The CLI drives the browser for it and keeps your test secret values on your machine.
|
|
27
23
|
|
|
28
|
-
##
|
|
24
|
+
## Quick start
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
Zerocheck needs a dedicated instance, which we set up with you during [hands-on onboarding](https://tryzerocheck.com/onboarding/). There is no default public service. You'll also need Node.js 20.19 or newer, `zerocheck.yaml` and at least one saved test. We set those up with you too.
|
|
31
27
|
|
|
32
28
|
```bash
|
|
33
|
-
npm install --save-dev --save-exact zerocheck
|
|
29
|
+
npm install --save-dev --save-exact zerocheck
|
|
34
30
|
npx playwright install chromium
|
|
35
31
|
export ZEROCHECK_API="https://your-instance.example.com"
|
|
36
32
|
npx zerocheck login
|
|
37
|
-
npx zerocheck run
|
|
33
|
+
npx zerocheck run
|
|
38
34
|
```
|
|
39
35
|
|
|
40
|
-
`
|
|
36
|
+
`login` prints a URL and a code for you to approve in your browser. `run` executes the tests in your configured test directory and prints each result with a link to the run. Open it to see the steps and screenshots, and the recording of each test that uses no configured secrets. To run one test, use its path: `npx zerocheck run zerocheck/tests/discount-code.yaml`.
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
In CI, set `ZEROCHECK_API` and a project token from Settings as `ZEROCHECK_TOKEN` instead of signing in.
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
## Commands
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
| Command | What it does |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `login` | Sign in and authorize this device for a project |
|
|
45
|
+
| `logout` | Revoke this device login and clear its local token |
|
|
46
|
+
| `whoami` | Show the instance and project you're signed in to |
|
|
47
|
+
| `run [paths...]` | Run tests in your browser |
|
|
48
|
+
|
|
49
|
+
`run` options: `--env <name>`, `--json <path>`, `--fail-on-flaky`, `--headed` and `--project-dir <dir>`.
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
Exit codes: **0** every blocking test passed. **1** a blocking test failed, or with `--fail-on-flaky` passed only after a retry. **2** the run gave no verdict.
|
|
51
52
|
|
|
52
|
-
## Test secrets
|
|
53
|
+
## Test secrets
|
|
53
54
|
|
|
54
|
-
Reference each secret in `zerocheck.yaml` as an environment variable and set that variable where the CLI runs:
|
|
55
|
+
Reference each secret in `zerocheck.yaml` as an environment variable, and set that variable where the CLI runs:
|
|
55
56
|
|
|
56
57
|
```yaml
|
|
57
58
|
environments:
|
|
@@ -63,38 +64,12 @@ environments:
|
|
|
63
64
|
- Enter "{{credential:PASSWORD}}" into "Password"
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
The instance receives the selected test files, the environment's settings without secret values, and what the browser shows while the tests run: page snapshots, screenshots, recordings and console messages.
|
|
69
|
-
|
|
70
|
-
## What a test looks like
|
|
71
|
-
|
|
72
|
-
Each repository test is a readable YAML file. Adapt this example to a route and outcome that exist in your app:
|
|
73
|
-
|
|
74
|
-
```yaml
|
|
75
|
-
version: zerocheck/v1
|
|
76
|
-
name: Release notes are available
|
|
77
|
-
blocks_merge: true
|
|
78
|
-
steps:
|
|
79
|
-
- Navigate to /releases
|
|
80
|
-
- Verify the Release notes heading is visible
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
To bring a test you made in the web app into your repository, use **Download YAML** and put that file in the configured test directory. This creates an independent copy.
|
|
84
|
-
|
|
85
|
-
## When a run needs attention
|
|
67
|
+
Your instance receives each secret's name, never its value. It does receive the selected test files and what the browser shows while tests run, so the CLI needs network access and doesn't run offline.
|
|
86
68
|
|
|
87
|
-
|
|
88
|
-
| --- | --- |
|
|
89
|
-
| No instance configured | Set `ZEROCHECK_API` to your customer instance before signing in. |
|
|
90
|
-
| No configuration or tests found | Add the project configuration and saved YAML tests. |
|
|
91
|
-
| Missing test secrets | Set the environment variables your configured environment references. |
|
|
92
|
-
| A test fails or cannot complete | Open the results link and inspect the failed step and its evidence. |
|
|
93
|
-
| Your instance is running as many runs as it allows | Try again shortly. |
|
|
94
|
-
| The run is not finished on your instance | Run `zerocheck run` again in the same folder: it finishes the earlier run first, then runs the tests you asked for. |
|
|
69
|
+
## Web app or CLI
|
|
95
70
|
|
|
96
|
-
|
|
71
|
+
Tests you create in the web app run there in a hosted browser, with nothing to install. To bring one into your repository, use **Download YAML** and put the file in your test directory. That is an independent copy: editing, renaming or deleting the file, or running it with the CLI, never changes the test in the web app. To update the web copy from a file, use **Upload YAML** in the web app; a file downloaded from there replaces its test only after you confirm.
|
|
97
72
|
|
|
98
|
-
|
|
73
|
+
## Documentation
|
|
99
74
|
|
|
100
|
-
[
|
|
75
|
+
[CLI guide](https://tryzerocheck.com/docs/cli/) · [Web app](https://tryzerocheck.com/docs/web-app/) · [Run in CI](https://tryzerocheck.com/docs/github-actions/) · [Credentials and data](https://tryzerocheck.com/docs/security/) · [Pricing](https://tryzerocheck.com/pricing/)
|
package/dist/index.js
CHANGED
|
@@ -4862,12 +4862,49 @@ async function installNavigationGuard(page, options) {
|
|
|
4862
4862
|
}
|
|
4863
4863
|
|
|
4864
4864
|
// ../../src/agent/browser-session.ts
|
|
4865
|
+
var RECORDING_FRAME_INTERVAL_MS = 1e3;
|
|
4866
|
+
function keepRecordingCurrent(page, intervalMs = RECORDING_FRAME_INTERVAL_MS) {
|
|
4867
|
+
let client, pending = false, stopped = false;
|
|
4868
|
+
const capture = async () => {
|
|
4869
|
+
if (!client) {
|
|
4870
|
+
const created = await page.context().newCDPSession(page);
|
|
4871
|
+
if (stopped) {
|
|
4872
|
+
await created.detach().catch(() => {
|
|
4873
|
+
});
|
|
4874
|
+
return;
|
|
4875
|
+
}
|
|
4876
|
+
client = created;
|
|
4877
|
+
}
|
|
4878
|
+
await client.send("Page.captureScreenshot", { format: "jpeg", quality: 1 });
|
|
4879
|
+
};
|
|
4880
|
+
const timer = setInterval(() => {
|
|
4881
|
+
if (pending || stopped) return;
|
|
4882
|
+
pending = true;
|
|
4883
|
+
void capture().catch(() => {
|
|
4884
|
+
}).finally(() => {
|
|
4885
|
+
pending = false;
|
|
4886
|
+
});
|
|
4887
|
+
}, intervalMs);
|
|
4888
|
+
timer.unref?.();
|
|
4889
|
+
const stop = () => {
|
|
4890
|
+
if (stopped) return;
|
|
4891
|
+
stopped = true;
|
|
4892
|
+
clearInterval(timer);
|
|
4893
|
+
page.off("close", stop);
|
|
4894
|
+
void client?.detach().catch(() => {
|
|
4895
|
+
});
|
|
4896
|
+
};
|
|
4897
|
+
page.once("close", stop);
|
|
4898
|
+
return stop;
|
|
4899
|
+
}
|
|
4865
4900
|
var BrowserSession = class {
|
|
4866
4901
|
context;
|
|
4867
4902
|
page;
|
|
4868
4903
|
releaseGuard;
|
|
4869
4904
|
console = new ConsoleRecorder();
|
|
4870
4905
|
stage = "new";
|
|
4906
|
+
recording = false;
|
|
4907
|
+
stopRecordingFrames;
|
|
4871
4908
|
/** The latest refusal and guard failure, kept so a lost message cannot hide them. */
|
|
4872
4909
|
denied;
|
|
4873
4910
|
failure;
|
|
@@ -4914,6 +4951,7 @@ var BrowserSession = class {
|
|
|
4914
4951
|
const video = options.recordVideo && !env.secrets.length;
|
|
4915
4952
|
await this.setup("new", "opening", "context", async () => {
|
|
4916
4953
|
this.context = await env.browser.newContext({ viewport, ...video ? { recordVideo: { dir: env.videoDir, size: viewport } } : {}, ...env.allowRequest ? { serviceWorkers: "block" } : {} });
|
|
4954
|
+
this.recording = video;
|
|
4917
4955
|
});
|
|
4918
4956
|
}
|
|
4919
4957
|
async prepareContext(defaultTimeoutMs) {
|
|
@@ -4988,12 +5026,14 @@ var BrowserSession = class {
|
|
|
4988
5026
|
});
|
|
4989
5027
|
});
|
|
4990
5028
|
this.console.attach(page);
|
|
5029
|
+
if (this.recording) this.stopRecordingFrames = keepRecordingCurrent(page);
|
|
4991
5030
|
}
|
|
4992
5031
|
drainConsole() {
|
|
4993
5032
|
return redactConsoleLogs(this.console.drain(), this.env.secrets);
|
|
4994
5033
|
}
|
|
4995
5034
|
async closeContext() {
|
|
4996
5035
|
this.stage = "closed";
|
|
5036
|
+
this.stopRecordingFrames?.();
|
|
4997
5037
|
this.console.dispose();
|
|
4998
5038
|
await this.context?.close();
|
|
4999
5039
|
}
|
|
@@ -6413,7 +6453,7 @@ function unlinkQuietly(path) {
|
|
|
6413
6453
|
}
|
|
6414
6454
|
|
|
6415
6455
|
// package.json
|
|
6416
|
-
var version = "0.2.
|
|
6456
|
+
var version = "0.2.2";
|
|
6417
6457
|
|
|
6418
6458
|
// src/index.ts
|
|
6419
6459
|
var program = new Command().name("zerocheck").version(version).description("Run Zerocheck browser tests on your own machine.").exitOverride();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zerocheck",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Zerocheck is an AI QA engineer that tests your app end to end. Run saved YAML tests with the CLI, on your machine or in CI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"qa-agent",
|
|
7
7
|
"ai-testing",
|