form-tester 0.10.3 → 0.11.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.
|
@@ -5,9 +5,10 @@ Install (user runs once):
|
|
|
5
5
|
npm install -g form-tester
|
|
6
6
|
```
|
|
7
7
|
|
|
8
|
-
Install skill files:
|
|
8
|
+
Install skill files and configure:
|
|
9
9
|
```
|
|
10
10
|
form-tester install
|
|
11
|
+
form-tester init # set baseUrl, pnr, person, etc.
|
|
11
12
|
```
|
|
12
13
|
|
|
13
14
|
Test modes:
|
|
@@ -71,10 +72,13 @@ IMPORTANT: Each prompt below MUST be asked as a separate message to the user. Wa
|
|
|
71
72
|
4. Only after receiving answers to all prompts, proceed with the steps below.
|
|
72
73
|
|
|
73
74
|
Step 1 — Open and setup:
|
|
74
|
-
|
|
75
|
+
You can pass a full URL, a path, or just the form name. The CLI resolves it using `baseUrl` and `skjemaUrl` from config:
|
|
75
76
|
```
|
|
76
|
-
form-tester test
|
|
77
|
+
form-tester test SLV-PasRapp-2020 --auto # just form name
|
|
78
|
+
form-tester test skjemautfyller/SLV-PasRapp-2020 --auto # path
|
|
79
|
+
form-tester test https://example.com/skjemautfyller/X --auto # full URL
|
|
77
80
|
```
|
|
81
|
+
To check resolution: `form-tester url SLV-PasRapp-2020`
|
|
78
82
|
|
|
79
83
|
Step 2 — Dismiss cookies:
|
|
80
84
|
```
|
|
@@ -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
|
|
20
|
-
form-tester test
|
|
21
|
-
form-tester test
|
|
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
|
|
25
|
-
form-tester test
|
|
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
|
|
@@ -8,6 +8,7 @@ User must install globally first:
|
|
|
8
8
|
```bash
|
|
9
9
|
npm install -g form-tester
|
|
10
10
|
form-tester install
|
|
11
|
+
form-tester init # set baseUrl, pnr, person, etc.
|
|
11
12
|
```
|
|
12
13
|
|
|
13
14
|
## Running a test
|
|
@@ -16,16 +17,15 @@ When the user gives you a form URL to test, execute ALL steps below in sequence
|
|
|
16
17
|
|
|
17
18
|
### Step 1 — Start the test
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
form-tester test <full-url> --auto
|
|
23
|
-
```
|
|
24
|
-
Or with options:
|
|
20
|
+
You can pass a full URL, a path, or just the form name. The CLI resolves it using `baseUrl` and `skjemaUrl` from config:
|
|
25
21
|
```bash
|
|
26
|
-
form-tester test
|
|
22
|
+
form-tester test SLV-PasRapp-2020 --auto # just form name
|
|
23
|
+
form-tester test skjemautfyller/SLV-PasRapp-2020 --auto # path
|
|
24
|
+
form-tester test https://example.com/skjemautfyller/X --auto # full URL
|
|
27
25
|
```
|
|
28
26
|
|
|
27
|
+
To check how a form name resolves: `form-tester url SLV-PasRapp-2020`
|
|
28
|
+
|
|
29
29
|
### Step 2 — Dismiss cookies
|
|
30
30
|
```bash
|
|
31
31
|
form-tester cookies
|
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
|
+
const LOCAL_VERSION = "0.11.1";
|
|
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);
|
|
@@ -921,9 +936,11 @@ function printHelp() {
|
|
|
921
936
|
[
|
|
922
937
|
"",
|
|
923
938
|
"Subcommands (run directly):",
|
|
939
|
+
" form-tester init Set up config (baseUrl, pnr, person, etc.)",
|
|
924
940
|
" form-tester install [--global] Install skill files into project or ~/.claude/skills/",
|
|
925
|
-
" form-tester test <url> --auto
|
|
926
|
-
" form-tester test <url> --human
|
|
941
|
+
" form-tester test <name-or-url> --auto Non-interactive test (for AI agents)",
|
|
942
|
+
" form-tester test <name-or-url> --human Interactive test with prompts",
|
|
943
|
+
" form-tester url <name-or-path> Resolve form name/path to full URL",
|
|
927
944
|
" form-tester exec <command> [args] Run playwright-cli command (recorded)",
|
|
928
945
|
" form-tester replay <recording.json> Replay a recorded test run",
|
|
929
946
|
" form-tester cookies Dismiss cookie banner",
|
|
@@ -1720,6 +1737,51 @@ function install(targetDir, isGlobal) {
|
|
|
1720
1737
|
async function main() {
|
|
1721
1738
|
const args = process.argv.slice(2);
|
|
1722
1739
|
|
|
1740
|
+
if (args[0] === "init") {
|
|
1741
|
+
const config = loadConfig();
|
|
1742
|
+
console.log("Form Tester Setup\n");
|
|
1743
|
+
console.log("Current config:");
|
|
1744
|
+
console.log(` baseUrl: ${config.baseUrl || "(not set)"}`);
|
|
1745
|
+
console.log(` pnr: ${config.pnr || "(not set)"}`);
|
|
1746
|
+
console.log(` person: ${config.person || "(not set)"}`);
|
|
1747
|
+
console.log(` skjemaUrl: ${config.skjemaUrl || "/skjemautfyller"}`);
|
|
1748
|
+
console.log(` dokumenterUrl: ${config.dokumenterUrlTemplate || "/dokumenter?pnr={PNR}"}`);
|
|
1749
|
+
console.log("");
|
|
1750
|
+
|
|
1751
|
+
const currentRl = ensureReadline();
|
|
1752
|
+
|
|
1753
|
+
const prompt = (question, current) => new Promise((resolve) => {
|
|
1754
|
+
const suffix = current ? ` [${current}]` : "";
|
|
1755
|
+
currentRl.question(`${question}${suffix}: `, (answer) => {
|
|
1756
|
+
resolve(answer.trim() || current || "");
|
|
1757
|
+
});
|
|
1758
|
+
});
|
|
1759
|
+
|
|
1760
|
+
config.baseUrl = await prompt("Base URL (e.g. https://tjenester-a-vak-sprak.int-hn.nhn.no)", config.baseUrl);
|
|
1761
|
+
config.pnr = await prompt("PNR (fødselsnummer for test)", config.pnr);
|
|
1762
|
+
config.person = await prompt("Default person name (e.g. Uromantisk Direktør)", config.person);
|
|
1763
|
+
config.skjemaUrl = await prompt("Skjema path prefix", config.skjemaUrl || "/skjemautfyller");
|
|
1764
|
+
config.dokumenterUrlTemplate = await prompt("Dokumenter URL template", config.dokumenterUrlTemplate || "/dokumenter?pnr={PNR}");
|
|
1765
|
+
|
|
1766
|
+
saveConfig(config);
|
|
1767
|
+
currentRl.close();
|
|
1768
|
+
|
|
1769
|
+
console.log("\nConfig saved to form-tester.config.json:");
|
|
1770
|
+
console.log(` baseUrl: ${config.baseUrl}`);
|
|
1771
|
+
console.log(` pnr: ${config.pnr}`);
|
|
1772
|
+
console.log(` person: ${config.person}`);
|
|
1773
|
+
console.log(` skjemaUrl: ${config.skjemaUrl}`);
|
|
1774
|
+
console.log(` dokumenterUrl: ${config.dokumenterUrlTemplate}`);
|
|
1775
|
+
|
|
1776
|
+
// Test URL resolution
|
|
1777
|
+
console.log(`\nTest: form-tester test SLV-PasRapp-2020 --auto`);
|
|
1778
|
+
const testUrl = resolveFormUrl("SLV-PasRapp-2020", config);
|
|
1779
|
+
const withPnr = config.pnr && !extractPnrFromUrl(testUrl) ? setPnrOnUrl(testUrl, config.pnr) : testUrl;
|
|
1780
|
+
console.log(` → ${withPnr}`);
|
|
1781
|
+
|
|
1782
|
+
process.exit(0);
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1723
1785
|
if (args[0] === "install") {
|
|
1724
1786
|
const isGlobal = args.includes("--global") || args.includes("-g");
|
|
1725
1787
|
const remaining = args.slice(1).filter((a) => a !== "--global" && a !== "-g");
|
|
@@ -1824,6 +1886,34 @@ async function main() {
|
|
|
1824
1886
|
process.exit(code);
|
|
1825
1887
|
}
|
|
1826
1888
|
|
|
1889
|
+
if (args[0] === "url") {
|
|
1890
|
+
const config = loadConfig();
|
|
1891
|
+
const input = args.slice(1).join(" ");
|
|
1892
|
+
if (!input) {
|
|
1893
|
+
console.error("Usage: form-tester url <form-name-or-path>");
|
|
1894
|
+
console.error("\nExamples:");
|
|
1895
|
+
console.error(" form-tester url SLV-PasRapp-2020");
|
|
1896
|
+
console.error(" form-tester url skjemautfyller/SLV-PasRapp-2020");
|
|
1897
|
+
console.error(" form-tester url https://example.com/skjemautfyller/FORM");
|
|
1898
|
+
console.error(`\nConfig: baseUrl=${config.baseUrl || "(not set)"}, skjemaUrl=${config.skjemaUrl || "/skjemautfyller"}, pnr=${config.pnr || "(not set)"}`);
|
|
1899
|
+
console.error("\nRun 'form-tester init' to configure.");
|
|
1900
|
+
process.exit(1);
|
|
1901
|
+
}
|
|
1902
|
+
let formUrl = resolveFormUrl(input, config);
|
|
1903
|
+
if (config.pnr && !extractPnrFromUrl(formUrl)) {
|
|
1904
|
+
formUrl = setPnrOnUrl(formUrl, config.pnr);
|
|
1905
|
+
}
|
|
1906
|
+
// Also resolve dokumenter URL
|
|
1907
|
+
const tmpConfig = { ...config, lastTestUrl: formUrl };
|
|
1908
|
+
const dokUrl = resolveDokumenterUrl(tmpConfig);
|
|
1909
|
+
|
|
1910
|
+
console.log(`Form URL: ${formUrl}`);
|
|
1911
|
+
console.log(`Dokumenter URL: ${dokUrl || "(not available — set pnr)"}`);
|
|
1912
|
+
console.log(`Person: ${config.person || "(not set)"}`);
|
|
1913
|
+
console.log(`\nRun: form-tester test ${input} --auto`);
|
|
1914
|
+
process.exit(0);
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1827
1917
|
if (args[0] === "cookies") {
|
|
1828
1918
|
const code = await handleCookies();
|
|
1829
1919
|
process.exit(code);
|
|
@@ -1844,12 +1934,13 @@ async function main() {
|
|
|
1844
1934
|
|
|
1845
1935
|
if (args[0] === "test" && args.includes("--human")) {
|
|
1846
1936
|
const config = loadConfig();
|
|
1847
|
-
const
|
|
1937
|
+
const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
|
|
1938
|
+
const rawUrl = args.find((a) => a !== "test" && !a.startsWith("--") && a !== flagVal("--persona") && a !== flagVal("--scenario") && a !== flagVal("--pnr"));
|
|
1939
|
+
const url = rawUrl ? resolveFormUrl(rawUrl, config) : null;
|
|
1848
1940
|
if (!url) {
|
|
1849
|
-
console.error("Usage: form-tester test <url> --human --persona <id> --scenario \"<text>\"");
|
|
1941
|
+
console.error("Usage: form-tester test <form-name-or-url> --human --persona <id> --scenario \"<text>\"");
|
|
1850
1942
|
process.exit(1);
|
|
1851
1943
|
}
|
|
1852
|
-
const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
|
|
1853
1944
|
const personaFlag = flagVal("--persona");
|
|
1854
1945
|
const scenarioFlag = flagVal("--scenario");
|
|
1855
1946
|
|
|
@@ -1876,12 +1967,13 @@ async function main() {
|
|
|
1876
1967
|
|
|
1877
1968
|
if (args[0] === "test" && args.includes("--auto")) {
|
|
1878
1969
|
const config = loadConfig();
|
|
1879
|
-
const
|
|
1970
|
+
const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
|
|
1971
|
+
const rawUrl = args.find((a) => a !== "test" && !a.startsWith("--") && a !== flagVal("--persona") && a !== flagVal("--scenario") && a !== flagVal("--pnr"));
|
|
1972
|
+
const url = rawUrl ? resolveFormUrl(rawUrl, config) : null;
|
|
1880
1973
|
if (!url) {
|
|
1881
|
-
console.error("Usage: form-tester test <url> --auto [--pnr <pnr>] [--persona <id>] [--scenario <text>] [--silent|--verbose]");
|
|
1974
|
+
console.error("Usage: form-tester test <form-name-or-url> --auto [--pnr <pnr>] [--persona <id>] [--scenario <text>] [--silent|--verbose]");
|
|
1882
1975
|
process.exit(1);
|
|
1883
1976
|
}
|
|
1884
|
-
const flagVal = (flag) => args.includes(flag) ? args[args.indexOf(flag) + 1] : undefined;
|
|
1885
1977
|
const verbosity = args.includes("--silent") ? "silent" : args.includes("--verbose") ? "verbose" : "normal";
|
|
1886
1978
|
await handleTestAuto(url, config, {
|
|
1887
1979
|
pnr: flagVal("--pnr"),
|
|
@@ -1941,6 +2033,7 @@ module.exports = {
|
|
|
1941
2033
|
finalizeRecording,
|
|
1942
2034
|
logIssue,
|
|
1943
2035
|
listIssues,
|
|
2036
|
+
resolveFormUrl,
|
|
1944
2037
|
ISSUE_CATEGORIES,
|
|
1945
2038
|
};
|
|
1946
2039
|
|
package/package.json
CHANGED