apify-test-tools 0.10.1-beta.4 → 0.10.1-beta.5

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.
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "apify-test-tools",
3
+ "owner": {
4
+ "name": "Apify"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "platform-tests-investigate-and-fix",
9
+ "source": "./platform-tests-investigate-and-fix"
10
+ }
11
+ ]
12
+ }
@@ -39,16 +39,17 @@ on:
39
39
  type: string
40
40
  default: sonnet
41
41
  description: Claude model to use for investigation and fix
42
+ max_flakiness_runs:
43
+ required: false
44
+ type: number
45
+ default: 200
46
+ description: The most times Claude may re-run the failing Actor run to measure how often the failure happens, when that isn't obvious. Claude decides how many of them it needs.
42
47
  investigate_prompt:
43
48
  required: false
44
49
  type: string
45
50
  default: |
46
51
  Investigate the failing E2E platform test and open a GitHub issue documenting your findings. Start by reviewing the test logs, error messages, and recent workflow run history to determine the root cause.
47
52
 
48
- The failure will typically fall into one of these categories:
49
- - Flaky test: The test is non-deterministic or depends on timing/external state and fails intermittently. Check past workflow runs to see if this test has failed before.
50
- - Real bug: Genuine broken functionality — either a pre-existing issue or an environment/dependency change outside the codebase (e.g. a website changed its structure, an external API changed behavior).
51
-
52
53
  Use available tools to check previous workflow runs, git history, and existing GitHub issues to gather context and avoid creating duplicate issues. For deeper context,
53
54
  use tools to investigate the run on Apify platform, review its logs, datasets, key-value stores.
54
55
 
@@ -56,9 +57,12 @@ on:
56
57
  - Debug snapshots: often stored as a field on dataset items (e.g. `_debugSnapshots`) or as records in a key-value store, keyed so they can be matched to the log line for the failing request.
57
58
  - Any other debug artifacts the Actor produced (extra logs, error/state fields on output items) that narrow down the failing request.
58
59
 
60
+ Before you create a new issue, check whether the `platform-tests-investigate-and-fix:measure-flakiness` skill applies, and follow it if it does.
61
+
59
62
  When you create the issue, write it like an incident postmortem: a short summary and impact up top for anyone skimming, full technical detail below for whoever fixes it. Don't water down the engineering detail to make the top readable.
60
63
  - Title: short and clean, describing the actual problem in plain terms — no dates, run numbers, or other noise. Prefix it with a conventional-commit-style type, e.g. "fix: blocking issue on detail endpoint".
61
64
  - Body, section 1 ("## Summary"): one line stating what's broken plus its impact, in plain language a PM can understand at a glance — no jargon, internal field names, or stack traces (e.g. "Scraping product detail pages fails when a listing has no reviews, affecting N% of runs").
65
+ - If you measured flakiness, a "## Flakiness" section right after the Summary, as the `measure-flakiness` skill describes.
62
66
  - A `---` divider, then section 2 ("## Details"): the engineering bug report — root cause, relevant log lines, links to the failing run, and any other internals an engineer needs. If a single item/request failed among otherwise-good ones, show or link that specific one (e.g. the dataset item index/id, or its matching debug snapshot) rather than just describing the run as failed.
63
67
 
64
68
  If you create a new issue, you MUST write its issue number (just the number, nothing else) to $GITHUB_WORKSPACE/issue-number.txt as the very last thing you do. If you skip creating one because a duplicate already exists, do not create the file.
@@ -67,9 +71,9 @@ on:
67
71
  ANTHROPIC_API_KEY:
68
72
  required: true
69
73
  description: Claude API key
70
- TESTER_APIFY_TOKEN_READ_ONLY:
74
+ TESTER_APIFY_TOKEN:
71
75
  required: true
72
- description: Apify token used only for read-only investigation — reading the failing run, its log and its storages.
76
+ description: Apify token for investigating the failing run — reading it, its log and its storages — and re-running it to measure how often the failure happens.
73
77
  NPM_TOKEN:
74
78
  required: false
75
79
  description: Read-only token for installing private npm packages before Claude runs.
@@ -92,7 +96,8 @@ jobs:
92
96
  id: claude
93
97
  uses: anthropics/claude-code-action@8251c103ac8c1d761882c86aba1412c7f583c844 # v1.0.213
94
98
  env:
95
- TESTER_APIFY_TOKEN_READ_ONLY: ${{ secrets.TESTER_APIFY_TOKEN_READ_ONLY }}
99
+ TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
100
+ MAX_FLAKINESS_RUNS: ${{ inputs.max_flakiness_runs }}
96
101
  with:
97
102
  prompt: |
98
103
  The failing E2E platform test ran in workflow run ${{ github.run_id }} of this repo.
@@ -100,13 +105,15 @@ jobs:
100
105
  ${{ inputs.investigate_prompt }}
101
106
  github_token: ${{ secrets.GITHUB_TOKEN }}
102
107
  anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
108
+ plugin_marketplaces: https://github.com/apify/apify-test-tools.git
109
+ plugins: platform-tests-investigate-and-fix@apify-test-tools
103
110
  # The `tools` query parameter below selects which tools the Apify MCP server
104
111
  # exposes: reading an Actor run — its status, exit code, storage ids and log — and
105
112
  # reading that run's dataset items and its key-value store keys and records, e.g.
106
113
  # INPUT, OUTPUT and error snapshots. WARN: the server adds `abort-actor-run` on top
107
114
  # even when not listed here, see https://github.com/apify/apify-mcp-server
108
115
  claude_args: |
109
- --mcp-config '{"mcpServers":{"apify":{"type":"http","url":"https://mcp.apify.com/?tools=get-actor-run,get-actor-log,get-dataset-list,get-dataset,get-dataset-items,get-key-value-store-list,get-key-value-store,get-key-value-store-keys,get-key-value-store-record","headers":{"Authorization":"Bearer ${TESTER_APIFY_TOKEN_READ_ONLY}"}}}}'
116
+ --mcp-config '{"mcpServers":{"apify":{"type":"http","url":"https://mcp.apify.com/?tools=get-actor-run,get-actor-run-log,get-dataset-list,get-dataset,get-dataset-items,get-key-value-store-list,get-key-value-store,get-key-value-store-keys,get-key-value-store-record","headers":{"Authorization":"Bearer ${TESTER_APIFY_TOKEN}"}}}}'
110
117
  --model ${{ inputs.model }}
111
118
  --dangerously-skip-permissions
112
119
 
package/CHANGELOG.md CHANGED
@@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file.
9
9
 
10
10
  - **relative-path:** Path safety and manipulation lib ([#154](https://github.com/apify/apify-test-tools/pull/154)) ([c151a1c](https://github.com/apify/apify-test-tools/commit/c151a1c2755fef98b335d48a3461f5042b90def9)) by [@JuanGalilea](https://github.com/JuanGalilea)
11
11
  - **logger:** Add logger and ban console statements ([#170](https://github.com/apify/apify-test-tools/pull/170)) ([b295d36](https://github.com/apify/apify-test-tools/commit/b295d363276c92fc6c30dd34d7a90acef5d380bf)) by [@JuanGalilea](https://github.com/JuanGalilea), closes [#156](https://github.com/apify/apify-test-tools/issues/156)
12
+ - Give claude investigator a skill to test flakiness ([#184](https://github.com/apify/apify-test-tools/pull/184)) ([b490298](https://github.com/apify/apify-test-tools/commit/b4902987dc2ae55882463ff8223e1e9f25b8b497)) by [@foxt451](https://github.com/foxt451), closes [#162](https://github.com/apify/apify-test-tools/issues/162)
12
13
 
13
14
  ### 🐛 Bug Fixes
14
15
 
package/README.md CHANGED
@@ -258,13 +258,12 @@ it at a branch only to test a prompt change.
258
258
  Callers pass `secrets: inherit`. The workflows do not turn every inherited secret into job-wide
259
259
  environment variables, so a secret is only visible to the step that needs it:
260
260
 
261
- | Secret | Reaches |
262
- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
263
- | `NPM_TOKEN` | dependency install steps only, as both `NPM_TOKEN` and `NODE_AUTH_TOKEN`. Use a read-only token: npm granular tokens can be read-only, classic automation tokens can publish. |
264
- | the Actor tokens named by `tokenEnvVar` in `apify-test-tools.config.json` | the `build`, `release`, and `delete-old-builds` steps only |
265
- | `TESTER_APIFY_TOKEN` | the vitest step only |
266
- | `SLACK_TOKEN_TESTS_BOT` / `SLACK_TOKEN_RELEASES_BOT` | the reporting and release steps only |
267
- | `TESTER_APIFY_TOKEN_READ_ONLY` | the Claude investigation step only, as the Apify MCP server's bearer token. Required by `public_platform-tests-claude-investigate-and-fix`. Use a read-only token: it reads the failing run, its log and its storages. |
261
+ | Secret | Reaches |
262
+ | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
263
+ | `NPM_TOKEN` | dependency install steps only, as both `NPM_TOKEN` and `NODE_AUTH_TOKEN`. Use a read-only token: npm granular tokens can be read-only, classic automation tokens can publish. |
264
+ | the Actor tokens named by `tokenEnvVar` in `apify-test-tools.config.json` | the `build`, `release`, and `delete-old-builds` steps only |
265
+ | `TESTER_APIFY_TOKEN` | the vitest step, and the Claude investigation step: the Apify MCP server's bearer token for reading the failing run, its log and its storages, and Claude's token for re-running it to measure how often the failure happens |
266
+ | `SLACK_TOKEN_TESTS_BOT` / `SLACK_TOKEN_RELEASES_BOT` | the reporting and release steps only |
268
267
 
269
268
  The Actor tokens are the one set that cannot be listed in the workflow, because each Actor names its
270
269
  own token via `tokenEnvVar` in `apify-test-tools.config.json`. Those steps pass
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apify-test-tools",
3
- "version": "0.10.1-beta.4",
3
+ "version": "0.10.1-beta.5",
4
4
  "type": "module",
5
5
  "description": "TBD",
6
6
  "repository": {
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "platform-tests-investigate-and-fix",
3
+ "description": "Skills for the platform-tests Claude investigate-and-fix workflow"
4
+ }
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: measure-flakiness
3
+ description: Re-runs the failing Actor run many times in parallel to measure how often the failure happens. Use only when you are about to create a new issue for a failing platform test and its failure rate is not already obvious.
4
+ ---
5
+
6
+ # Measure flakiness
7
+
8
+ Use this only when both are true:
9
+
10
+ - You are about to create a new issue — no existing issue already covers this failure.
11
+ - How often the failure happens isn't obvious. Blocking, too few scraped items or a missing field can happen in 1% of runs or in all of them, and one failed run doesn't tell which.
12
+
13
+ ## Steps
14
+
15
+ The Apify API token is in the `TESTER_APIFY_TOKEN` environment variable. It is always set, so there's no need to check for it.
16
+
17
+ 1. From the failing run (the run the failed test started; its link is in the test log), get the Actor ID, build number, memory, timeout and input. For example, you can get the first four from `GET https://api.apify.com/v2/actor-runs/{runId}`.
18
+ 2. Decide how to tell whether a finished run hit the same failure. Check what the failed test assertion checked — e.g. the run's status, its dataset item count against the expected minimum, a field missing from items, a log line.
19
+ 3. Start runs of the same Actor at once, with the same build, memory, timeout and input. For example, you can start each with `POST https://api.apify.com/v2/acts/{actorId}/runs`. If a run can't start because the account's memory limit is reached, start it once earlier runs finish.
20
+
21
+ Decide on your own how many runs you need, up to !`echo "$MAX_FLAKINESS_RUNS"` in total. The point isn't a statistically significant rate, but a rough idea of whether the failure is frequent, infrequent or a once-in-a-lifetime event. For example:
22
+ - Blocking that looks persistent: if around 20 runs all get blocked the same way, that's enough.
23
+ - A rare flake that's hard to reproduce, e.g. one item out of hundreds missing a field: start a lot of runs — it may take a hundred runs, and after that another hundred, to see it even a few times.
24
+
25
+ 4. Wait until every run has finished, then apply the check from step 2 to each. If there were no or almost no reproductions and you can't tell yet how often the failure happens, start more runs and check them the same way, but up to !`echo "$MAX_FLAKINESS_RUNS"` in total.
26
+ 5. Add a short `## Flakiness` section to the issue, right after the Summary:
27
+ - The rate, e.g. "Fails in 28 of 47 runs (60%)". Leave out runs that failed for another reason, e.g. never started — only mention how many there were.
28
+ - Links to up to 2 runs that hit the failure.