@beryl-so/cli 0.46.0 → 0.46.1
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/dist/beryl-test-skill.js +27 -10
- package/dist/commands/accounts.js +3 -0
- package/package.json +5 -3
package/dist/beryl-test-skill.js
CHANGED
|
@@ -159,7 +159,17 @@ An empty \`accounts list\` means nothing is set up. In order of preference:
|
|
|
159
159
|
1. **The user has a dedicated test account** → bank it:
|
|
160
160
|
\`beryl accounts create --email <email> --password <password>\`. A DEDICATED test
|
|
161
161
|
account only — never a real user's.
|
|
162
|
-
2. **
|
|
162
|
+
2. **Only Google (or another SSO) sign-in, no email+password form** → the same path:
|
|
163
|
+
ask for a DEDICATED Google test account and bank it with \`accounts create --email
|
|
164
|
+
--password\`. Its sign-in plan runs through Google's own pages — click the app's
|
|
165
|
+
Google button, fill \`#identifierId\` with \`{{login_email}}\`, click
|
|
166
|
+
\`#identifierNext\`, fill \`input[name=Passwd]\` with \`{{login_password}}\`, click
|
|
167
|
+
\`#passwordNext\`, then assert the app's signed-in shell. Store it with \`accounts
|
|
168
|
+
set-login\`, prove it with \`accounts check\`. Author its tests with \`auth_mode:
|
|
169
|
+
"session"\` only, so Google is signed in once per run, never per test. Google may
|
|
170
|
+
still challenge a scripted sign-in now and then ("Verify it's you"); the captured
|
|
171
|
+
session (end of §1) is the fallback for that, not the default.
|
|
172
|
+
3. **No credentials, but the app has a signup form** → let Beryl make one.
|
|
163
173
|
\`beryl accounts create --type beryl\`, then sign it up with
|
|
164
174
|
\`beryl accounts signup <id> --file <signup-plan.json>\`. The plan is the app's own
|
|
165
175
|
signup form as an ActionPlan, ending LOGGED IN, filling \`{{mailbox_address}}\` and
|
|
@@ -168,7 +178,7 @@ An empty \`accounts list\` means nothing is set up. In order of preference:
|
|
|
168
178
|
or the record was lost) skips signup: store its sign-in with \`accounts set-login\`.
|
|
169
179
|
No password sign-in? Pass \`--login-method otp\` (or \`magic_link\`) and let the plan
|
|
170
180
|
\`await_email\` through; later sign-ins read the same mailbox.
|
|
171
|
-
|
|
181
|
+
4. **Neither** → the flow is not testable authenticated. Say so rather than guessing.
|
|
172
182
|
|
|
173
183
|
A project with no accounts falls back to the \`LOGIN_EMAIL\` variable +
|
|
174
184
|
\`LOGIN_PASSWORD\` secret with the same handle resolution, so existing tests are
|
|
@@ -222,11 +232,13 @@ pending", "the share link is issued") — a real, strong outcome. While AUTHORIN
|
|
|
222
232
|
drive the full handshake live: a second account (\`accounts create --label member\`), or
|
|
223
233
|
a second mailbox (\`mailbox create --label invitee\`, read with \`mailbox read\`).
|
|
224
234
|
|
|
225
|
-
SSO-only sites
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
235
|
+
SSO-only sites are not a dead end: with a dedicated Google test account they follow §1
|
|
236
|
+
item 2 like any password account. The captured session is the FALLBACK — no test account
|
|
237
|
+
can be provided, or Google challenges the scripted sign-in: a human signs in once
|
|
238
|
+
through a live browser view in the Beryl webapp, Beryl stores the session encrypted
|
|
239
|
+
server-side and injects it into cloud runs — \`tests create\` verifies such plans
|
|
240
|
+
server-side, \`runs trigger\` runs them, \`runs local\` skips them (the session never
|
|
241
|
+
leaves Beryl's cloud).
|
|
230
242
|
|
|
231
243
|
## 2. Author locally over the Playwright MCP
|
|
232
244
|
|
|
@@ -349,14 +361,19 @@ Every one of these has produced a wrong plan or a red \`tests create\`. Check th
|
|
|
349
361
|
\`text=X\` to a case-insensitive SUBSTRING — \`text=Continue\` is ambiguous. Use
|
|
350
362
|
something unique (\`button[type=submit]\`, \`input[name=email]\`,
|
|
351
363
|
\`input[autocomplete=one-time-code]\`).
|
|
352
|
-
4. **
|
|
364
|
+
4. **Google's sign-in pages carry decoys.** The identifier page already holds a hidden
|
|
365
|
+
\`input[type=password]\`, so a \`wait_for\` on it fires before the real field exists —
|
|
366
|
+
target \`input[name=Passwd]\`. Responsive layouts often render the app's "Continue
|
|
367
|
+
with Google" button twice (mobile + desktop); add \`:visible\` or use a structural
|
|
368
|
+
selector so the click is not ambiguous.
|
|
369
|
+
5. **A single-page app can redirect after the first \`goto\`.** If \`/dashboard\`
|
|
353
370
|
client-side redirects to \`/dashboard/<id>\`, a click fired straight after the goto
|
|
354
371
|
lands on the pre-redirect render and is discarded on re-render. Put a \`wait_for\`
|
|
355
372
|
on something that exists only AFTER the redirect, then act.
|
|
356
|
-
|
|
373
|
+
6. **Never bake an id into a URL.** \`goto /projects/8ab46d63-.../settings\` breaks for
|
|
357
374
|
any other account. Navigate to the stable entry point and click through
|
|
358
375
|
(\`a[href$='/settings']\`) — the plan is about the app, not your row.
|
|
359
|
-
|
|
376
|
+
7. **Assert durable content, not the empty state.** "No tests yet" is true today and
|
|
360
377
|
false the moment anything exists. Prefer what is structural — a section heading, a
|
|
361
378
|
permanent explainer, an always-present control.
|
|
362
379
|
|
|
@@ -65,6 +65,8 @@ export const testAccountCommands = [
|
|
|
65
65
|
"the site: pass --email and --password, and it is usable immediately. `--type beryl` " +
|
|
66
66
|
"reserves one Beryl will sign up itself, addressed at the project mailbox. It starts " +
|
|
67
67
|
"`pending` and becomes usable after `beryl accounts signup`. " +
|
|
68
|
+
"Works for Google-only apps too: bank a dedicated Google test account as user_provided " +
|
|
69
|
+
"and author its sign-in plan through Google's form. " +
|
|
68
70
|
"The first account an environment gets is its default whatever you pass.",
|
|
69
71
|
scope: "project",
|
|
70
72
|
flags: [
|
|
@@ -98,6 +100,7 @@ export const testAccountCommands = [
|
|
|
98
100
|
"beryl accounts create --email qa@acme.test --password 'hunter2'",
|
|
99
101
|
"beryl accounts create --type beryl --login-method otp",
|
|
100
102
|
"beryl accounts create --email admin@acme.test --password 'hunter2' --label admin",
|
|
103
|
+
"beryl accounts create --email qa@gmail.com --password 'hunter2' # Google-only app",
|
|
101
104
|
],
|
|
102
105
|
async run(ctx, input) {
|
|
103
106
|
const { workspaceId, projectId } = await ctx.requireProject(input);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beryl-so/cli",
|
|
3
|
-
"version": "0.46.
|
|
3
|
+
"version": "0.46.1",
|
|
4
4
|
"description": "Beryl on the command line — projects, runs, the exploring agent, and an MCP server over the same commands.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -40,9 +40,11 @@
|
|
|
40
40
|
"@types/node": "^26.1.1",
|
|
41
41
|
"tsx": "^4.23.1",
|
|
42
42
|
"typescript": "^7.0.2",
|
|
43
|
-
"vitest": "^4.1.
|
|
43
|
+
"vitest": "^4.1.11"
|
|
44
44
|
},
|
|
45
45
|
"overrides": {
|
|
46
|
-
"@hono/node-server": "2.0.11"
|
|
46
|
+
"@hono/node-server": "2.0.11",
|
|
47
|
+
"hono": "^4.13.5",
|
|
48
|
+
"@vitest/mocker": "^4.1.11"
|
|
47
49
|
}
|
|
48
50
|
}
|