stably 4.12.15 → 4.12.16

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // ../../app/node_modules/.pnpm/@stablyai-internal+playwright-cli@0.4.29/node_modules/@stablyai-internal/playwright-cli/playwright-cli.js
3
+ // ../../app/node_modules/.pnpm/@stablyai-internal+playwright-cli@0.4.30/node_modules/@stablyai-internal/playwright-cli/playwright-cli.js
4
4
  var fs = require("fs");
5
5
  var path = require("path");
6
6
  if (process.platform === "darwin" && !process.env.PLAYWRIGHT_DAEMON_SOCKETS_DIR) {
@@ -405,9 +405,14 @@ const test = realPw.test.extend({
405
405
  // No close \u2014 preserve state for post-test inspection
406
406
  },
407
407
 
408
- // Test-scoped: reuse the existing page from the daemon's context.
409
- // Applies project options and baseURL wrapper after acquiring the page.
408
+ // Test-scoped: create a fresh page for each test to avoid stale CDP frame references.
409
+ // The previous test's page is closed to free resources. The new page gets a fresh
410
+ // CDP frame, avoiding the "second test always fails" issue where the reused page's
411
+ // internal frame reference becomes invalid between fixture teardown/setup cycles.
410
412
  page: async ({ context, browser, playwright, baseURL, extraHTTPHeaders, httpCredentials, geolocation, permissions, offline }, use, testInfo) => {
413
+ // Get or create a page. We reuse the existing page (don't close it \u2014 closing
414
+ // the last page on a CDP default context can terminate the browser process).
415
+ // Instead, navigate to about:blank to reset frame state.
411
416
  let page = context.pages()[0];
412
417
  if (!page) {
413
418
  try {
@@ -419,11 +424,24 @@ const test = realPw.test.extend({
419
424
  page = ctx.pages()[0] || await ctx.newPage();
420
425
  }
421
426
  }
427
+ // Navigate to about:blank to get a fresh frame/document, avoiding stale
428
+ // frame references from the previous test. This is cheaper than closing
429
+ // and recreating the page (which can kill the CDP browser).
430
+ try {
431
+ await page.goto('about:blank', { timeout: 5000 });
432
+ } catch {
433
+ // If navigation fails, the page might be stale \u2014 create a new one
434
+ try {
435
+ page = await context.newPage();
436
+ } catch (error) {
437
+ if (!isRecoverableCdpError(error)) throw error;
438
+ const freshBrowser = await reconnectBrowser(playwright);
439
+ const ctx = freshBrowser.contexts()[0] || await freshBrowser.newContext();
440
+ page = ctx.pages()[0] || await ctx.newPage();
441
+ }
442
+ }
422
443
 
423
444
  // Apply project options to the reused context.
424
- // Navigate to about:blank first to ensure CDP emulation options (timezone, colorScheme)
425
- // take effect before the test loads any content.
426
- await page.goto('about:blank').catch(() => {});
427
445
  await applyContextOptions(context, page, testInfo, {
428
446
  extraHTTPHeaders, httpCredentials, geolocation, permissions, offline,
429
447
  });
@@ -231,16 +231,13 @@ stably-browser run-test --help
231
231
  - Overrides `browser`/`context`/`page` fixtures to connect via CDP (no new browser launched)
232
232
  - Preserves browser state after the run (pages remain open for inspection)
233
233
 
234
- ### Running Multiple Tests Sequentially (Verification)
234
+ ### Running Multiple Tests Sequential vs Parallel
235
235
 
236
- **CRITICAL:** When verifying that multiple independent tests pass, you **MUST close and reopen the browser** between each `run-test` call. Browser state (cookies, localStorage, auth sessions) persists between runs, and stale state from one test will contaminate the next.
237
-
238
- This applies when you are running separate test files to check they pass — not when intentionally using `run-test` as a setup/seed mechanism (see "Use run-test as a Setup/Seed Mechanism" above).
239
-
240
- **IMPORTANT: `stably-browser close` must be its own separate Bash call.** Do NOT chain it with other commands (e.g., `stably-browser close; stably-browser run-test ...`). The browser is only fully terminated after the Bash command finishes, so chaining means the next command runs on the old browser with stale state.
236
+ When verifying that multiple independent tests pass, each test needs its own clean browser state. Two approaches:
241
237
 
238
+ **Option A: Sequential (close/reopen between each)**
242
239
  ```bash
243
- # CORRECT: Each command is a separate Bash call
240
+ # Each test gets a fresh browser via close/reopen
244
241
  stably-browser run-test tests/login.spec.ts
245
242
  stably-browser close
246
243
  stably-browser run-test tests/checkout.spec.ts
@@ -248,17 +245,30 @@ stably-browser close
248
245
  stably-browser run-test tests/settings.spec.ts
249
246
  ```
250
247
 
248
+ **Option B: Parallel (different browser sessions, run_in_background)**
249
+ ```bash
250
+ # Start tests in parallel on separate browsers (each has clean state)
251
+ stably-browser run-test tests/login.spec.ts # run_in_background: true
252
+ stably-browser -s=browser-2 run-test tests/checkout.spec.ts # run_in_background: true
253
+ stably-browser -s=browser-3 run-test tests/settings.spec.ts # run_in_background: true
254
+ # Poll results with TaskOutput (block: true)
255
+ ```
256
+
257
+ **Rules:**
258
+ - Only use `run_in_background` when running multiple tests in parallel — for single tests, run in foreground
259
+ - Each parallel test MUST target a different browser session (`-s=<name>`)
260
+ - Do NOT run multiple tests on the same browser simultaneously
261
+ - **`stably-browser close` must be its own separate Bash call** — do NOT chain with other commands
262
+
251
263
  ```bash
252
264
  # WRONG: Chaining close with run-test in one command
253
265
  stably-browser close; stably-browser run-test tests/checkout.spec.ts # ← run-test hits old browser
254
- stably-browser close && stably-browser run-test tests/settings.spec.ts # ← same problem
255
266
  ```
256
267
 
257
268
  ```bash
258
- # WRONG: Running independent tests without resetting causes cascading failures
269
+ # WRONG: Running independent tests on the SAME browser without resetting
259
270
  stably-browser run-test tests/login.spec.ts
260
- stably-browser run-test tests/checkout.spec.ts # ← may fail: browser still has login state from test 1
261
- stably-browser run-test tests/settings.spec.ts # ← may fail: stale cookies/auth from previous tests
271
+ stably-browser run-test tests/checkout.spec.ts # ← may fail: stale state from test 1
262
272
  ```
263
273
 
264
274
  **Why this matters:** The browser is a cloud VM that persists across commands. `stably-browser close` terminates it, but only after the Bash call returns. If you chain `close; run-test`, the test runs on the old browser before it's terminated. Running `close` as its own Bash call ensures the old browser is fully gone before the next test starts with a fresh one.
@@ -280,13 +290,20 @@ stably-browser run-test tests/settings.spec.ts # ← may fail: stale cookies/a
280
290
 
281
291
  ## Browser Session Policy
282
292
 
283
- Your environment may enforce a single-session browser policy. When active:
293
+ Your environment may enforce a single-session or multi-session browser policy. **Check the system prompt for which policy is active.**
294
+
295
+ When **single-session** policy is active:
284
296
  - Always use the default session — do not use `-s=<name>`.
285
297
  - Close the current browser before opening a new one.
286
298
  - If the user asks to "open a new browser", close the existing one first.
287
- - Do not use `stably-browser list` — there is at most one session.
288
299
 
289
- When multi-session is allowed, you may use named sessions as documented below.
300
+ When **multi-session** policy is active (up to 5 concurrent browsers):
301
+ - Use the default session (no `-s=` flag) for single-browser workflows
302
+ - Open additional named browsers with `-s=<name>` (e.g., `stably-browser -s=browser-2 open https://bing.com`)
303
+ - Run commands on a specific browser by prefixing with `-s=<name>` (e.g., `stably-browser -s=browser-2 click e5`)
304
+ - Each named session is fully independent (cookies, state, tabs)
305
+ - Do NOT mix commands for different sessions in one Bash call — use separate calls
306
+ - The `-s=<name>` flag must come before the subcommand
290
307
 
291
308
  ## Browser Sessions
292
309
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stably",
3
- "version": "4.12.15",
3
+ "version": "4.12.16",
4
4
  "packageManager": "pnpm@10.24.0",
5
5
  "description": "AI-powered E2E Playwright testing CLI. Stably can understand your codebase, edit/run tests, and handle complex test scenarios for you.",
6
6
  "main": "dist/index.mjs",
@@ -87,7 +87,7 @@
87
87
  "playwright": "1.59.0-alpha-1771104257000",
88
88
  "@stablyai/codegen-agent-constants": "workspace:*",
89
89
  "@stablyai-internal/api-client": "workspace:*",
90
- "@stablyai-internal/playwright-cli": "0.4.29",
90
+ "@stablyai-internal/playwright-cli": "0.4.30",
91
91
  "@stablyai-internal/pwtrace": "0.3.1",
92
92
  "@stablyai/agent-hooks": "workspace:*",
93
93
  "@stablyai/agent-schemas": "workspace:*",