form-tester 0.8.1 → 0.8.3

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.
@@ -16,14 +16,23 @@ Test modes:
16
16
  form-tester test <url> --auto
17
17
  form-tester test <url> --auto --pnr 12345 --persona ung-mann
18
18
 
19
- # Human mode — prompts for persona, scenario, person selection:
19
+ # Human mode — user chooses persona and scenario:
20
+ # Step 1: Run without flags to see available personas:
20
21
  form-tester test <url> --human
22
+ # Step 2: Ask the user which persona and scenario they want.
23
+ # Step 3: Re-run with their choices:
24
+ form-tester test <url> --human --persona ung-mann --scenario "test validation"
21
25
 
22
26
  # Full interactive CLI:
23
27
  form-tester
24
28
  ```
25
29
 
26
- When the user asks for human/interactive mode, use `--human`. Otherwise default to `--auto`.
30
+ When the user asks for human/interactive mode, use `--human`:
31
+ 1. First run `form-tester test <url> --human` (no flags) to get the persona list.
32
+ 2. Show the personas to the user and ask them to choose.
33
+ 3. Ask the user for a test scenario (or use "" for standard).
34
+ 4. Re-run with their choices: `form-tester test <url> --human --persona <id> --scenario "<text>"`
35
+ Otherwise default to `--auto`.
27
36
 
28
37
  Commands:
29
38
  ```
@@ -69,27 +78,33 @@ Dokumenter verification (only when modal confirms storage):
69
78
  1. Navigate to `/dokumenter?pnr={PNR}` and select the same person used during form fill.
70
79
  2. The document list loads sorted newest first. The first entry should match the form title.
71
80
  3. Click "Se detaljer" on the first document, then click "Åpne dokumentet".
72
- 4. After clicking "Åpne dokumentet", the document may open in a dialog, a new tab, or inline. FIRST determine the format before capturing:
73
-
74
- Step A Detect format:
75
- Run `form-tester exec snapshot` and examine the result.
76
- - If you see an iframe/embed/object with a src containing `.pdf`, `blob:`, or a PDF viewer it's a PDF.
77
- - If you see rendered HTML content (headings, paragraphs, form data) → it's HTML.
78
- - If `--full-page` screenshot times out it's almost certainly a PDF viewer. Do NOT retry the screenshot. Switch to PDF download.
79
-
80
- Step BPDF documents (viewer in dialog/modal/iframe/new tab):
81
- Do NOT screenshot PDFs it will timeout or produce garbage. Download the file:
82
- 1. Extract PDF URL from the iframe/embed/object:
83
- `form-tester exec eval "document.querySelector('iframe')?.src || document.querySelector('embed')?.src || document.querySelector('object')?.data"`
84
- 2. If the result is a URL, download it with run-code:
85
- `form-tester exec run-code "async page => { const url = await page.evaluate(() => document.querySelector('iframe')?.src || document.querySelector('embed')?.src || document.querySelector('object')?.data); if (url) { const resp = await page.request.get(url); require('fs').writeFileSync('$OUTPUT_DIR/document.pdf', await resp.body()); } }"`
86
- 3. Or if the PDF viewer has a download button, click it.
87
- 4. Record in test_results.txt: document type PDF, downloaded to document.pdf.
88
-
89
- Step C HTML documents:
90
- Take a FULL-PAGE screenshot (`form-tester exec screenshot --filename "$OUTPUT_DIR/document_screenshot.png" --full-page`).
81
+ 4. After clicking "Åpne dokumentet", determine the document format:
82
+
83
+ How to detect format:
84
+ - Take a snapshot: `form-tester exec snapshot`
85
+ - If snapshot shows a link with href containing `/pdf/` or `blob:` → PDF
86
+ - If `--full-page` screenshot times out PDF (do NOT retry, switch to download)
87
+ - If snapshot shows rendered HTML content (headings, paragraphs, form data) HTML
88
+
89
+ PDF documentsDOWNLOAD, do NOT screenshot:
90
+ IMPORTANT: `run-code` does NOT have access to `require` or `fs`. Do NOT use `require('fs')`. Use Playwright's download API instead.
91
+
92
+ Find the PDF download link in the snapshot (look for `a[href*="/pdf/"]` or "Last ned" link), then download using the Playwright download event:
93
+ ```
94
+ form-tester exec run-code "async page => { const link = page.locator('a[href*=\"/pdf/\"]').first(); const [download] = await Promise.all([ page.waitForEvent('download'), link.click() ]); await download.saveAs('$OUTPUT_DIR/document.pdf'); }"
95
+ ```
96
+ If there is no direct PDF link but a "Last ned" button:
97
+ ```
98
+ form-tester exec run-code "async page => { const [download] = await Promise.all([ page.waitForEvent('download'), page.getByRole('link', { name: 'Last ned' }).click() ]); await download.saveAs('$OUTPUT_DIR/document.pdf'); }"
99
+ ```
100
+ Verify the download: check that document.pdf exists in the output folder.
101
+
102
+ HTML documents — SCREENSHOT full page:
103
+ ```
104
+ form-tester exec screenshot --filename "$OUTPUT_DIR/document_screenshot.png" --full-page
105
+ ```
91
106
  Also save raw HTML: `form-tester exec eval "document.documentElement.outerHTML"` → save to document.html.
92
107
 
93
- Step D — XML/other: Note type in test_results.txt, skip capture.
108
+ XML/other: Note type in test_results.txt, skip capture.
94
109
 
95
110
  5. Include the document verification results in test_results.txt (document title, whether it matched the form h1, document type: HTML/PDF/XML).
@@ -20,8 +20,9 @@ form-tester install --global # or install to ~/.claude/skills/
20
20
  form-tester test <url> --auto
21
21
  form-tester test <url> --auto --pnr 12345 --persona ung-mann --scenario "test validation"
22
22
 
23
- # Interactive mode (prompts for persona, scenario, etc.):
24
- form-tester test <url> --human
23
+ # Human mode (user picks persona and scenario):
24
+ form-tester test <url> --human # lists personas, ask user
25
+ form-tester test <url> --human --persona ung-mann --scenario "test X" # run with user's choices
25
26
 
26
27
  # Full interactive CLI:
27
28
  form-tester
@@ -17,8 +17,9 @@ form-tester install
17
17
  form-tester test <url> --auto
18
18
  form-tester test <url> --auto --pnr 12345 --persona ung-mann --scenario "test validation"
19
19
 
20
- # Human mode — prompts for persona, scenario, person selection:
21
- form-tester test <url> --human
20
+ # Human mode — user chooses persona and scenario:
21
+ form-tester test <url> --human # lists personas
22
+ form-tester test <url> --human --persona ung-mann --scenario "test X" # run with choices
22
23
 
23
24
  # Full interactive CLI:
24
25
  form-tester
@@ -26,7 +27,11 @@ form-tester
26
27
 
27
28
  Persona IDs: `ung-mann`, `gravid-kvinne`, `eldre-kvinne`, `kronisk-syk-mann`. Defaults to "noen" if omitted.
28
29
 
29
- When the user asks for `--human` mode, use that flag. Otherwise default to `--auto`.
30
+ When the user asks for `--human` mode:
31
+ 1. Run `form-tester test <url> --human` to get persona list.
32
+ 2. Ask the user to pick a persona and scenario.
33
+ 3. Re-run: `form-tester test <url> --human --persona <id> --scenario "<text>"` (use `""` for standard test).
34
+ Otherwise default to `--auto`.
30
35
 
31
36
  ## Commands
32
37
 
@@ -82,13 +87,18 @@ After submission, read the modal text:
82
87
  - If it mentions Dokumenter storage -> navigate to `/dokumenter?pnr={PNR}`, verify the document appears.
83
88
  - If it does NOT mention Dokumenter -> skip verification, note in test_results.txt.
84
89
 
85
- Document capture — FIRST detect the format by running `form-tester exec snapshot`:
90
+ Document capture — detect format via `form-tester exec snapshot`:
86
91
 
87
- **PDF documents** (iframe/embed with .pdf or blob: URL, or screenshot times out): Do NOT screenshot PDFs. Download instead:
88
- 1. Extract URL: `form-tester exec eval "document.querySelector('iframe')?.src || document.querySelector('embed')?.src || document.querySelector('object')?.data"`
89
- 2. Download: `form-tester exec run-code "async page => { const url = await page.evaluate(() => document.querySelector('iframe')?.src || document.querySelector('embed')?.src || document.querySelector('object')?.data); if (url) { const resp = await page.request.get(url); require('fs').writeFileSync('OUTPUT_DIR/document.pdf', await resp.body()); } }"`
90
- 3. Or click the download button in the PDF viewer if available.
91
- 4. If `--full-page` screenshot times out, it's a PDF switch to download, don't retry screenshot.
92
+ **PDF documents** (link with href containing `/pdf/`, or screenshot times out):
93
+ Do NOT screenshot PDFs. Do NOT use `require('fs')` in run-code (it doesn't exist there).
94
+ Download using Playwright's download event:
95
+ ```
96
+ form-tester exec run-code "async page => { const link = page.locator('a[href*=\"/pdf/\"]').first(); const [download] = await Promise.all([ page.waitForEvent('download'), link.click() ]); await download.saveAs('$OUTPUT_DIR/document.pdf'); }"
97
+ ```
98
+ Or if there's a "Last ned" button:
99
+ ```
100
+ form-tester exec run-code "async page => { const [download] = await Promise.all([ page.waitForEvent('download'), page.getByRole('link', { name: 'Last ned' }).click() ]); await download.saveAs('$OUTPUT_DIR/document.pdf'); }"
101
+ ```
92
102
 
93
103
  **HTML documents**: `form-tester exec screenshot --filename "..." --full-page`. Also save raw HTML.
94
104
 
package/form-tester.js CHANGED
@@ -6,7 +6,7 @@ const { spawn, execSync } = require("child_process");
6
6
 
7
7
  const CONFIG_PATH = path.join(process.cwd(), "form-tester.config.json");
8
8
  const OUTPUT_BASE = path.resolve(process.cwd(), "output");
9
- const LOCAL_VERSION = "0.8.1";
9
+ const LOCAL_VERSION = "0.8.3";
10
10
  const RECOMMENDED_PERSON = "Uromantisk Direktør";
11
11
 
12
12
  // Recording — persisted to disk so `form-tester exec` can append across processes
@@ -1321,10 +1321,31 @@ async function main() {
1321
1321
  const config = loadConfig();
1322
1322
  const url = args.find((a) => a.startsWith("http"));
1323
1323
  if (!url) {
1324
- console.error("Usage: form-tester test <url> --human");
1324
+ console.error("Usage: form-tester test <url> --human --persona <id> --scenario \"<text>\"");
1325
1325
  process.exit(1);
1326
1326
  }
1327
- await handleTest(url, config);
1327
+ const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
1328
+ const personaFlag = flagVal("--persona");
1329
+ const scenarioFlag = flagVal("--scenario");
1330
+
1331
+ // If persona or scenario missing, print choices and exit so the AI can ask the user
1332
+ if (!personaFlag || scenarioFlag === undefined) {
1333
+ console.log("HUMAN MODE: Ask the user to choose persona and scenario, then re-run with flags.\n");
1334
+ console.log("Available personas:");
1335
+ console.log(formatPersonaList());
1336
+ console.log("\nPersona IDs: ung-mann, gravid-kvinne, eldre-kvinne, kronisk-syk-mann, noen");
1337
+ console.log("\nRe-run with: form-tester test <url> --human --persona <id> --scenario \"<description>\"");
1338
+ console.log("Use --scenario \"\" for standard test.");
1339
+ process.exit(0);
1340
+ }
1341
+
1342
+ // Run with user's choices
1343
+ await handleTestAuto(url, config, {
1344
+ pnr: flagVal("--pnr"),
1345
+ persona: personaFlag,
1346
+ scenario: scenarioFlag || undefined,
1347
+ verbosity: "normal",
1348
+ });
1328
1349
  process.exit(0);
1329
1350
  }
1330
1351
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "form-tester",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "AI-powered form testing skill for /skjemautfyller forms using Playwright CLI. Works with Claude Code and GitHub Copilot.",
5
5
  "main": "form-tester.js",
6
6
  "bin": {