fix(add-portal): keep generated tests offline in CI (#714)

* fix(add-portal): keep generated tests offline in CI

* docs(changelog): reference portal test fix PR 714

* chore: drop the CHANGELOG hunk, the file is frozen since #800

Release notes are generated from PR titles now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Mads Lorentzen <madslorentzen17@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-11-09 21:17:38 +01:00
1 parent ccc1c04765
commit e9ab29dcc2
1 file changed
+3 -3
+3 -3
View File
@@ -93,7 +93,7 @@ These conventions are what make portal skills interchangeable for `/scrape` and
- **`SKILL.md` body:** what the skill searches, the personal-use warning if Step 2 found terms restrictions, command reference with flags, 4-6 usage examples using the user's market (real cities, realistic roles), output-format table, and a Notes section recording portal quirks found in Step 2. If Step 2.5 found the portal needs a credential, add a **Setup** section naming the service, the exact environment variable to export, and the fact that every call is billed - stated where the user reads it before running the skill, not after. Under the search command, write one line `Query syntax: ...` stating whether the portal honours phrase quoting and which operators, if any, it supports (e.g. `Query syntax: double quotes inside the argument make an exact phrase, word order included; no OR.`). `/scrape` sends one plain term per call and follows this line for quoting, so the rule lives in the portal skill rather than in a list upstream maintains. Determine it in Step 4 by running a two-word test query bare, inside double quotes, inside single quotes, reversed inside double quotes, and with `OR` between two terms, each with `--format json` and no `--limit`, then comparing the total the portal itself reports (not the rows returned, which `--limit` and the portal's page size cap): a quoted total below the bare one means the quotes narrow the match, and a reversed total below the quoted one means word order counts. If the portal reports no total, write the behaviour as not verified - never assume it from another portal. - **`SKILL.md` body:** what the skill searches, the personal-use warning if Step 2 found terms restrictions, command reference with flags, 4-6 usage examples using the user's market (real cities, realistic roles), output-format table, and a Notes section recording portal quirks found in Step 2. If Step 2.5 found the portal needs a credential, add a **Setup** section naming the service, the exact environment variable to export, and the fact that every call is billed - stated where the user reads it before running the skill, not after. Under the search command, write one line `Query syntax: ...` stating whether the portal honours phrase quoting and which operators, if any, it supports (e.g. `Query syntax: double quotes inside the argument make an exact phrase, word order included; no OR.`). `/scrape` sends one plain term per call and follows this line for quoting, so the rule lives in the portal skill rather than in a list upstream maintains. Determine it in Step 4 by running a two-word test query bare, inside double quotes, inside single quotes, reversed inside double quotes, and with `OR` between two terms, each with `--format json` and no `--limit`, then comparing the total the portal itself reports (not the rows returned, which `--limit` and the portal's page size cap): a quoted total below the bare one means the quotes narrow the match, and a reversed total below the quoted one means word order counts. If the portal reports no total, write the behaviour as not verified - never assume it from another portal.
- **`url-reference.md`:** the endpoints, parameters table, and response-structure notes from Step 2 - this is the file a future maintainer needs when the portal changes its markup. - **`url-reference.md`:** the endpoints, parameters table, and response-structure notes from Step 2 - this is the file a future maintainer needs when the portal changes its markup.
- **`package.json`:** name `<portal>-cli`, `"type": "module"`, scripts `start`, `test` (`bun test --timeout 30000`), and `typecheck` (`tsc --noEmit`); dev-only dependencies in the zero-dependency default. - **`package.json`:** name `<portal>-cli`, `"type": "module"`, scripts `start`, `test` (`bun test --timeout 30000`), and `typecheck` (`tsc --noEmit`); dev-only dependencies in the zero-dependency default.
- **`tests/`:** copy `runCLI`/`parseJSON` from `jobindex-search/cli/tests/helpers.ts`, then add a small live smoke-test file: `search` with the test query returns exit code 0 and ≥1 result with non-null `id`/`title`/`url`; a bogus flag or missing required arg exits 1 with a JSON error on stderr. - **`tests/`:** copy `runCLI`/`parseJSON` from `jobindex-search/cli/tests/helpers.ts`, then add network-free fixture/mock tests. Use the response captured in Step 2 to exercise the real parser or CLI: `search` returns exit code 0 and the fixture's expected `id`/`title`/`url`; a bogus flag or missing required arg exits 1 with a JSON error on stderr. For a CLI-level request test, follow the shipped portal tests' local HTTP server/fetch-preload pattern and reject unexpected external requests. Do not put live portal calls in checked-in `*.test.ts` files: CI discovers every generated CLI and runs its test script on every push. The bounded live search/detail verification belongs to Step 4, run manually, rather than to `bun test`.
--- ---
@@ -115,7 +115,7 @@ Never register a portal skill that has not returned real results. Markup assumpt
bun run src/cli.ts detail <id> --format plain bun run src/cli.ts detail <id> --format plain
``` ```
Verify the description is readable text (entities decoded, tags stripped, paragraph breaks preserved). Verify the description is readable text (entities decoded, tags stripped, paragraph breaks preserved).
5. Run the test suite: `bun run test`. 5. Run the network-free test suite: `bun run test`. The live calls in Steps 4.2 and 4.4 are separate manual checks; they must not become tests that CI replays against the portal.
6. Keep volume low during iteration - a handful of requests, not a crawl. If the portal rate-limits you mid-test, back off and tell the user. 6. Keep volume low during iteration - a handful of requests, not a crawl. If the portal rate-limits you mid-test, back off and tell the user.
Do not proceed to Step 5 until search, detail, and tests all pass. Do not proceed to Step 5 until search, detail, and tests all pass.
@@ -134,7 +134,7 @@ Do not proceed to Step 5 until search, detail, and tests all pass.
``` ```
(Skip if the skill is zero-dependency and they don't care about typecheck types.) (Skip if the skill is zero-dependency and they don't care about typecheck types.)
3. Note that the skill auto-triggers from its `SKILL.md` description - no other wiring is needed. 3. Note that the skill auto-triggers from its `SKILL.md` description - no other wiring is needed.
4. CI coverage is also automatic: the `cli-checks` job discovers every `.agents/skills/*/cli/package.json`, so the new CLI's `typecheck` and `test` scripts run on every push to the fork without editing the workflow. 4. CI coverage is also automatic: the `cli-checks` job discovers every `.agents/skills/*/cli/package.json`, so the new CLI's `typecheck` and network-free `test` scripts run on every push to the fork without editing the workflow. CI must not contact the live portal, including when personal use was approved in Step 2.4.
--- ---