form-tester 0.10.3 → 0.11.0

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.
@@ -71,10 +71,13 @@ IMPORTANT: Each prompt below MUST be asked as a separate message to the user. Wa
71
71
  4. Only after receiving answers to all prompts, proceed with the steps below.
72
72
 
73
73
  Step 1 — Open and setup:
74
- If the user gives a partial URL (e.g. `skjemautfyller/SLV-PasRapp-2020`), read `form-tester.config.json` to get `baseUrl` and `pnr`. Construct the full URL as `{baseUrl}/{path}?pnr={pnr}`. Do NOT guess the domain.
74
+ You can pass a full URL, a path, or just the form name. The CLI resolves it using `baseUrl` and `skjemaUrl` from config:
75
75
  ```
76
- form-tester test <full-url> --auto --pnr <pnr> --persona <id> --scenario "<text>"
76
+ form-tester test SLV-PasRapp-2020 --auto # just form name
77
+ form-tester test skjemautfyller/SLV-PasRapp-2020 --auto # path
78
+ form-tester test https://example.com/skjemautfyller/X --auto # full URL
77
79
  ```
80
+ To check resolution: `form-tester url SLV-PasRapp-2020`
78
81
 
79
82
  Step 2 — Dismiss cookies:
80
83
  ```
@@ -16,13 +16,17 @@ npm install -g form-tester
16
16
  form-tester install
17
17
  form-tester install --global # or install to ~/.claude/skills/
18
18
 
19
- # Non-interactive mode (no prompts, best for AI agents):
20
- form-tester test <url> --auto
21
- form-tester test <url> --auto --pnr 12345 --persona ung-mann --scenario "test validation"
19
+ # Non-interactive mode accepts form name, path, or full URL:
20
+ form-tester test SLV-PasRapp-2020 --auto
21
+ form-tester test SLV-PasRapp-2020 --auto --pnr 12345 --persona ung-mann
22
+ form-tester test https://example.com/skjemautfyller/FORM --auto
22
23
 
23
24
  # 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
+ form-tester test SLV-PasRapp-2020 --human # lists personas
26
+ form-tester test SLV-PasRapp-2020 --human --persona ung-mann --scenario "X" # with choices
27
+
28
+ # Check URL resolution:
29
+ form-tester url SLV-PasRapp-2020
26
30
 
27
31
  # Full interactive CLI:
28
32
  form-tester
@@ -16,16 +16,15 @@ When the user gives you a form URL to test, execute ALL steps below in sequence
16
16
 
17
17
  ### Step 1 — Start the test
18
18
 
19
- If the user gives a partial URL (e.g. `skjemautfyller/SLV-PasRapp-2020`), read `form-tester.config.json` first to get `baseUrl` and `pnr`. Construct the full URL as `{baseUrl}/{partial-path}?pnr={pnr}`. Do NOT guess the domain — always use `baseUrl` from config.
20
-
21
- ```bash
22
- form-tester test <full-url> --auto
23
- ```
24
- Or with options:
19
+ You can pass a full URL, a path, or just the form name. The CLI resolves it using `baseUrl` and `skjemaUrl` from config:
25
20
  ```bash
26
- form-tester test <full-url> --auto --pnr 12345 --persona ung-mann --scenario "test validation"
21
+ form-tester test SLV-PasRapp-2020 --auto # just form name
22
+ form-tester test skjemautfyller/SLV-PasRapp-2020 --auto # path
23
+ form-tester test https://example.com/skjemautfyller/X --auto # full URL
27
24
  ```
28
25
 
26
+ To check how a form name resolves: `form-tester url SLV-PasRapp-2020`
27
+
29
28
  ### Step 2 — Dismiss cookies
30
29
  ```bash
31
30
  form-tester cookies
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "pnr": "YOUR_PNR_HERE",
3
3
  "person": "",
4
- "baseUrl": ""
4
+ "baseUrl": "",
5
+ "skjemaUrl": "/skjemautfyller"
5
6
  }
package/form-tester.js CHANGED
@@ -7,7 +7,7 @@ const { spawn, execSync } = require("child_process");
7
7
  const CONFIG_PATH = path.join(process.cwd(), "form-tester.config.json");
8
8
  const OUTPUT_BASE = path.resolve(process.cwd(), "output");
9
9
  const ISSUES_PATH = path.join(OUTPUT_BASE, "issues.jsonl");
10
- const LOCAL_VERSION = "0.10.3";
10
+ const LOCAL_VERSION = "0.11.0";
11
11
  const RECOMMENDED_PERSON = "Uromantisk Direktør";
12
12
 
13
13
  // Recording — persisted to disk so `form-tester exec` can append across processes
@@ -659,6 +659,7 @@ const DEFAULT_CONFIG = {
659
659
  pnr: "",
660
660
  person: "",
661
661
  baseUrl: "",
662
+ skjemaUrl: "/skjemautfyller",
662
663
  dokumenterUrlTemplate: "/dokumenter?pnr={PNR}",
663
664
  lastTestUrl: "",
664
665
  lastRunDir: "",
@@ -694,6 +695,20 @@ function resolveDokumenterUrl(config) {
694
695
  return url;
695
696
  }
696
697
 
698
+ function resolveFormUrl(input, config) {
699
+ // If it's already a full URL, return as-is
700
+ if (input.startsWith("http://") || input.startsWith("https://")) return input;
701
+ const base = config.baseUrl || "";
702
+ // If it's a path like /skjemautfyller/FORM-ID or skjemautfyller/FORM-ID
703
+ if (input.includes("/")) {
704
+ const path = input.startsWith("/") ? input : `/${input}`;
705
+ return `${base}${path}`;
706
+ }
707
+ // It's just a form name like SLV-PasRapp-2020
708
+ const skjema = config.skjemaUrl || "/skjemautfyller";
709
+ return `${base}${skjema}/${input}`;
710
+ }
711
+
697
712
  function extractPnrFromUrl(url) {
698
713
  try {
699
714
  const parsed = new URL(url);
@@ -922,8 +937,9 @@ function printHelp() {
922
937
  "",
923
938
  "Subcommands (run directly):",
924
939
  " form-tester install [--global] Install skill files into project or ~/.claude/skills/",
925
- " form-tester test <url> --auto Non-interactive test (for AI agents)",
926
- " form-tester test <url> --human Interactive test with prompts",
940
+ " form-tester test <name-or-url> --auto Non-interactive test (for AI agents)",
941
+ " form-tester test <name-or-url> --human Interactive test with prompts",
942
+ " form-tester url <name-or-path> Resolve form name/path to full URL",
927
943
  " form-tester exec <command> [args] Run playwright-cli command (recorded)",
928
944
  " form-tester replay <recording.json> Replay a recorded test run",
929
945
  " form-tester cookies Dismiss cookie banner",
@@ -1824,6 +1840,26 @@ async function main() {
1824
1840
  process.exit(code);
1825
1841
  }
1826
1842
 
1843
+ if (args[0] === "url") {
1844
+ const config = loadConfig();
1845
+ const input = args.slice(1).join(" ");
1846
+ if (!input) {
1847
+ console.error("Usage: form-tester url <form-name-or-path>");
1848
+ console.error("\nExamples:");
1849
+ console.error(" form-tester url SLV-PasRapp-2020");
1850
+ console.error(" form-tester url skjemautfyller/SLV-PasRapp-2020");
1851
+ console.error(" form-tester url https://example.com/skjemautfyller/FORM");
1852
+ console.error(`\nConfig: baseUrl=${config.baseUrl || "(not set)"}, skjemaUrl=${config.skjemaUrl || "/skjemautfyller"}, pnr=${config.pnr || "(not set)"}`);
1853
+ process.exit(1);
1854
+ }
1855
+ let resolved = resolveFormUrl(input, config);
1856
+ if (config.pnr && !extractPnrFromUrl(resolved)) {
1857
+ resolved = setPnrOnUrl(resolved, config.pnr);
1858
+ }
1859
+ console.log(resolved);
1860
+ process.exit(0);
1861
+ }
1862
+
1827
1863
  if (args[0] === "cookies") {
1828
1864
  const code = await handleCookies();
1829
1865
  process.exit(code);
@@ -1844,12 +1880,13 @@ async function main() {
1844
1880
 
1845
1881
  if (args[0] === "test" && args.includes("--human")) {
1846
1882
  const config = loadConfig();
1847
- const url = args.find((a) => a.startsWith("http"));
1883
+ const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
1884
+ const rawUrl = args.find((a) => a !== "test" && !a.startsWith("--") && a !== flagVal("--persona") && a !== flagVal("--scenario") && a !== flagVal("--pnr"));
1885
+ const url = rawUrl ? resolveFormUrl(rawUrl, config) : null;
1848
1886
  if (!url) {
1849
- console.error("Usage: form-tester test <url> --human --persona <id> --scenario \"<text>\"");
1887
+ console.error("Usage: form-tester test <form-name-or-url> --human --persona <id> --scenario \"<text>\"");
1850
1888
  process.exit(1);
1851
1889
  }
1852
- const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
1853
1890
  const personaFlag = flagVal("--persona");
1854
1891
  const scenarioFlag = flagVal("--scenario");
1855
1892
 
@@ -1876,12 +1913,13 @@ async function main() {
1876
1913
 
1877
1914
  if (args[0] === "test" && args.includes("--auto")) {
1878
1915
  const config = loadConfig();
1879
- const url = args.find((a) => a.startsWith("http"));
1916
+ const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
1917
+ const rawUrl = args.find((a) => a !== "test" && !a.startsWith("--") && a !== flagVal("--persona") && a !== flagVal("--scenario") && a !== flagVal("--pnr"));
1918
+ const url = rawUrl ? resolveFormUrl(rawUrl, config) : null;
1880
1919
  if (!url) {
1881
- console.error("Usage: form-tester test <url> --auto [--pnr <pnr>] [--persona <id>] [--scenario <text>] [--silent|--verbose]");
1920
+ console.error("Usage: form-tester test <form-name-or-url> --auto [--pnr <pnr>] [--persona <id>] [--scenario <text>] [--silent|--verbose]");
1882
1921
  process.exit(1);
1883
1922
  }
1884
- const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
1885
1923
  const verbosity = args.includes("--silent") ? "silent" : args.includes("--verbose") ? "verbose" : "normal";
1886
1924
  await handleTestAuto(url, config, {
1887
1925
  pnr: flagVal("--pnr"),
@@ -1941,6 +1979,7 @@ module.exports = {
1941
1979
  finalizeRecording,
1942
1980
  logIssue,
1943
1981
  listIssues,
1982
+ resolveFormUrl,
1944
1983
  ISSUE_CATEGORIES,
1945
1984
  };
1946
1985
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "form-tester",
3
- "version": "0.10.3",
3
+ "version": "0.11.0",
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": {