apify-test-tools 0.10.2-beta.2 → 0.10.2-beta.21

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.
Files changed (275) hide show
  1. package/.gitattributes +1 -0
  2. package/.github/actionlint.yaml +11 -0
  3. package/.github/actions/checkout-restore-dependencies/action.yaml +58 -6
  4. package/.github/cli/apify-test-tools.mjs +135 -142
  5. package/.github/scripts/mask-config-secrets.sh +17 -0
  6. package/.github/scripts/run-with-apify-tokens.mjs +63 -103
  7. package/.github/workflows/_check_code.yaml +5 -21
  8. package/.github/workflows/_move_major_tag.yaml +2 -2
  9. package/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml +89 -8
  10. package/.github/workflows/public_platform-tests.yaml +68 -30
  11. package/.github/workflows/public_pr-build-test.yaml +77 -38
  12. package/.github/workflows/public_push-build-latest.yaml +49 -11
  13. package/.github/workflows/public_review.yaml +5 -4
  14. package/.github/workflows/public_stale-issues.yaml +51 -0
  15. package/.husky/pre-commit +4 -4
  16. package/.prettierignore +2 -1
  17. package/CHANGELOG.md +23 -0
  18. package/CONTRIBUTING.md +117 -17
  19. package/README.md +221 -595
  20. package/bin/actor-ids.ts +41 -0
  21. package/bin/affected-actors.ts +211 -0
  22. package/bin/build-from-local.ts +19 -1
  23. package/bin/build.ts +105 -39
  24. package/bin/diff-changes.ts +69 -36
  25. package/bin/diff-json-schema.ts +5 -6
  26. package/bin/git.ts +73 -175
  27. package/bin/main.ts +142 -189
  28. package/bin/notify.ts +198 -0
  29. package/bin/run-tests.ts +182 -0
  30. package/bin/slack.ts +16 -76
  31. package/bin/stdin-input.ts +156 -0
  32. package/bin/test-files-glob.ts +126 -0
  33. package/bin/test-report.ts +141 -140
  34. package/bin/types.ts +4 -7
  35. package/bin/utils/config/load-config.ts +20 -2
  36. package/bin/utils/config/parser.ts +40 -8
  37. package/bin/utils/config/structures/grouped.ts +2 -2
  38. package/bin/utils/config/structures/legacy.ts +1 -1
  39. package/dist/bin/actor-ids.d.ts +15 -0
  40. package/dist/bin/actor-ids.d.ts.map +1 -0
  41. package/dist/bin/actor-ids.js +30 -0
  42. package/dist/bin/actor-ids.js.map +1 -0
  43. package/dist/bin/affected-actors.d.ts +55 -0
  44. package/dist/bin/affected-actors.d.ts.map +1 -0
  45. package/dist/bin/affected-actors.js +142 -0
  46. package/dist/bin/affected-actors.js.map +1 -0
  47. package/dist/bin/build-from-local.d.ts +2 -1
  48. package/dist/bin/build-from-local.d.ts.map +1 -1
  49. package/dist/bin/build-from-local.js +6 -2
  50. package/dist/bin/build-from-local.js.map +1 -1
  51. package/dist/bin/build.d.ts +18 -5
  52. package/dist/bin/build.d.ts.map +1 -1
  53. package/dist/bin/build.js +74 -24
  54. package/dist/bin/build.js.map +1 -1
  55. package/dist/bin/diff-changes.d.ts +21 -5
  56. package/dist/bin/diff-changes.d.ts.map +1 -1
  57. package/dist/bin/diff-changes.js +41 -28
  58. package/dist/bin/diff-changes.js.map +1 -1
  59. package/dist/bin/diff-json-schema.d.ts +2 -2
  60. package/dist/bin/diff-json-schema.d.ts.map +1 -1
  61. package/dist/bin/diff-json-schema.js +1 -4
  62. package/dist/bin/diff-json-schema.js.map +1 -1
  63. package/dist/bin/git.d.ts +26 -34
  64. package/dist/bin/git.d.ts.map +1 -1
  65. package/dist/bin/git.js +60 -143
  66. package/dist/bin/git.js.map +1 -1
  67. package/dist/bin/main.js +126 -140
  68. package/dist/bin/main.js.map +1 -1
  69. package/dist/bin/notify.d.ts +35 -0
  70. package/dist/bin/notify.d.ts.map +1 -0
  71. package/dist/bin/notify.js +131 -0
  72. package/dist/bin/notify.js.map +1 -0
  73. package/dist/bin/run-tests.d.ts +21 -0
  74. package/dist/bin/run-tests.d.ts.map +1 -0
  75. package/dist/bin/run-tests.js +149 -0
  76. package/dist/bin/run-tests.js.map +1 -0
  77. package/dist/bin/slack.d.ts +2 -14
  78. package/dist/bin/slack.d.ts.map +1 -1
  79. package/dist/bin/slack.js +17 -46
  80. package/dist/bin/slack.js.map +1 -1
  81. package/dist/bin/stdin-input.d.ts +79 -0
  82. package/dist/bin/stdin-input.d.ts.map +1 -0
  83. package/dist/bin/stdin-input.js +124 -0
  84. package/dist/bin/stdin-input.js.map +1 -0
  85. package/dist/bin/test-files-glob.d.ts +18 -0
  86. package/dist/bin/test-files-glob.d.ts.map +1 -0
  87. package/dist/bin/test-files-glob.js +108 -0
  88. package/dist/bin/test-files-glob.js.map +1 -0
  89. package/dist/bin/test-report.d.ts +69 -8
  90. package/dist/bin/test-report.d.ts.map +1 -1
  91. package/dist/bin/test-report.js +76 -67
  92. package/dist/bin/test-report.js.map +1 -1
  93. package/dist/bin/types.d.ts +4 -7
  94. package/dist/bin/types.d.ts.map +1 -1
  95. package/dist/bin/utils/config/load-config.d.ts +8 -0
  96. package/dist/bin/utils/config/load-config.d.ts.map +1 -1
  97. package/dist/bin/utils/config/load-config.js +14 -1
  98. package/dist/bin/utils/config/load-config.js.map +1 -1
  99. package/dist/bin/utils/config/parser.d.ts +15 -2
  100. package/dist/bin/utils/config/parser.d.ts.map +1 -1
  101. package/dist/bin/utils/config/parser.js +29 -8
  102. package/dist/bin/utils/config/parser.js.map +1 -1
  103. package/dist/bin/utils/config/structures/grouped.js +2 -2
  104. package/dist/bin/utils/config/structures/grouped.js.map +1 -1
  105. package/dist/bin/utils/config/structures/legacy.js +1 -1
  106. package/dist/bin/utils/config/structures/legacy.js.map +1 -1
  107. package/dist/lib/extend-expect.d.ts.map +1 -1
  108. package/dist/lib/extend-expect.js +37 -218
  109. package/dist/lib/extend-expect.js.map +1 -1
  110. package/dist/lib/lib.d.ts +1 -5
  111. package/dist/lib/lib.d.ts.map +1 -1
  112. package/dist/lib/lib.js +19 -31
  113. package/dist/lib/lib.js.map +1 -1
  114. package/dist/lib/run-checks.d.ts +14 -0
  115. package/dist/lib/run-checks.d.ts.map +1 -0
  116. package/dist/lib/run-checks.js +82 -0
  117. package/dist/lib/run-checks.js.map +1 -0
  118. package/dist/lib/run-test-result.d.ts +3 -6
  119. package/dist/lib/run-test-result.d.ts.map +1 -1
  120. package/dist/lib/run-test-result.js +41 -54
  121. package/dist/lib/run-test-result.js.map +1 -1
  122. package/dist/test/bundle/cli-bundle.test.js +76 -56
  123. package/dist/test/bundle/cli-bundle.test.js.map +1 -1
  124. package/dist/test/bundle/token-wrapper.test.d.ts +2 -0
  125. package/dist/test/bundle/token-wrapper.test.d.ts.map +1 -0
  126. package/dist/test/bundle/token-wrapper.test.js +80 -0
  127. package/dist/test/bundle/token-wrapper.test.js.map +1 -0
  128. package/dist/test/e2e/cli-bundle.e2e.test.js +33 -68
  129. package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -1
  130. package/dist/test/e2e/git-build-release.e2e.test.d.ts +2 -0
  131. package/dist/test/e2e/git-build-release.e2e.test.d.ts.map +1 -0
  132. package/dist/test/e2e/git-build-release.e2e.test.js +87 -0
  133. package/dist/test/e2e/git-build-release.e2e.test.js.map +1 -0
  134. package/dist/test/e2e/helpers.d.ts +37 -0
  135. package/dist/test/e2e/helpers.d.ts.map +1 -0
  136. package/dist/test/e2e/helpers.js +57 -0
  137. package/dist/test/e2e/helpers.js.map +1 -0
  138. package/dist/test/unit/bin/actor-filtering.test.js +7 -0
  139. package/dist/test/unit/bin/actor-filtering.test.js.map +1 -1
  140. package/dist/test/unit/bin/actor-ids.test.d.ts +2 -0
  141. package/dist/test/unit/bin/actor-ids.test.d.ts.map +1 -0
  142. package/dist/test/unit/bin/actor-ids.test.js +40 -0
  143. package/dist/test/unit/bin/actor-ids.test.js.map +1 -0
  144. package/dist/test/unit/bin/affected-actors-cli.test.d.ts +2 -0
  145. package/dist/test/unit/bin/affected-actors-cli.test.d.ts.map +1 -0
  146. package/dist/test/unit/bin/affected-actors-cli.test.js +224 -0
  147. package/dist/test/unit/bin/affected-actors-cli.test.js.map +1 -0
  148. package/dist/test/unit/bin/affected-actors.test.d.ts +2 -0
  149. package/dist/test/unit/bin/affected-actors.test.d.ts.map +1 -0
  150. package/dist/test/unit/bin/affected-actors.test.js +153 -0
  151. package/dist/test/unit/bin/affected-actors.test.js.map +1 -0
  152. package/dist/test/unit/bin/build-cli.test.d.ts +2 -0
  153. package/dist/test/unit/bin/build-cli.test.d.ts.map +1 -0
  154. package/dist/test/unit/bin/build-cli.test.js +49 -0
  155. package/dist/test/unit/bin/build-cli.test.js.map +1 -0
  156. package/dist/test/unit/bin/build-from-local.test.js +12 -0
  157. package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
  158. package/dist/test/unit/bin/build.test.js +116 -6
  159. package/dist/test/unit/bin/build.test.js.map +1 -1
  160. package/dist/test/unit/bin/compiled-cli.d.ts +6 -0
  161. package/dist/test/unit/bin/compiled-cli.d.ts.map +1 -0
  162. package/dist/test/unit/bin/compiled-cli.js +23 -0
  163. package/dist/test/unit/bin/compiled-cli.js.map +1 -0
  164. package/dist/test/unit/bin/diff-changes.test.js +168 -114
  165. package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
  166. package/dist/test/unit/bin/diff.test.js +25 -28
  167. package/dist/test/unit/bin/diff.test.js.map +1 -1
  168. package/dist/test/unit/bin/git.test.js +67 -288
  169. package/dist/test/unit/bin/git.test.js.map +1 -1
  170. package/dist/test/unit/bin/notify.test.d.ts +2 -0
  171. package/dist/test/unit/bin/notify.test.d.ts.map +1 -0
  172. package/dist/test/unit/bin/notify.test.js +222 -0
  173. package/dist/test/unit/bin/notify.test.js.map +1 -0
  174. package/dist/test/unit/bin/stdin-input.test.d.ts +2 -0
  175. package/dist/test/unit/bin/stdin-input.test.d.ts.map +1 -0
  176. package/dist/test/unit/bin/stdin-input.test.js +92 -0
  177. package/dist/test/unit/bin/stdin-input.test.js.map +1 -0
  178. package/dist/test/unit/bin/test-cli.test.d.ts +2 -0
  179. package/dist/test/unit/bin/test-cli.test.d.ts.map +1 -0
  180. package/dist/test/unit/bin/test-cli.test.js +165 -0
  181. package/dist/test/unit/bin/test-cli.test.js.map +1 -0
  182. package/dist/test/unit/bin/test-files-glob.test.d.ts +2 -0
  183. package/dist/test/unit/bin/test-files-glob.test.d.ts.map +1 -0
  184. package/dist/test/unit/bin/test-files-glob.test.js +102 -0
  185. package/dist/test/unit/bin/test-files-glob.test.js.map +1 -0
  186. package/dist/test/unit/bin/test-report.test.d.ts +2 -0
  187. package/dist/test/unit/bin/test-report.test.d.ts.map +1 -0
  188. package/dist/test/unit/bin/test-report.test.js +100 -0
  189. package/dist/test/unit/bin/test-report.test.js.map +1 -0
  190. package/dist/test/unit/bin/utils/config/load-config.test.js +19 -1
  191. package/dist/test/unit/bin/utils/config/load-config.test.js.map +1 -1
  192. package/dist/test/unit/bin/utils/config/parser.test.js +36 -4
  193. package/dist/test/unit/bin/utils/config/parser.test.js.map +1 -1
  194. package/dist/test/unit/bin/utils/config/structures/grouped.test.js +6 -0
  195. package/dist/test/unit/bin/utils/config/structures/grouped.test.js.map +1 -1
  196. package/dist/test/unit/bin/utils/config/structures/legacy.test.js +1 -0
  197. package/dist/test/unit/bin/utils/config/structures/legacy.test.js.map +1 -1
  198. package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts +2 -0
  199. package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts.map +1 -0
  200. package/dist/test/unit/github-scripts/mask-config-secrets.test.js +50 -0
  201. package/dist/test/unit/github-scripts/mask-config-secrets.test.js.map +1 -0
  202. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts +2 -0
  203. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts.map +1 -0
  204. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js +102 -0
  205. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js.map +1 -0
  206. package/dist/test/unit/run-checks.test.d.ts +2 -0
  207. package/dist/test/unit/run-checks.test.d.ts.map +1 -0
  208. package/dist/test/unit/run-checks.test.js +62 -0
  209. package/dist/test/unit/run-checks.test.js.map +1 -0
  210. package/dist/test/unit/run-test-result.test.d.ts +2 -0
  211. package/dist/test/unit/run-test-result.test.d.ts.map +1 -0
  212. package/dist/test/unit/run-test-result.test.js +34 -0
  213. package/dist/test/unit/run-test-result.test.js.map +1 -0
  214. package/dist/test/unit/should-built-and-test.test.js +41 -38
  215. package/dist/test/unit/should-built-and-test.test.js.map +1 -1
  216. package/dist/tsconfig.tsbuildinfo +1 -1
  217. package/dist/workflow-scripts-src/run-with-apify-tokens.d.ts +3 -0
  218. package/dist/workflow-scripts-src/run-with-apify-tokens.d.ts.map +1 -0
  219. package/dist/workflow-scripts-src/run-with-apify-tokens.js +100 -0
  220. package/dist/workflow-scripts-src/run-with-apify-tokens.js.map +1 -0
  221. package/docs/cli.md +473 -0
  222. package/docs/lib.md +276 -0
  223. package/docs/workflows.md +455 -0
  224. package/eslint.config.mjs +10 -1
  225. package/lib/extend-expect.ts +48 -258
  226. package/lib/lib.ts +25 -34
  227. package/lib/run-checks.ts +101 -0
  228. package/lib/run-test-result.ts +45 -55
  229. package/package.json +4 -2
  230. package/platform-tests-investigate-and-fix/skills/assess-impact/SKILL.md +42 -0
  231. package/platform-tests-investigate-and-fix/skills/measure-flakiness/SKILL.md +4 -2
  232. package/test/bundle/cli-bundle.test.ts +97 -67
  233. package/test/bundle/token-wrapper.test.ts +110 -0
  234. package/test/e2e/cli-bundle.e2e.test.ts +60 -93
  235. package/test/e2e/git-build-release.e2e.test.ts +113 -0
  236. package/test/e2e/helpers.ts +82 -0
  237. package/test/unit/bin/actor-filtering.test.ts +8 -0
  238. package/test/unit/bin/actor-ids.test.ts +47 -0
  239. package/test/unit/bin/affected-actors-cli.test.ts +271 -0
  240. package/test/unit/bin/affected-actors.test.ts +221 -0
  241. package/test/unit/bin/build-cli.test.ts +61 -0
  242. package/test/unit/bin/build-from-local.test.ts +16 -0
  243. package/test/unit/bin/build.test.ts +149 -5
  244. package/test/unit/bin/compiled-cli.ts +23 -0
  245. package/test/unit/bin/diff-changes.test.ts +181 -114
  246. package/test/unit/bin/diff.test.ts +25 -28
  247. package/test/unit/bin/git.test.ts +76 -361
  248. package/test/unit/bin/notify.test.ts +299 -0
  249. package/test/unit/bin/stdin-input.test.ts +120 -0
  250. package/test/unit/bin/test-cli.test.ts +207 -0
  251. package/test/unit/bin/test-files-glob.test.ts +118 -0
  252. package/test/unit/bin/test-report.test.ts +118 -0
  253. package/test/unit/bin/utils/config/load-config.test.ts +26 -1
  254. package/test/unit/bin/utils/config/parser.test.ts +46 -5
  255. package/test/unit/bin/utils/config/structures/grouped.test.ts +12 -0
  256. package/test/unit/bin/utils/config/structures/legacy.test.ts +1 -0
  257. package/test/unit/github-scripts/mask-config-secrets.test.ts +61 -0
  258. package/test/unit/github-scripts/run-with-apify-tokens.test.ts +115 -0
  259. package/test/unit/run-checks.test.ts +76 -0
  260. package/test/unit/run-test-result.test.ts +44 -0
  261. package/test/unit/should-built-and-test.test.ts +46 -39
  262. package/tsconfig.json +1 -1
  263. package/vitest.config.ts +9 -0
  264. package/workflow-scripts-src/run-with-apify-tokens.ts +112 -0
  265. package/.github/scripts/check-major-tag-refs.mjs +0 -72
  266. package/dist/test/unit/bin/logging.test.d.ts +0 -2
  267. package/dist/test/unit/bin/logging.test.d.ts.map +0 -1
  268. package/dist/test/unit/bin/logging.test.js +0 -43
  269. package/dist/test/unit/bin/logging.test.js.map +0 -1
  270. package/dist/test/unit/bin/slack.test.d.ts +0 -2
  271. package/dist/test/unit/bin/slack.test.d.ts.map +0 -1
  272. package/dist/test/unit/bin/slack.test.js +0 -54
  273. package/dist/test/unit/bin/slack.test.js.map +0 -1
  274. package/test/unit/bin/logging.test.ts +0 -52
  275. package/test/unit/bin/slack.test.ts +0 -65
@@ -59,7 +59,21 @@ const amazonActor = actorConfig('junglee/amazon-crawler', 'actors/junglee_Amazon
59
59
  'shared',
60
60
  ]);
61
61
 
62
- const commits = [{ sha: 'Commit1', author: '', date: '', message: '' }];
62
+ const range = { fromRef: 'Commit0', toRef: 'Commit1' };
63
+
64
+ // What a PR (functional changes only) or a release (isLatest, all changes) builds, in config order
65
+ const changedActorsFor = async ({
66
+ isLatest = false,
67
+ ...options
68
+ }: Parameters<typeof getChangedActors>[0] & { isLatest?: boolean }): Promise<ActorConfig[]> => {
69
+ const { functional, cosmetic } = await getChangedActors(options);
70
+ const changed = isLatest ? [...functional, ...cosmetic] : functional;
71
+ return options.actorConfigs.filter((config) => changed.includes(config));
72
+ };
73
+
74
+ // The Actors whose platform tests run because of a test change
75
+ const testChangedActorsFor = async (options: Parameters<typeof getChangedActors>[0]): Promise<ActorConfig[]> =>
76
+ (await getChangedActors(options)).test;
63
77
 
64
78
  describe('getChangedActors', () => {
65
79
  beforeEach(() => {
@@ -68,51 +82,51 @@ describe('getChangedActors', () => {
68
82
  });
69
83
 
70
84
  it('returns empty array when no files changed', async () => {
71
- expect(await getChangedActors({ filepathsChanged: [], actorConfigs, commits })).toEqual([]);
85
+ expect(await changedActorsFor({ filepathsChanged: [], actorConfigs, range })).toEqual([]);
72
86
  });
73
87
 
74
88
  it('returns empty array when only ignored top-level files changed', async () => {
75
- const result = await getChangedActors({
89
+ const result = await changedActorsFor({
76
90
  filepathsChanged: ['.gitignore', 'README.md', '.husky/pre-commit', '.vscode/settings.json'],
77
91
  actorConfigs,
78
- commits,
92
+ range,
79
93
  });
80
94
  expect(result).toEqual([]);
81
95
  });
82
96
 
83
97
  it('does not ignore source files whose names contain an ignored file name', async () => {
84
- const result = await getChangedActors({
98
+ const result = await changedActorsFor({
85
99
  filepathsChanged: ['actors/foo_bar/src/.gitignore-helper.ts'],
86
100
  actorConfigs,
87
- commits,
101
+ range,
88
102
  });
89
103
  expect(result).toEqual([miniActor]);
90
104
  });
91
105
 
92
106
  it('returns the actor when a functional file in its folder changes', async () => {
93
- const result = await getChangedActors({
107
+ const result = await changedActorsFor({
94
108
  filepathsChanged: ['actors/foo_bar/src/main.ts'],
95
109
  actorConfigs,
96
- commits,
110
+ range,
97
111
  });
98
112
  expect(result).toEqual([miniActor]);
99
113
  });
100
114
 
101
115
  it('returns actor when isLatest and README in actor folder changed (cosmetic)', async () => {
102
- const result = await getChangedActors({
116
+ const result = await changedActorsFor({
103
117
  filepathsChanged: ['actors/foo_bar/README.md'],
104
118
  actorConfigs,
105
- commits,
119
+ range,
106
120
  isLatest: true,
107
121
  });
108
122
  expect(result).toEqual([miniActor]);
109
123
  });
110
124
 
111
125
  it('does not return actor when not isLatest and only README changed (cosmetic)', async () => {
112
- const result = await getChangedActors({
126
+ const result = await changedActorsFor({
113
127
  filepathsChanged: ['actors/foo_bar/README.md'],
114
128
  actorConfigs,
115
- commits,
129
+ range,
116
130
  isLatest: false,
117
131
  });
118
132
  expect(result).toEqual([]);
@@ -120,10 +134,10 @@ describe('getChangedActors', () => {
120
134
 
121
135
  it('returns actor when isLatest and JSON file has only cosmetic changes', async () => {
122
136
  vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
123
- const result = await getChangedActors({
137
+ const result = await changedActorsFor({
124
138
  filepathsChanged: ['actors/foo_bar/.actor/actor.json'],
125
139
  actorConfigs,
126
- commits,
140
+ range,
127
141
  isLatest: true,
128
142
  });
129
143
  expect(result).toEqual([miniActor]);
@@ -131,30 +145,30 @@ describe('getChangedActors', () => {
131
145
 
132
146
  it('does not return actor when not isLatest and JSON file has only cosmetic changes', async () => {
133
147
  vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
134
- const result = await getChangedActors({
148
+ const result = await changedActorsFor({
135
149
  filepathsChanged: ['actors/foo_bar/.actor/actor.json'],
136
150
  actorConfigs,
137
- commits,
151
+ range,
138
152
  isLatest: false,
139
153
  });
140
154
  expect(result).toEqual([]);
141
155
  });
142
156
 
143
157
  it('returns actor when JSON file has functional changes', async () => {
144
- const result = await getChangedActors({
158
+ const result = await changedActorsFor({
145
159
  filepathsChanged: ['actors/foo_bar/.actor/actor.json'],
146
160
  actorConfigs,
147
- commits,
161
+ range,
148
162
  });
149
163
  expect(result).toEqual([miniActor]);
150
164
  });
151
165
 
152
166
  it('JSON file in actor folder but outside .actor/ is functional, not checked for cosmetic', async () => {
153
167
  vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
154
- const result = await getChangedActors({
168
+ const result = await changedActorsFor({
155
169
  filepathsChanged: ['actors/foo_bar/package.json'],
156
170
  actorConfigs,
157
- commits,
171
+ range,
158
172
  isLatest: false,
159
173
  });
160
174
  expect(result).toEqual([miniActor]);
@@ -163,34 +177,34 @@ describe('getChangedActors', () => {
163
177
 
164
178
  it('JSON file under .actor/ inside actor folder is checked for cosmetic changes', async () => {
165
179
  vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
166
- const result = await getChangedActors({
180
+ const result = await changedActorsFor({
167
181
  filepathsChanged: ['actors/foo_bar/.actor/input_schema.json'],
168
182
  actorConfigs,
169
- commits,
183
+ range,
170
184
  isLatest: false,
171
185
  });
172
186
  expect(result).toEqual([]);
173
187
  expect(DiffJsonSchema.isCosmeticOnlyJsonSchemaChange).toHaveBeenCalledWith(
174
- commits,
188
+ range,
175
189
  'actors/foo_bar/.actor/input_schema.json',
176
190
  );
177
191
  });
178
192
 
179
193
  it('does not trigger narrow-context actor when shared file changes', async () => {
180
- const result = await getChangedActors({
194
+ const result = await changedActorsFor({
181
195
  filepathsChanged: ['shared/utils.ts'],
182
196
  actorConfigs,
183
- commits,
197
+ range,
184
198
  });
185
199
  expect(result).toContainEqual(miniActor);
186
200
  expect(result).not.toContainEqual(standaloneActor);
187
201
  });
188
202
 
189
203
  it('root-level changelog outside any actor folder is cosmetic for every actor when isLatest', async () => {
190
- const result = await getChangedActors({
204
+ const result = await changedActorsFor({
191
205
  filepathsChanged: ['CHANGELOG.md'],
192
206
  actorConfigs,
193
- commits,
207
+ range,
194
208
  isLatest: true,
195
209
  });
196
210
  expect(result).toEqual(expect.arrayContaining([miniActor, standaloneActor]));
@@ -198,20 +212,20 @@ describe('getChangedActors', () => {
198
212
  });
199
213
 
200
214
  it('root-level changelog is not cosmetic-triggered when not isLatest', async () => {
201
- const result = await getChangedActors({
215
+ const result = await changedActorsFor({
202
216
  filepathsChanged: ['CHANGELOG.md'],
203
217
  actorConfigs,
204
- commits,
218
+ range,
205
219
  isLatest: false,
206
220
  });
207
221
  expect(result).toEqual([]);
208
222
  });
209
223
 
210
224
  it('treats any changelog filename as cosmetic regardless of configured paths', async () => {
211
- const result = await getChangedActors({
225
+ const result = await changedActorsFor({
212
226
  filepathsChanged: ['docs/CHANGELOG.md'],
213
227
  actorConfigs: [miniActor, standaloneActor],
214
- commits,
228
+ range,
215
229
  isLatest: true,
216
230
  });
217
231
  expect(result).toEqual([miniActor, standaloneActor]);
@@ -222,39 +236,39 @@ describe('getChangedActors', () => {
222
236
  ...standaloneActor,
223
237
  actorJson: { ...standaloneActor.actorJson, readme: new RelativeFile('docs/guide.md') },
224
238
  };
225
- const result = await getChangedActors({
239
+ const result = await changedActorsFor({
226
240
  filepathsChanged: ['docs/guide.md'],
227
241
  actorConfigs: [configuredActor],
228
- commits,
242
+ range,
229
243
  isLatest: true,
230
244
  });
231
245
  expect(result).toEqual([]);
232
246
  });
233
247
 
234
248
  it('triggers narrow-context actor when its own folder changes', async () => {
235
- const result = await getChangedActors({
249
+ const result = await changedActorsFor({
236
250
  filepathsChanged: ['standalone-actors/standalone/src/main.ts'],
237
251
  actorConfigs,
238
- commits,
252
+ range,
239
253
  });
240
254
  expect(result).toContainEqual(standaloneActor);
241
255
  });
242
256
 
243
257
  it('deduplicates actors when multiple files in same actor folder change', async () => {
244
- const result = await getChangedActors({
258
+ const result = await changedActorsFor({
245
259
  filepathsChanged: ['actors/foo_bar/src/main.ts', 'actors/foo_bar/package.json'],
246
260
  actorConfigs,
247
- commits,
261
+ range,
248
262
  });
249
263
  expect(result).toHaveLength(1);
250
264
  expect(result).toContainEqual(miniActor);
251
265
  });
252
266
 
253
267
  it('handles mixed changes: returns both broad and narrow-context actors', async () => {
254
- const result = await getChangedActors({
268
+ const result = await changedActorsFor({
255
269
  filepathsChanged: ['actors/foo_bar/src/main.ts', 'standalone-actors/standalone/Dockerfile'],
256
270
  actorConfigs,
257
- commits,
271
+ range,
258
272
  });
259
273
  expect(result).toContainEqual(miniActor);
260
274
  expect(result).toContainEqual(standaloneActor);
@@ -262,29 +276,29 @@ describe('getChangedActors', () => {
262
276
 
263
277
  it('matches folder where folder name differs from actor name', async () => {
264
278
  const ownerlessActor = actorConfig('myteam/shopify-scraper', 'actors/shopify', 'APIFY_TOKEN_MYTEAM', '', ['']);
265
- const result = await getChangedActors({
279
+ const result = await changedActorsFor({
266
280
  filepathsChanged: ['actors/shopify/src/main.ts'],
267
281
  actorConfigs: [ownerlessActor],
268
- commits,
282
+ range,
269
283
  });
270
284
  expect(result).toEqual([ownerlessActor]);
271
285
  });
272
286
 
273
287
  it('in single-actor repo, .actor/ changes trigger builds', async () => {
274
288
  const rootActor = actorConfig('myteam/my-actor', '', 'BUILDER_APIFY_TOKEN', '', ['']);
275
- const result = await getChangedActors({
289
+ const result = await changedActorsFor({
276
290
  filepathsChanged: ['.actor/actor.json'],
277
291
  actorConfigs: [rootActor],
278
- commits,
292
+ range,
279
293
  });
280
294
  expect(result).toEqual([rootActor]);
281
295
  });
282
296
 
283
297
  it('in multi-actor repo, .actor/ changes only trigger broad-context actors', async () => {
284
- const result = await getChangedActors({
298
+ const result = await changedActorsFor({
285
299
  filepathsChanged: ['.actor/actor.json'],
286
300
  actorConfigs,
287
- commits,
301
+ range,
288
302
  });
289
303
  expect(result).toEqual([miniActor]);
290
304
  });
@@ -293,10 +307,10 @@ describe('getChangedActors', () => {
293
307
  const narrowActor = actorConfig('foo/bar', 'actors/foo_bar', 'APIFY_TOKEN_FOO', 'actors/foo_bar', [
294
308
  'actors/foo_bar',
295
309
  ]);
296
- const result = await getChangedActors({
310
+ const result = await changedActorsFor({
297
311
  filepathsChanged: ['Actors/FOO_BAR/Main.ts'],
298
312
  actorConfigs: [narrowActor],
299
- commits,
313
+ range,
300
314
  });
301
315
  expect(result).toEqual([]);
302
316
  });
@@ -309,10 +323,10 @@ describe('getChangedActors', () => {
309
323
  'actors/override',
310
324
  ['actors/override', 'packages'],
311
325
  );
312
- const result = await getChangedActors({
326
+ const result = await changedActorsFor({
313
327
  filepathsChanged: ['packages/shared/utils.ts'],
314
328
  actorConfigs: [overrideActor],
315
- commits,
329
+ range,
316
330
  });
317
331
  expect(result).toEqual([overrideActor]);
318
332
  });
@@ -325,10 +339,10 @@ describe('getChangedActors', () => {
325
339
  'actors/override',
326
340
  ['actors/override', 'packages'],
327
341
  );
328
- const result = await getChangedActors({
342
+ const result = await changedActorsFor({
329
343
  filepathsChanged: ['other-dir/file.ts'],
330
344
  actorConfigs: [overrideActor],
331
- commits,
345
+ range,
332
346
  });
333
347
  expect(result).toEqual([]);
334
348
  });
@@ -336,10 +350,10 @@ describe('getChangedActors', () => {
336
350
  it('broad-context actor skips files in sibling actor folders', async () => {
337
351
  const actorA = actorConfig('team/actor-a', 'actors/a', 'APIFY_TOKEN_TEAM', '', ['']);
338
352
  const actorB = actorConfig('team/actor-b', 'actors/b', 'APIFY_TOKEN_TEAM', '', ['']);
339
- const result = await getChangedActors({
353
+ const result = await changedActorsFor({
340
354
  filepathsChanged: ['actors/b/src/main.ts'],
341
355
  actorConfigs: [actorA, actorB],
342
- commits,
356
+ range,
343
357
  });
344
358
  expect(result).toEqual([actorB]);
345
359
  });
@@ -349,10 +363,10 @@ describe('getChangedActors', () => {
349
363
  const childActor = actorConfig('team/child', 'actors/child', 'APIFY_TOKEN_TEAM', 'actors/child', [
350
364
  'actors/child',
351
365
  ]);
352
- const result = await getChangedActors({
366
+ const result = await changedActorsFor({
353
367
  filepathsChanged: ['actors/child/src/main.ts'],
354
368
  actorConfigs: [rootActor, childActor],
355
- commits,
369
+ range,
356
370
  });
357
371
  expect(result).not.toContainEqual(rootActor);
358
372
  expect(result).toContainEqual(childActor);
@@ -363,10 +377,10 @@ describe('getChangedActors', () => {
363
377
  const childActor = actorConfig('team/child', 'actors/child', 'APIFY_TOKEN_TEAM', 'actors/child', [
364
378
  'actors/child',
365
379
  ]);
366
- const result = await getChangedActors({
380
+ const result = await changedActorsFor({
367
381
  filepathsChanged: ['lib/shared-utils.ts'],
368
382
  actorConfigs: [rootActor, childActor],
369
- commits,
383
+ range,
370
384
  });
371
385
  expect(result).toContainEqual(rootActor);
372
386
  expect(result).not.toContainEqual(childActor);
@@ -376,71 +390,95 @@ describe('getChangedActors', () => {
376
390
  vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(
377
391
  (filePath) => filePath === 'actors/foo_bar/node_modules/foo.js',
378
392
  );
379
- const result = await getChangedActors({
393
+ const result = await changedActorsFor({
380
394
  filepathsChanged: ['actors/foo_bar/node_modules/foo.js'],
381
395
  actorConfigs: [miniActor],
382
- commits,
396
+ range,
383
397
  });
384
398
  expect(result).toEqual([]);
385
399
  });
386
400
 
387
401
  it('file not matched by .dockerignore is classified normally', async () => {
388
402
  vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.includes('node_modules'));
389
- const result = await getChangedActors({
403
+ const result = await changedActorsFor({
390
404
  filepathsChanged: ['actors/foo_bar/src/main.ts'],
391
405
  actorConfigs: [miniActor],
392
- commits,
406
+ range,
393
407
  });
394
408
  expect(result).toEqual([miniActor]);
395
409
  });
396
410
 
397
- it('test file listed in .dockerignore triggers a build when it matches the test files glob', async () => {
411
+ it('test file listed in .dockerignore is a test change when it matches the platform tests glob', async () => {
398
412
  vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.startsWith('test/'));
399
- const result = await getChangedActors({
413
+ const options = {
400
414
  filepathsChanged: ['test/platform/daily/foo.test.ts'],
401
415
  actorConfigs: [miniActor],
402
- commits,
403
- testFilesGlob: 'test/platform/**',
416
+ range,
417
+ platformTestsGlob: 'test/platform/**',
418
+ };
419
+ expect(await testChangedActorsFor(options)).toEqual([miniActor]);
420
+ // A test change needs no build of its own, neither for a PR nor for a release
421
+ expect(await changedActorsFor({ ...options, isLatest: true })).toEqual([]);
422
+ });
423
+
424
+ it('a test change that is not listed in .dockerignore is still only a test change', async () => {
425
+ vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => false);
426
+ const options = {
427
+ filepathsChanged: ['test/platform/utils.ts'],
428
+ actorConfigs: [miniActor],
429
+ range,
430
+ platformTestsGlob: 'test/platform/**',
431
+ };
432
+ expect(await testChangedActorsFor(options)).toEqual([miniActor]);
433
+ expect(await changedActorsFor({ ...options, isLatest: true })).toEqual([]);
434
+ });
435
+
436
+ it('lists an Actor with both source and test changes as functional and as test changed', async () => {
437
+ const result = await getChangedActors({
438
+ filepathsChanged: ['test/platform/daily/foo.test.ts', 'actors/foo_bar/src/main.ts'],
439
+ actorConfigs: [miniActor],
440
+ range,
441
+ platformTestsGlob: 'test/platform/**',
404
442
  });
405
- expect(result).toEqual([miniActor]);
443
+ expect(result).toStrictEqual({ functional: [miniActor], cosmetic: [], test: [miniActor] });
406
444
  });
407
445
 
408
- it('test file listed in .dockerignore stays ignored without a test files glob', async () => {
446
+ it('test file listed in .dockerignore stays ignored without a platform tests glob', async () => {
409
447
  vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.startsWith('test/'));
410
448
  const result = await getChangedActors({
411
449
  filepathsChanged: ['test/platform/daily/foo.test.ts'],
412
450
  actorConfigs: [miniActor],
413
- commits,
451
+ range,
414
452
  });
415
- expect(result).toEqual([]);
453
+ expect(result).toStrictEqual({ functional: [], cosmetic: [], test: [] });
416
454
  });
417
455
 
418
- it('test files glob matches case-insensitively and does not bypass .dockerignore for other files', async () => {
456
+ it('platform tests glob matches case-insensitively and does not bypass .dockerignore for other files', async () => {
419
457
  vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => true);
420
- const result = await getChangedActors({
458
+ const result = await testChangedActorsFor({
421
459
  filepathsChanged: ['Test/Platform/Foo.test.ts'],
422
460
  actorConfigs: [miniActor],
423
- commits,
424
- testFilesGlob: 'test/platform/**',
461
+ range,
462
+ platformTestsGlob: 'test/platform/**',
425
463
  });
426
464
  expect(result).toEqual([miniActor]);
427
465
  expect(
428
- await getChangedActors({
466
+ await changedActorsFor({
429
467
  filepathsChanged: ['actors/foo_bar/node_modules/foo.js'],
430
468
  actorConfigs: [miniActor],
431
- commits,
432
- testFilesGlob: 'test/platform/**',
469
+ range,
470
+ platformTestsGlob: 'test/platform/**',
433
471
  }),
434
472
  ).toEqual([]);
435
473
  });
436
474
 
437
475
  it('test file outside an actor context still does not trigger it', async () => {
438
476
  vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => true);
439
- const result = await getChangedActors({
477
+ const result = await changedActorsFor({
440
478
  filepathsChanged: ['test/platform/daily/foo.test.ts'],
441
479
  actorConfigs: [standaloneActor],
442
- commits,
443
- testFilesGlob: 'test/platform/**',
480
+ range,
481
+ platformTestsGlob: 'test/platform/**',
444
482
  });
445
483
  expect(result).toEqual([]);
446
484
  });
@@ -451,85 +489,85 @@ describe('getChangedActors', () => {
451
489
  ...standaloneActor,
452
490
  contextPaths: [...standaloneActor.contextPaths, new RelativeDir('test')],
453
491
  };
454
- const result = await getChangedActors({
492
+ const result = await testChangedActorsFor({
455
493
  filepathsChanged: ['test/platform/standalone.test.ts'],
456
494
  actorConfigs: [actorWithTests],
457
- commits,
458
- testFilesGlob: 'test/platform/**',
495
+ range,
496
+ platformTestsGlob: 'test/platform/**',
459
497
  });
460
498
  expect(result).toEqual([actorWithTests]);
461
499
  });
462
500
 
463
501
  it('JSON file in context but outside actor folder is functional (not checked for cosmetic)', async () => {
464
- const result = await getChangedActors({
502
+ const result = await changedActorsFor({
465
503
  filepathsChanged: ['lib/config.json'],
466
504
  actorConfigs: [miniActor],
467
- commits,
505
+ range,
468
506
  });
469
507
  expect(result).toEqual([miniActor]);
470
508
  });
471
509
 
472
510
  it('README outside actor folder but inside context is ignored (not cosmetic)', async () => {
473
- const result = await getChangedActors({
511
+ const result = await changedActorsFor({
474
512
  filepathsChanged: ['docs/README.md'],
475
513
  actorConfigs: [miniActor],
476
- commits,
514
+ range,
477
515
  isLatest: true,
478
516
  });
479
517
  expect(result).toEqual([]);
480
518
  });
481
519
 
482
520
  it('README inside actor folder is cosmetic', async () => {
483
- const result = await getChangedActors({
521
+ const result = await changedActorsFor({
484
522
  filepathsChanged: ['actors/foo_bar/README.md'],
485
523
  actorConfigs: [miniActor],
486
- commits,
524
+ range,
487
525
  isLatest: true,
488
526
  });
489
527
  expect(result).toEqual([miniActor]);
490
528
  });
491
529
 
492
530
  it('ignores a standalone actor top-level dev file relative to its context', async () => {
493
- const result = await getChangedActors({
531
+ const result = await changedActorsFor({
494
532
  filepathsChanged: ['standalone-actors/standalone/.eslintrc'],
495
533
  actorConfigs,
496
- commits,
534
+ range,
497
535
  });
498
536
  expect(result).toEqual([]);
499
537
  });
500
538
 
501
- it('does not special-case code/ and shared/ prefixes anymore — must be declared via overrideActorContext', async () => {
502
- const result = await getChangedActors({
539
+ it('does not special-case code/ and shared/ prefixes — they must be declared via overrideActorContext', async () => {
540
+ const result = await changedActorsFor({
503
541
  filepathsChanged: ['code/some/code.ts'],
504
542
  actorConfigs: [miniActor],
505
- commits,
543
+ range,
506
544
  });
507
545
  expect(result).toEqual([miniActor]);
508
546
  });
509
547
 
510
548
  it('ignores code/.eslintrc when "code" is declared via overrideActorContext', async () => {
511
- const result = await getChangedActors({
549
+ const result = await changedActorsFor({
512
550
  filepathsChanged: ['code/.eslintrc'],
513
551
  actorConfigs: [amazonActor],
514
- commits,
552
+ range,
515
553
  });
516
554
  expect(result).toEqual([]);
517
555
  });
518
556
 
519
557
  it('shared/Dockerfile declared via overrideActorContext is functional', async () => {
520
- const result = await getChangedActors({
558
+ const result = await changedActorsFor({
521
559
  filepathsChanged: ['shared/Dockerfile'],
522
560
  actorConfigs: [amazonActor],
523
- commits,
561
+ range,
524
562
  });
525
563
  expect(result).toEqual([amazonActor]);
526
564
  });
527
565
 
528
566
  it('code/README.md declared via overrideActorContext is ignored (outside actor folder)', async () => {
529
- const result = await getChangedActors({
567
+ const result = await changedActorsFor({
530
568
  filepathsChanged: ['code/README.md'],
531
569
  actorConfigs: [amazonActor],
532
- commits,
570
+ range,
533
571
  isLatest: true,
534
572
  });
535
573
  expect(result).toEqual([]);
@@ -547,13 +585,14 @@ describe('getChangedActors logging', () => {
547
585
  await getChangedActors({
548
586
  filepathsChanged: ['actors/foo_bar/src/main.ts'],
549
587
  actorConfigs: [miniActor],
550
- commits,
588
+ range,
551
589
  });
552
590
 
553
591
  expect(logger.info).toHaveBeenCalledWith(
554
592
  '[DIFF]: Changes specific to actor foo/bar: actors/foo_bar/src/main.ts',
555
593
  );
556
- expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors to be built and tested: foo/bar');
594
+ expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with functional changes: foo/bar');
595
+ expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with only cosmetic changes: none');
557
596
  });
558
597
 
559
598
  it('logs a single "shared" group when two actors are triggered by the exact same file', async () => {
@@ -563,14 +602,14 @@ describe('getChangedActors logging', () => {
563
602
  await getChangedActors({
564
603
  filepathsChanged: ['shared/shared.ts'],
565
604
  actorConfigs: [actorA, actorB],
566
- commits,
605
+ range,
567
606
  });
568
607
 
569
608
  expect(logger.info).toHaveBeenCalledWith(
570
609
  '[DIFF]: Shared changes for actors team/actor-a, team/actor-b: shared/shared.ts',
571
610
  );
572
611
  expect(logger.info).not.toHaveBeenCalledWith(expect.stringContaining('Changes specific to actor'));
573
- expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors to be built and tested: team/actor-a, team/actor-b');
612
+ expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with functional changes: team/actor-a, team/actor-b');
574
613
  });
575
614
 
576
615
  it('logs shared and specific groups in descending-size order for partial overlap across actors', async () => {
@@ -580,7 +619,7 @@ describe('getChangedActors logging', () => {
580
619
  await getChangedActors({
581
620
  filepathsChanged: ['shared.ts', 'actors/a/a-only.ts', 'actors/b/b-only.ts'],
582
621
  actorConfigs: [actorA, actorB],
583
- commits,
622
+ range,
584
623
  });
585
624
 
586
625
  const errorCalls = vi.mocked(logger.info).mock.calls.map((call) => call[0]);
@@ -589,7 +628,9 @@ describe('getChangedActors logging', () => {
589
628
  '[DIFF]: Shared changes for actors team/actor-a, team/actor-b: shared.ts',
590
629
  '[DIFF]: Changes specific to actor team/actor-a: actors/a/a-only.ts',
591
630
  '[DIFF]: Changes specific to actor team/actor-b: actors/b/b-only.ts',
592
- '[DIFF]: Actors to be built and tested: team/actor-a, team/actor-b',
631
+ '[DIFF]: Actors with functional changes: team/actor-a, team/actor-b',
632
+ '[DIFF]: Actors with only cosmetic changes: none',
633
+ '[DIFF]: Actors with platform test changes: none',
593
634
  ]);
594
635
  });
595
636
 
@@ -601,19 +642,19 @@ describe('getChangedActors logging', () => {
601
642
  await getChangedActors({
602
643
  filepathsChanged: ['test/platform/standalone.test.ts'],
603
644
  actorConfigs: [standaloneActor],
604
- commits,
605
- testFilesGlob: 'test/platform/**',
645
+ range,
646
+ platformTestsGlob: 'test/platform/**',
606
647
  });
607
648
 
608
649
  expect(logger.warn).toHaveBeenCalledWith(outsideContextWarning('test/platform/standalone.test.ts'));
609
650
  });
610
651
 
611
652
  it('still warns when the same push also rebuilds an Actor', async () => {
612
- const result = await getChangedActors({
653
+ const result = await changedActorsFor({
613
654
  filepathsChanged: ['test/platform/standalone.test.ts', 'standalone-actors/standalone/src/main.ts'],
614
655
  actorConfigs: [standaloneActor],
615
- commits,
616
- testFilesGlob: 'test/platform/**',
656
+ range,
657
+ platformTestsGlob: 'test/platform/**',
617
658
  });
618
659
 
619
660
  expect(result).toEqual([standaloneActor]);
@@ -624,8 +665,8 @@ describe('getChangedActors logging', () => {
624
665
  await getChangedActors({
625
666
  filepathsChanged: ['test/platform/foo.test.ts', 'test/platform/README.md', 'test/platform/CHANGELOG.md'],
626
667
  actorConfigs: [miniActor],
627
- commits,
628
- testFilesGlob: 'test/platform/**',
668
+ range,
669
+ platformTestsGlob: 'test/platform/**',
629
670
  });
630
671
 
631
672
  expect(logger.warn).not.toHaveBeenCalled();
@@ -635,11 +676,37 @@ describe('getChangedActors logging', () => {
635
676
  await getChangedActors({
636
677
  filepathsChanged: ['.gitignore', '.prettierrc'],
637
678
  actorConfigs,
638
- commits,
679
+ range,
639
680
  });
640
681
 
641
682
  expect(logger.info).not.toHaveBeenCalledWith(expect.stringContaining('Shared changes'));
642
683
  expect(logger.info).not.toHaveBeenCalledWith(expect.stringContaining('Changes specific to'));
643
- expect(logger.info).toHaveBeenCalledWith('[DIFF]: No relevant files changed, skipping builds and tests');
684
+ expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with functional changes: none');
685
+ expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with only cosmetic changes: none');
686
+ });
687
+ });
688
+
689
+ describe('getChangedActors split by impact', () => {
690
+ beforeEach(() => {
691
+ vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(false);
692
+ });
693
+
694
+ it('lists an Actor as functional when it has any functional change, and as cosmetic only otherwise', async () => {
695
+ const result = await getChangedActors({
696
+ filepathsChanged: [
697
+ 'actors/foo_bar/README.md',
698
+ 'standalone-actors/standalone/README.md',
699
+ 'actors/foo_bar/src/main.ts',
700
+ ],
701
+ actorConfigs,
702
+ range,
703
+ });
704
+ expect(result).toStrictEqual({ functional: [miniActor], cosmetic: [standaloneActor], test: [] });
705
+ });
706
+
707
+ it('returns empty lists when nothing relevant changed', async () => {
708
+ expect(
709
+ await getChangedActors({ filepathsChanged: ['.vscode/settings.json'], actorConfigs, range }),
710
+ ).toStrictEqual({ functional: [], cosmetic: [], test: [] });
644
711
  });
645
712
  });