apify-test-tools 0.10.2-beta.12 → 0.10.2-beta.14

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 (120) hide show
  1. package/.github/cli/apify-test-tools.mjs +123 -128
  2. package/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml +1 -1
  3. package/.github/workflows/public_platform-tests.yaml +36 -22
  4. package/.github/workflows/public_pr-build-test.yaml +7 -6
  5. package/.github/workflows/public_push-build-latest.yaml +6 -4
  6. package/.prettierignore +1 -1
  7. package/CHANGELOG.md +3 -0
  8. package/CONTRIBUTING.md +8 -6
  9. package/README.md +10 -11
  10. package/bin/actor-ids.ts +38 -0
  11. package/bin/build.ts +1 -1
  12. package/bin/git.ts +20 -92
  13. package/bin/main.ts +87 -73
  14. package/bin/notify.ts +198 -0
  15. package/bin/run-tests.ts +141 -0
  16. package/bin/slack.ts +16 -87
  17. package/bin/stdin-input.ts +98 -7
  18. package/bin/test-report.ts +141 -140
  19. package/bin/types.ts +0 -9
  20. package/dist/bin/actor-ids.d.ts +16 -0
  21. package/dist/bin/actor-ids.d.ts.map +1 -0
  22. package/dist/bin/actor-ids.js +24 -0
  23. package/dist/bin/actor-ids.js.map +1 -0
  24. package/dist/bin/build.js +1 -1
  25. package/dist/bin/build.js.map +1 -1
  26. package/dist/bin/git.d.ts +6 -16
  27. package/dist/bin/git.d.ts.map +1 -1
  28. package/dist/bin/git.js +15 -75
  29. package/dist/bin/git.js.map +1 -1
  30. package/dist/bin/main.js +80 -51
  31. package/dist/bin/main.js.map +1 -1
  32. package/dist/bin/notify.d.ts +35 -0
  33. package/dist/bin/notify.d.ts.map +1 -0
  34. package/dist/bin/notify.js +131 -0
  35. package/dist/bin/notify.js.map +1 -0
  36. package/dist/bin/run-tests.d.ts +21 -0
  37. package/dist/bin/run-tests.d.ts.map +1 -0
  38. package/dist/bin/run-tests.js +116 -0
  39. package/dist/bin/run-tests.js.map +1 -0
  40. package/dist/bin/slack.d.ts +2 -17
  41. package/dist/bin/slack.d.ts.map +1 -1
  42. package/dist/bin/slack.js +17 -58
  43. package/dist/bin/slack.js.map +1 -1
  44. package/dist/bin/stdin-input.d.ts +71 -9
  45. package/dist/bin/stdin-input.d.ts.map +1 -1
  46. package/dist/bin/stdin-input.js +76 -6
  47. package/dist/bin/stdin-input.js.map +1 -1
  48. package/dist/bin/test-report.d.ts +69 -8
  49. package/dist/bin/test-report.d.ts.map +1 -1
  50. package/dist/bin/test-report.js +76 -67
  51. package/dist/bin/test-report.js.map +1 -1
  52. package/dist/bin/types.d.ts +0 -8
  53. package/dist/bin/types.d.ts.map +1 -1
  54. package/dist/lib/lib.d.ts +0 -3
  55. package/dist/lib/lib.d.ts.map +1 -1
  56. package/dist/lib/lib.js +5 -10
  57. package/dist/lib/lib.js.map +1 -1
  58. package/dist/test/bundle/cli-bundle.test.js +40 -48
  59. package/dist/test/bundle/cli-bundle.test.js.map +1 -1
  60. package/dist/test/e2e/cli-bundle.e2e.test.js +15 -16
  61. package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -1
  62. package/dist/test/e2e/git-build-release.e2e.test.js +2 -2
  63. package/dist/test/e2e/git-build-release.e2e.test.js.map +1 -1
  64. package/dist/test/unit/bin/actor-ids.test.d.ts +2 -0
  65. package/dist/test/unit/bin/actor-ids.test.d.ts.map +1 -0
  66. package/dist/test/unit/bin/actor-ids.test.js +32 -0
  67. package/dist/test/unit/bin/actor-ids.test.js.map +1 -0
  68. package/dist/test/unit/bin/build-cli.test.js +8 -3
  69. package/dist/test/unit/bin/build-cli.test.js.map +1 -1
  70. package/dist/test/unit/bin/compiled-cli.d.ts +1 -1
  71. package/dist/test/unit/bin/compiled-cli.d.ts.map +1 -1
  72. package/dist/test/unit/bin/compiled-cli.js +12 -5
  73. package/dist/test/unit/bin/compiled-cli.js.map +1 -1
  74. package/dist/test/unit/bin/diff-changes.test.js +1 -1
  75. package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
  76. package/dist/test/unit/bin/git.test.js +4 -142
  77. package/dist/test/unit/bin/git.test.js.map +1 -1
  78. package/dist/test/unit/bin/notify.test.d.ts +2 -0
  79. package/dist/test/unit/bin/notify.test.d.ts.map +1 -0
  80. package/dist/test/unit/bin/notify.test.js +222 -0
  81. package/dist/test/unit/bin/notify.test.js.map +1 -0
  82. package/dist/test/unit/bin/stdin-input.test.js +51 -9
  83. package/dist/test/unit/bin/stdin-input.test.js.map +1 -1
  84. package/dist/test/unit/bin/test-cli.test.d.ts +2 -0
  85. package/dist/test/unit/bin/test-cli.test.d.ts.map +1 -0
  86. package/dist/test/unit/bin/test-cli.test.js +115 -0
  87. package/dist/test/unit/bin/test-cli.test.js.map +1 -0
  88. package/dist/test/unit/bin/test-report.test.d.ts +2 -0
  89. package/dist/test/unit/bin/test-report.test.d.ts.map +1 -0
  90. package/dist/test/unit/bin/test-report.test.js +100 -0
  91. package/dist/test/unit/bin/test-report.test.js.map +1 -0
  92. package/dist/tsconfig.tsbuildinfo +1 -1
  93. package/docs/cli.md +131 -53
  94. package/docs/lib.md +21 -16
  95. package/docs/workflows.md +24 -23
  96. package/eslint.config.mjs +1 -1
  97. package/lib/lib.ts +5 -10
  98. package/package.json +1 -1
  99. package/test/bundle/cli-bundle.test.ts +47 -60
  100. package/test/e2e/cli-bundle.e2e.test.ts +18 -25
  101. package/test/e2e/git-build-release.e2e.test.ts +2 -2
  102. package/test/unit/bin/actor-ids.test.ts +43 -0
  103. package/test/unit/bin/build-cli.test.ts +9 -3
  104. package/test/unit/bin/compiled-cli.ts +11 -5
  105. package/test/unit/bin/diff-changes.test.ts +1 -1
  106. package/test/unit/bin/git.test.ts +3 -197
  107. package/test/unit/bin/notify.test.ts +299 -0
  108. package/test/unit/bin/stdin-input.test.ts +68 -9
  109. package/test/unit/bin/test-cli.test.ts +137 -0
  110. package/test/unit/bin/test-report.test.ts +118 -0
  111. package/dist/test/unit/bin/logging.test.d.ts +0 -2
  112. package/dist/test/unit/bin/logging.test.d.ts.map +0 -1
  113. package/dist/test/unit/bin/logging.test.js +0 -43
  114. package/dist/test/unit/bin/logging.test.js.map +0 -1
  115. package/dist/test/unit/bin/slack.test.d.ts +0 -2
  116. package/dist/test/unit/bin/slack.test.d.ts.map +0 -1
  117. package/dist/test/unit/bin/slack.test.js +0 -71
  118. package/dist/test/unit/bin/slack.test.js.map +0 -1
  119. package/test/unit/bin/logging.test.ts +0 -52
  120. package/test/unit/bin/slack.test.ts +0 -84
@@ -1,43 +0,0 @@
1
- import { execFileSync, spawnSync } from 'node:child_process';
2
- import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import process from 'node:process';
6
- import { fileURLToPath } from 'node:url';
7
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
8
- const projectRoot = fileURLToPath(new URL('../../../', import.meta.url));
9
- const compilerPath = fileURLToPath(new URL('../../../node_modules/typescript/bin/tsc', import.meta.url));
10
- let cliPath;
11
- let buildDir;
12
- let gitStubDir;
13
- const sha = '1'.repeat(40);
14
- describe('CLI logging', () => {
15
- beforeAll(async () => {
16
- buildDir = await mkdtemp(path.join(projectRoot, '.cli-test-'));
17
- execFileSync(process.execPath, [compilerPath, '--outDir', buildDir], { cwd: projectRoot });
18
- cliPath = path.join(buildDir, 'bin/main.js');
19
- await chmod(cliPath, 0o755);
20
- gitStubDir = await mkdtemp(path.join(os.tmpdir(), 'apify-cli-logging-'));
21
- const gitStub = path.join(gitStubDir, 'git');
22
- await writeFile(gitStub, `#!/bin/sh\nprintf '%s' '${sha}»¦«Test<test@example.com>»¦«Tue, 06 Oct 2026 00:00:00 +0000»¦«feature'\n`);
23
- await chmod(gitStub, 0o755);
24
- });
25
- afterAll(async () => {
26
- if (buildDir)
27
- await rm(buildDir, { recursive: true, force: true });
28
- if (gitStubDir)
29
- await rm(gitStubDir, { recursive: true, force: true });
30
- });
31
- it.each(['info', 'silent'])('keeps JSON results intact with --log-level %s', (level) => {
32
- const result = spawnSync(cliPath, ['get-commits', '--source-branch', 'feature', '--target-branch', 'base', '--log-level', level], {
33
- encoding: 'utf8',
34
- stdio: ['ignore', 'pipe', 'pipe'],
35
- env: { ...process.env, PATH: `${gitStubDir}${path.delimiter}${process.env.PATH ?? ''}` },
36
- });
37
- expect(result.status, result.stderr).toBe(0);
38
- expect(result.stderr).toEqual(level === 'silent' ? '' : expect.stringContaining('Commits being returned:'));
39
- expect(JSON.parse(result.stdout)).toMatchObject([{ sha, date: expect.any(String), message: 'feature' }]);
40
- expect(result.stdout.endsWith('\n')).toBe(true);
41
- });
42
- });
43
- //# sourceMappingURL=logging.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logging.test.js","sourceRoot":"","sources":["../../../../test/unit/bin/logging.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=slack.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slack.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/bin/slack.test.ts"],"names":[],"mappings":""}
@@ -1,71 +0,0 @@
1
- import { WebClient } from '@slack/web-api';
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { notifyToSlack } from '../../../bin/slack.js';
4
- vi.mock('@slack/web-api', () => ({ WebClient: vi.fn() }));
5
- const TOKEN_ENV_VAR = 'SLACK_TOKEN_RELEASES_BOT';
6
- const postMessage = vi.fn();
7
- const authTest = vi.fn();
8
- const notify = async (overrides = {}) => notifyToSlack({
9
- repoUrl: 'git@github.com:owner/repo',
10
- changedFiles: ['src/main.ts'],
11
- changelog: '- Fixed a bug',
12
- commits: [{ sha: '1', author: 'Test<test@example.com>', date: '', message: 'fix: bug' }],
13
- dryRun: true,
14
- releaseSlackChannel: '#releases',
15
- reportSlackChannel: '#notif',
16
- ...overrides,
17
- });
18
- describe('notifyToSlack', () => {
19
- beforeEach(() => {
20
- vi.stubEnv(TOKEN_ENV_VAR, 'token');
21
- vi.mocked(WebClient).mockImplementation(function () {
22
- return { chat: { postMessage }, auth: { test: authTest } };
23
- });
24
- });
25
- afterEach(() => {
26
- vi.unstubAllEnvs();
27
- vi.clearAllMocks();
28
- });
29
- it('should verify the token but post nothing in a dry run', async () => {
30
- await notify();
31
- expect(authTest).toHaveBeenCalledTimes(1);
32
- expect(postMessage).not.toHaveBeenCalled();
33
- });
34
- it('should still require the token in a dry run', async () => {
35
- vi.stubEnv(TOKEN_ENV_VAR, '');
36
- await expect(notify()).rejects.toThrow(`${TOKEN_ENV_VAR} not defined`);
37
- });
38
- it('should fail a dry run when Slack rejects the token', async () => {
39
- authTest.mockRejectedValueOnce(new Error('An API error occurred: invalid_auth'));
40
- await expect(notify()).rejects.toThrow(`${TOKEN_ENV_VAR} was rejected by Slack`);
41
- });
42
- it('should not need a token when no channel is passed', async () => {
43
- vi.stubEnv(TOKEN_ENV_VAR, '');
44
- await notify({ dryRun: false, releaseSlackChannel: undefined, reportSlackChannel: undefined });
45
- expect(WebClient).not.toHaveBeenCalled();
46
- });
47
- it('should post to both channels outside of a dry run', async () => {
48
- await notify({ dryRun: false });
49
- expect(authTest).not.toHaveBeenCalled();
50
- expect(postMessage).toHaveBeenCalledTimes(2);
51
- });
52
- it('should announce nothing, and need no token, when there are no new commits', async () => {
53
- vi.stubEnv(TOKEN_ENV_VAR, '');
54
- await notify({ commits: [], dryRun: false });
55
- expect(WebClient).not.toHaveBeenCalled();
56
- });
57
- it('should announce the release by the author of the newest commit, named after the repository', async () => {
58
- const commit = (author, message) => ({ sha: '1', author, date: '', message });
59
- await notify({
60
- commits: [commit('Old<old@example.com>', 'fix: older'), commit('New<new@example.com>', 'feat: newer')],
61
- repoUrl: 'git@github.com:owner/my-repo',
62
- dryRun: false,
63
- releaseSlackChannel: undefined,
64
- });
65
- expect(postMessage).toHaveBeenCalledWith({
66
- channel: '#notif',
67
- text: expect.stringContaining('*my-repo* – New release (by New)'),
68
- });
69
- });
70
- });
71
- //# sourceMappingURL=slack.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slack.test.js","sourceRoot":"","sources":["../../../../test/unit/bin/slack.test.ts"],"names":[],"mappings":"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"}
@@ -1,52 +0,0 @@
1
- import { execFileSync, spawnSync } from 'node:child_process';
2
- import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import process from 'node:process';
6
- import { fileURLToPath } from 'node:url';
7
-
8
- import { afterAll, beforeAll, describe, expect, it } from 'vitest';
9
-
10
- const projectRoot = fileURLToPath(new URL('../../../', import.meta.url));
11
- const compilerPath = fileURLToPath(new URL('../../../node_modules/typescript/bin/tsc', import.meta.url));
12
- let cliPath: string;
13
- let buildDir: string | undefined;
14
- let gitStubDir: string | undefined;
15
- const sha = '1'.repeat(40);
16
-
17
- describe('CLI logging', () => {
18
- beforeAll(async () => {
19
- buildDir = await mkdtemp(path.join(projectRoot, '.cli-test-'));
20
- execFileSync(process.execPath, [compilerPath, '--outDir', buildDir], { cwd: projectRoot });
21
- cliPath = path.join(buildDir, 'bin/main.js');
22
- await chmod(cliPath, 0o755);
23
- gitStubDir = await mkdtemp(path.join(os.tmpdir(), 'apify-cli-logging-'));
24
- const gitStub = path.join(gitStubDir, 'git');
25
- await writeFile(
26
- gitStub,
27
- `#!/bin/sh\nprintf '%s' '${sha}»¦«Test<test@example.com>»¦«Tue, 06 Oct 2026 00:00:00 +0000»¦«feature'\n`,
28
- );
29
- await chmod(gitStub, 0o755);
30
- });
31
-
32
- afterAll(async () => {
33
- if (buildDir) await rm(buildDir, { recursive: true, force: true });
34
- if (gitStubDir) await rm(gitStubDir, { recursive: true, force: true });
35
- });
36
-
37
- it.each(['info', 'silent'])('keeps JSON results intact with --log-level %s', (level) => {
38
- const result = spawnSync(
39
- cliPath,
40
- ['get-commits', '--source-branch', 'feature', '--target-branch', 'base', '--log-level', level],
41
- {
42
- encoding: 'utf8',
43
- stdio: ['ignore', 'pipe', 'pipe'],
44
- env: { ...process.env, PATH: `${gitStubDir}${path.delimiter}${process.env.PATH ?? ''}` },
45
- },
46
- );
47
- expect(result.status, result.stderr).toBe(0);
48
- expect(result.stderr).toEqual(level === 'silent' ? '' : expect.stringContaining('Commits being returned:'));
49
- expect(JSON.parse(result.stdout)).toMatchObject([{ sha, date: expect.any(String), message: 'feature' }]);
50
- expect(result.stdout.endsWith('\n')).toBe(true);
51
- });
52
- });
@@ -1,84 +0,0 @@
1
- import { WebClient } from '@slack/web-api';
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
-
4
- import { notifyToSlack } from '../../../bin/slack.js';
5
-
6
- vi.mock('@slack/web-api', () => ({ WebClient: vi.fn() }));
7
-
8
- const TOKEN_ENV_VAR = 'SLACK_TOKEN_RELEASES_BOT';
9
- const postMessage = vi.fn();
10
- const authTest = vi.fn();
11
-
12
- const notify = async (overrides: Partial<Parameters<typeof notifyToSlack>[0]> = {}) =>
13
- notifyToSlack({
14
- repoUrl: 'git@github.com:owner/repo',
15
- changedFiles: ['src/main.ts'],
16
- changelog: '- Fixed a bug',
17
- commits: [{ sha: '1', author: 'Test<test@example.com>', date: '', message: 'fix: bug' }],
18
- dryRun: true,
19
- releaseSlackChannel: '#releases',
20
- reportSlackChannel: '#notif',
21
- ...overrides,
22
- });
23
-
24
- describe('notifyToSlack', () => {
25
- beforeEach(() => {
26
- vi.stubEnv(TOKEN_ENV_VAR, 'token');
27
- vi.mocked(WebClient).mockImplementation(function () {
28
- return { chat: { postMessage }, auth: { test: authTest } };
29
- } as never);
30
- });
31
-
32
- afterEach(() => {
33
- vi.unstubAllEnvs();
34
- vi.clearAllMocks();
35
- });
36
-
37
- it('should verify the token but post nothing in a dry run', async () => {
38
- await notify();
39
- expect(authTest).toHaveBeenCalledTimes(1);
40
- expect(postMessage).not.toHaveBeenCalled();
41
- });
42
-
43
- it('should still require the token in a dry run', async () => {
44
- vi.stubEnv(TOKEN_ENV_VAR, '');
45
- await expect(notify()).rejects.toThrow(`${TOKEN_ENV_VAR} not defined`);
46
- });
47
-
48
- it('should fail a dry run when Slack rejects the token', async () => {
49
- authTest.mockRejectedValueOnce(new Error('An API error occurred: invalid_auth'));
50
- await expect(notify()).rejects.toThrow(`${TOKEN_ENV_VAR} was rejected by Slack`);
51
- });
52
-
53
- it('should not need a token when no channel is passed', async () => {
54
- vi.stubEnv(TOKEN_ENV_VAR, '');
55
- await notify({ dryRun: false, releaseSlackChannel: undefined, reportSlackChannel: undefined });
56
- expect(WebClient).not.toHaveBeenCalled();
57
- });
58
-
59
- it('should post to both channels outside of a dry run', async () => {
60
- await notify({ dryRun: false });
61
- expect(authTest).not.toHaveBeenCalled();
62
- expect(postMessage).toHaveBeenCalledTimes(2);
63
- });
64
-
65
- it('should announce nothing, and need no token, when there are no new commits', async () => {
66
- vi.stubEnv(TOKEN_ENV_VAR, '');
67
- await notify({ commits: [], dryRun: false });
68
- expect(WebClient).not.toHaveBeenCalled();
69
- });
70
-
71
- it('should announce the release by the author of the newest commit, named after the repository', async () => {
72
- const commit = (author: string, message: string) => ({ sha: '1', author, date: '', message });
73
- await notify({
74
- commits: [commit('Old<old@example.com>', 'fix: older'), commit('New<new@example.com>', 'feat: newer')],
75
- repoUrl: 'git@github.com:owner/my-repo',
76
- dryRun: false,
77
- releaseSlackChannel: undefined,
78
- });
79
- expect(postMessage).toHaveBeenCalledWith({
80
- channel: '#notif',
81
- text: expect.stringContaining('*my-repo* – New release (by New)'),
82
- });
83
- });
84
- });