apify-test-tools 0.8.6 → 0.9.0-beta.0
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.
- package/README.md +83 -13
- package/bin/build-from-local.ts +35 -34
- package/bin/build.ts +55 -59
- package/bin/diff-changes.ts +166 -125
- package/bin/dockerignore.ts +50 -0
- package/bin/main.ts +7 -7
- package/bin/path-utils.ts +13 -0
- package/bin/test-report.ts +5 -5
- package/bin/types.ts +17 -5
- package/bin/utils.ts +124 -95
- package/dist/bin/build-from-local.d.ts +2 -2
- package/dist/bin/build-from-local.d.ts.map +1 -1
- package/dist/bin/build-from-local.js +33 -28
- package/dist/bin/build-from-local.js.map +1 -1
- package/dist/bin/build.d.ts +5 -8
- package/dist/bin/build.d.ts.map +1 -1
- package/dist/bin/build.js +49 -56
- package/dist/bin/build.js.map +1 -1
- package/dist/bin/diff-changes.d.ts +0 -6
- package/dist/bin/diff-changes.d.ts.map +1 -1
- package/dist/bin/diff-changes.js +129 -89
- package/dist/bin/diff-changes.js.map +1 -1
- package/dist/bin/dockerignore.d.ts +17 -0
- package/dist/bin/dockerignore.d.ts.map +1 -0
- package/dist/bin/dockerignore.js +41 -0
- package/dist/bin/dockerignore.js.map +1 -0
- package/dist/bin/main.js +7 -7
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/path-utils.d.ts +4 -0
- package/dist/bin/path-utils.d.ts.map +1 -0
- package/dist/bin/path-utils.js +9 -0
- package/dist/bin/path-utils.js.map +1 -0
- package/dist/bin/test-report.js +3 -3
- package/dist/bin/test-report.js.map +1 -1
- package/dist/bin/types.d.ts +15 -4
- package/dist/bin/types.d.ts.map +1 -1
- package/dist/bin/utils.d.ts +2 -19
- package/dist/bin/utils.d.ts.map +1 -1
- package/dist/bin/utils.js +82 -81
- package/dist/bin/utils.js.map +1 -1
- package/dist/lib/lib.d.ts +10 -4
- package/dist/lib/lib.d.ts.map +1 -1
- package/dist/lib/lib.js +28 -22
- package/dist/lib/lib.js.map +1 -1
- package/dist/lib/types.d.ts +2 -2
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +4 -4
- package/dist/lib/utils.js.map +1 -1
- package/dist/test/unit/bin/build-from-local.test.js +55 -86
- package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
- package/dist/test/unit/bin/diff-changes.test.js +358 -36
- package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
- package/dist/test/unit/bin/dockerignore.test.d.ts +2 -0
- package/dist/test/unit/bin/dockerignore.test.d.ts.map +1 -0
- package/dist/test/unit/bin/dockerignore.test.js +102 -0
- package/dist/test/unit/bin/dockerignore.test.js.map +1 -0
- package/dist/test/unit/bin/path-utils.test.d.ts +2 -0
- package/dist/test/unit/bin/path-utils.test.d.ts.map +1 -0
- package/dist/test/unit/bin/path-utils.test.js +14 -0
- package/dist/test/unit/bin/path-utils.test.js.map +1 -0
- package/dist/test/unit/bin/utils.test.d.ts +2 -0
- package/dist/test/unit/bin/utils.test.d.ts.map +1 -0
- package/dist/test/unit/bin/utils.test.js +292 -0
- package/dist/test/unit/bin/utils.test.js.map +1 -0
- package/dist/test/unit/should-built-and-test.test.js +83 -32
- package/dist/test/unit/should-built-and-test.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/lib.ts +28 -22
- package/lib/types.ts +2 -2
- package/lib/utils.ts +4 -4
- package/package.json +62 -61
- package/test/unit/bin/build-from-local.test.ts +62 -121
- package/test/unit/bin/diff-changes.test.ts +397 -41
- package/test/unit/bin/dockerignore.test.ts +123 -0
- package/test/unit/bin/path-utils.test.ts +17 -0
- package/test/unit/bin/utils.test.ts +342 -0
- package/test/unit/should-built-and-test.test.ts +89 -32
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { CONFIG_FILE_NAME, readConfigFile } from '../../../bin/utils.js';
|
|
4
|
+
|
|
5
|
+
const { fsMock } = vi.hoisted(() => ({
|
|
6
|
+
fsMock: {
|
|
7
|
+
readFile: vi.fn(),
|
|
8
|
+
},
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
vi.mock('node:fs/promises', () => ({ default: fsMock }));
|
|
12
|
+
|
|
13
|
+
afterEach(() => vi.restoreAllMocks());
|
|
14
|
+
|
|
15
|
+
const validConfig = (actors: object[]) => JSON.stringify({ actors });
|
|
16
|
+
const actorJson = (fields: Record<string, unknown> = {}) => JSON.stringify(fields);
|
|
17
|
+
|
|
18
|
+
const expectFileRead = (filePath: string) => {
|
|
19
|
+
expect(fsMock.readFile).toHaveBeenCalledWith(filePath, expect.anything());
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const mockFiles = (files: Record<string, string>) => {
|
|
23
|
+
fsMock.readFile.mockImplementation(async (filePath: string) => {
|
|
24
|
+
if (filePath in files) return Promise.resolve(files[filePath]);
|
|
25
|
+
return Promise.reject(new Error(`ENOENT: ${filePath}`));
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
describe('readConfigFile', () => {
|
|
30
|
+
it('returns correct ActorConfig[] for a valid config', async () => {
|
|
31
|
+
mockFiles({
|
|
32
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
33
|
+
{
|
|
34
|
+
folder: 'actors/shopify',
|
|
35
|
+
actorFullName: 'myteam/shopify-scraper',
|
|
36
|
+
tokenEnvVar: 'APIFY_TOKEN_MYTEAM',
|
|
37
|
+
},
|
|
38
|
+
]),
|
|
39
|
+
'actors/shopify/.actor/actor.json': actorJson({ dockerContextDir: '../../..' }),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const result = await readConfigFile();
|
|
43
|
+
expectFileRead('actors/shopify/.actor/actor.json');
|
|
44
|
+
expect(result).toEqual([
|
|
45
|
+
{
|
|
46
|
+
actorFullName: 'myteam/shopify-scraper',
|
|
47
|
+
folder: 'actors/shopify',
|
|
48
|
+
tokenEnvVar: 'APIFY_TOKEN_MYTEAM',
|
|
49
|
+
dockerContextDir: '',
|
|
50
|
+
contextPaths: [''],
|
|
51
|
+
},
|
|
52
|
+
]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('normalizes folder "." to ""', async () => {
|
|
56
|
+
mockFiles({
|
|
57
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
58
|
+
{ folder: '.', actorFullName: 'apify/my-actor', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
59
|
+
]),
|
|
60
|
+
'.actor/actor.json': actorJson({}),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const result = await readConfigFile();
|
|
64
|
+
expect(result[0].folder).toBe('');
|
|
65
|
+
expectFileRead('.actor/actor.json');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('defaults dockerContextDir to actor folder when absent from actor.json', async () => {
|
|
69
|
+
mockFiles({
|
|
70
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
71
|
+
{ folder: 'actors/web-scraper', actorFullName: 'apify/web-scraper', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
72
|
+
]),
|
|
73
|
+
'actors/web-scraper/.actor/actor.json': actorJson({}),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const result = await readConfigFile();
|
|
77
|
+
expect(result[0].dockerContextDir).toBe('actors/web-scraper');
|
|
78
|
+
expect(result[0].contextPaths).toEqual(['actors/web-scraper']);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('resolves dockerContextDir relative to .actor/ folder', async () => {
|
|
82
|
+
mockFiles({
|
|
83
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
84
|
+
{ folder: 'actors/shopify', actorFullName: 'myteam/shopify', tokenEnvVar: 'APIFY_TOKEN' },
|
|
85
|
+
]),
|
|
86
|
+
'actors/shopify/.actor/actor.json': actorJson({ dockerContextDir: '../../..' }),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const result = await readConfigFile();
|
|
90
|
+
expect(result[0].dockerContextDir).toBe('');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('resolves contextPaths from overrideActorContext', async () => {
|
|
94
|
+
mockFiles({
|
|
95
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
96
|
+
{
|
|
97
|
+
folder: 'actors/shopify',
|
|
98
|
+
actorFullName: 'myteam/shopify',
|
|
99
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
100
|
+
overrideActorContext: ['actors/shopify', 'packages'],
|
|
101
|
+
},
|
|
102
|
+
]),
|
|
103
|
+
'actors/shopify/.actor/actor.json': actorJson({ dockerContextDir: '../../..' }),
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const result = await readConfigFile();
|
|
107
|
+
expect(result[0].contextPaths).toEqual(['actors/shopify', 'packages']);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('handles multiple actors', async () => {
|
|
111
|
+
mockFiles({
|
|
112
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
113
|
+
{ folder: 'actors/web-scraper', actorFullName: 'apify/web-scraper', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
114
|
+
{
|
|
115
|
+
folder: 'actors/email-sender',
|
|
116
|
+
actorFullName: 'other-team/email-sender',
|
|
117
|
+
tokenEnvVar: 'APIFY_TOKEN_OTHER_TEAM',
|
|
118
|
+
},
|
|
119
|
+
]),
|
|
120
|
+
'actors/web-scraper/.actor/actor.json': actorJson({}),
|
|
121
|
+
'actors/email-sender/.actor/actor.json': actorJson({}),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const result = await readConfigFile();
|
|
125
|
+
expect(result).toHaveLength(2);
|
|
126
|
+
expect(result[0].actorFullName).toBe('apify/web-scraper');
|
|
127
|
+
expect(result[1].actorFullName).toBe('other-team/email-sender');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('throws when config file is missing', async () => {
|
|
131
|
+
fsMock.readFile.mockRejectedValue(new Error('ENOENT'));
|
|
132
|
+
await expect(readConfigFile()).rejects.toThrow('not found');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('throws when config file contains invalid JSON', async () => {
|
|
136
|
+
fsMock.readFile.mockResolvedValue('{bad json');
|
|
137
|
+
await expect(readConfigFile()).rejects.toThrow('invalid JSON');
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('throws when actors array is missing', async () => {
|
|
141
|
+
fsMock.readFile.mockResolvedValue(JSON.stringify({ notActors: [] }));
|
|
142
|
+
await expect(readConfigFile()).rejects.toThrow('"actors" array');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('throws on duplicate folders', async () => {
|
|
146
|
+
mockFiles({
|
|
147
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
148
|
+
{ folder: 'actors/shopify', actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
149
|
+
{ folder: 'actors/shopify', actorFullName: 'other/shopify', tokenEnvVar: 'APIFY_TOKEN_OTHER' },
|
|
150
|
+
]),
|
|
151
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
await expect(readConfigFile()).rejects.toThrow('Duplicate folder');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('throws on duplicate folders after normalization ("." and "")', async () => {
|
|
158
|
+
mockFiles({
|
|
159
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
160
|
+
{ folder: '.', actorFullName: 'apify/actor-a', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
161
|
+
{ folder: '', actorFullName: 'other/actor-b', tokenEnvVar: 'APIFY_TOKEN_OTHER' },
|
|
162
|
+
]),
|
|
163
|
+
'.actor/actor.json': actorJson({}),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await expect(readConfigFile()).rejects.toThrow('Duplicate folder');
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('throws when actor.json is missing', async () => {
|
|
170
|
+
mockFiles({
|
|
171
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
172
|
+
{ folder: 'actors/shopify', actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
173
|
+
]),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
await expect(readConfigFile()).rejects.toThrow('Cannot read');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('throws when folder is missing', async () => {
|
|
180
|
+
mockFiles({
|
|
181
|
+
[CONFIG_FILE_NAME]: validConfig([{ actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' }]),
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
await expect(readConfigFile()).rejects.toThrow(/Invalid "folder"/);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('throws when folder is not a string', async () => {
|
|
188
|
+
mockFiles({
|
|
189
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
190
|
+
{ folder: 123, actorFullName: 'apify/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
191
|
+
]),
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
await expect(readConfigFile()).rejects.toThrow(/Invalid "folder"/);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('throws when actorFullName is missing', async () => {
|
|
198
|
+
mockFiles({
|
|
199
|
+
[CONFIG_FILE_NAME]: validConfig([{ folder: 'actors/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' }]),
|
|
200
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
await expect(readConfigFile()).rejects.toThrow('Invalid "actorFullName"');
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('throws when actorFullName has no slash', async () => {
|
|
207
|
+
mockFiles({
|
|
208
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
209
|
+
{ folder: 'actors/shopify', actorFullName: 'shopify-scraper', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
210
|
+
]),
|
|
211
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
await expect(readConfigFile()).rejects.toThrow('Invalid "actorFullName"');
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('throws when actorFullName has empty parts', async () => {
|
|
218
|
+
mockFiles({
|
|
219
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
220
|
+
{ folder: 'actors/shopify', actorFullName: '/shopify', tokenEnvVar: 'APIFY_TOKEN_APIFY' },
|
|
221
|
+
]),
|
|
222
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
await expect(readConfigFile()).rejects.toThrow('Invalid "actorFullName"');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('throws when overrideActorContext is not an array', async () => {
|
|
229
|
+
mockFiles({
|
|
230
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
231
|
+
{
|
|
232
|
+
folder: 'actors/shopify',
|
|
233
|
+
actorFullName: 'myteam/shopify',
|
|
234
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
235
|
+
overrideActorContext: 'packages',
|
|
236
|
+
},
|
|
237
|
+
]),
|
|
238
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
await expect(readConfigFile()).rejects.toThrow('Invalid "overrideActorContext"');
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('throws when overrideActorContext contains non-strings', async () => {
|
|
245
|
+
mockFiles({
|
|
246
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
247
|
+
{
|
|
248
|
+
folder: 'actors/shopify',
|
|
249
|
+
actorFullName: 'myteam/shopify',
|
|
250
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
251
|
+
overrideActorContext: [123],
|
|
252
|
+
},
|
|
253
|
+
]),
|
|
254
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
await expect(readConfigFile()).rejects.toThrow('Invalid "overrideActorContext"');
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('throws when overrideActorContext entries overlap (one is a prefix of another)', async () => {
|
|
261
|
+
mockFiles({
|
|
262
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
263
|
+
{
|
|
264
|
+
folder: 'actors/shopify',
|
|
265
|
+
actorFullName: 'myteam/shopify',
|
|
266
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
267
|
+
overrideActorContext: ['actors/shopify', 'actors'],
|
|
268
|
+
},
|
|
269
|
+
]),
|
|
270
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
await expect(readConfigFile()).rejects.toThrow(/overlap/);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('throws when overrideActorContext contains the repo root alongside another entry', async () => {
|
|
277
|
+
mockFiles({
|
|
278
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
279
|
+
{
|
|
280
|
+
folder: 'actors/shopify',
|
|
281
|
+
actorFullName: 'myteam/shopify',
|
|
282
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
283
|
+
overrideActorContext: ['', 'actors/shopify'],
|
|
284
|
+
},
|
|
285
|
+
]),
|
|
286
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
await expect(readConfigFile()).rejects.toThrow(/overlap/);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
it('throws when overrideActorContext does not include the actor own folder', async () => {
|
|
293
|
+
mockFiles({
|
|
294
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
295
|
+
{
|
|
296
|
+
folder: 'actors/shopify',
|
|
297
|
+
actorFullName: 'myteam/shopify',
|
|
298
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
299
|
+
overrideActorContext: ['code', 'shared'],
|
|
300
|
+
},
|
|
301
|
+
]),
|
|
302
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
await expect(readConfigFile()).rejects.toThrow('not reachable through its own context paths');
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('strips trailing slashes from folder and overrideActorContext entries', async () => {
|
|
309
|
+
mockFiles({
|
|
310
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
311
|
+
{
|
|
312
|
+
folder: 'actors/shopify/',
|
|
313
|
+
actorFullName: 'myteam/shopify',
|
|
314
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
315
|
+
overrideActorContext: ['actors/shopify/', 'packages/'],
|
|
316
|
+
},
|
|
317
|
+
]),
|
|
318
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
const result = await readConfigFile();
|
|
322
|
+
expect(result[0].folder).toBe('actors/shopify');
|
|
323
|
+
expect(result[0].contextPaths).toEqual(['actors/shopify', 'packages']);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('allows overrideActorContext with disjoint sibling paths that all reach the actor folder via one entry', async () => {
|
|
327
|
+
mockFiles({
|
|
328
|
+
[CONFIG_FILE_NAME]: validConfig([
|
|
329
|
+
{
|
|
330
|
+
folder: 'actors/shopify',
|
|
331
|
+
actorFullName: 'myteam/shopify',
|
|
332
|
+
tokenEnvVar: 'APIFY_TOKEN',
|
|
333
|
+
overrideActorContext: ['actors/shopify', 'code', 'shared'],
|
|
334
|
+
},
|
|
335
|
+
]),
|
|
336
|
+
'actors/shopify/.actor/actor.json': actorJson({}),
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
const result = await readConfigFile();
|
|
340
|
+
expect(result[0].contextPaths).toEqual(['actors/shopify', 'code', 'shared']);
|
|
341
|
+
});
|
|
342
|
+
});
|
|
@@ -9,19 +9,25 @@ describe('Should build and test parser', () => {
|
|
|
9
9
|
// From https://github.com/apify-store/testing-repo-for-github-actions
|
|
10
10
|
const ACTOR_CONFIGS: ActorConfig[] = [
|
|
11
11
|
{
|
|
12
|
-
|
|
12
|
+
actorFullName: 'lukaskrivka/testing-github-integration-1',
|
|
13
13
|
folder: 'actors/lukaskrivka_testing-github-integration-1',
|
|
14
|
-
|
|
14
|
+
tokenEnvVar: 'APIFY_TOKEN_LUKASKRIVKA',
|
|
15
|
+
dockerContextDir: '',
|
|
16
|
+
contextPaths: [''],
|
|
15
17
|
},
|
|
16
18
|
{
|
|
17
|
-
|
|
19
|
+
actorFullName: 'lukaskrivka/testing-github-integration-2',
|
|
18
20
|
folder: 'actors/lukaskrivka_testing-github-integration-2',
|
|
19
|
-
|
|
21
|
+
tokenEnvVar: 'APIFY_TOKEN_LUKASKRIVKA',
|
|
22
|
+
dockerContextDir: '',
|
|
23
|
+
contextPaths: [''],
|
|
20
24
|
},
|
|
21
25
|
{
|
|
22
|
-
|
|
26
|
+
actorFullName: 'lukaskrivka/test-standalone',
|
|
23
27
|
folder: 'standalone-actors/lukaskrivka_test-standalone',
|
|
24
|
-
|
|
28
|
+
tokenEnvVar: 'APIFY_TOKEN_LUKASKRIVKA',
|
|
29
|
+
dockerContextDir: 'standalone-actors/lukaskrivka_test-standalone',
|
|
30
|
+
contextPaths: ['standalone-actors/lukaskrivka_test-standalone'],
|
|
25
31
|
},
|
|
26
32
|
];
|
|
27
33
|
|
|
@@ -51,7 +57,7 @@ describe('Should build and test parser', () => {
|
|
|
51
57
|
});
|
|
52
58
|
|
|
53
59
|
test('Ignores other ignored files and folders', () => {
|
|
54
|
-
const FILES = ['.vscode/', '.gitignore', '.husky/', '.eslintrc', '.editorconfig'
|
|
60
|
+
const FILES = ['.vscode/', '.gitignore', '.husky/', '.eslintrc', '.editorconfig'];
|
|
55
61
|
|
|
56
62
|
const actorsChanged = getChangedActors({
|
|
57
63
|
actorConfigs: ACTOR_CONFIGS,
|
|
@@ -63,9 +69,42 @@ describe('Should build and test parser', () => {
|
|
|
63
69
|
expect(actorsChanged).toEqual([]);
|
|
64
70
|
});
|
|
65
71
|
|
|
66
|
-
test('
|
|
72
|
+
test('.actor/ changes trigger builds for broad-context actors', () => {
|
|
73
|
+
const FILES = ['.actor/actor.json'];
|
|
74
|
+
|
|
75
|
+
const actorsChanged = getChangedActors({
|
|
76
|
+
actorConfigs: ACTOR_CONFIGS,
|
|
77
|
+
isLatest: false,
|
|
78
|
+
filepathsChanged: FILES,
|
|
79
|
+
commits,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
expect(actorsChanged).toEqual(ACTOR_CONFIGS.slice(0, 2));
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('Root-level changelog is cosmetic for every actor, only on latest', () => {
|
|
67
86
|
const FILES = ['shared/CHANGELOG.md', 'CHANGELOG.md'];
|
|
68
87
|
|
|
88
|
+
const actorsChangedNotLatest = getChangedActors({
|
|
89
|
+
actorConfigs: ACTOR_CONFIGS,
|
|
90
|
+
isLatest: false,
|
|
91
|
+
filepathsChanged: FILES,
|
|
92
|
+
commits,
|
|
93
|
+
});
|
|
94
|
+
expect(actorsChangedNotLatest).toEqual([]);
|
|
95
|
+
|
|
96
|
+
const actorsChangedLatest = getChangedActors({
|
|
97
|
+
actorConfigs: ACTOR_CONFIGS,
|
|
98
|
+
isLatest: true,
|
|
99
|
+
filepathsChanged: FILES,
|
|
100
|
+
commits,
|
|
101
|
+
});
|
|
102
|
+
expect(actorsChangedLatest).toEqual(ACTOR_CONFIGS);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('A changelog nested inside one actor own folder is excluded for sibling actors, only triggers that actor', () => {
|
|
106
|
+
const FILES = ['actors/lukaskrivka_testing-github-integration-1/CHANGELOG.md'];
|
|
107
|
+
|
|
69
108
|
const actorsChanged = getChangedActors({
|
|
70
109
|
actorConfigs: ACTOR_CONFIGS,
|
|
71
110
|
isLatest: true,
|
|
@@ -73,10 +112,10 @@ describe('Should build and test parser', () => {
|
|
|
73
112
|
commits,
|
|
74
113
|
});
|
|
75
114
|
|
|
76
|
-
expect(actorsChanged).toEqual(ACTOR_CONFIGS
|
|
115
|
+
expect(actorsChanged).toEqual([ACTOR_CONFIGS[0]]);
|
|
77
116
|
});
|
|
78
117
|
|
|
79
|
-
test('Code updated, tests
|
|
118
|
+
test('Code updated, tests broad-context actors', () => {
|
|
80
119
|
const FILES = ['code/src/main.ts', 'package.json'];
|
|
81
120
|
|
|
82
121
|
const actorsChanged = getChangedActors({
|
|
@@ -86,7 +125,7 @@ describe('Should build and test parser', () => {
|
|
|
86
125
|
commits,
|
|
87
126
|
});
|
|
88
127
|
|
|
89
|
-
expect(actorsChanged).toEqual(ACTOR_CONFIGS.
|
|
128
|
+
expect(actorsChanged).toEqual(ACTOR_CONFIGS.slice(0, 2));
|
|
90
129
|
});
|
|
91
130
|
|
|
92
131
|
test('Specific Actor functionality configs updated', () => {
|
|
@@ -119,7 +158,7 @@ describe('Should build and test parser', () => {
|
|
|
119
158
|
expect(actorsChanged).toEqual(ACTOR_CONFIGS.slice(0, 2));
|
|
120
159
|
});
|
|
121
160
|
|
|
122
|
-
test('
|
|
161
|
+
test('Actor folder, shared code and narrow-context actor updated', () => {
|
|
123
162
|
const FILES = [
|
|
124
163
|
'actors/lukaskrivka_testing-github-integration-1/.actor/actor.json',
|
|
125
164
|
'code/src/main.ts',
|
|
@@ -216,7 +255,7 @@ describe('Should build and test parser', () => {
|
|
|
216
255
|
expect(actorsChanged).toEqual([ACTOR_CONFIGS[1]]);
|
|
217
256
|
});
|
|
218
257
|
|
|
219
|
-
test('
|
|
258
|
+
test('Narrow-context actor with cosmetic-only JSON change in PR context skips tests', () => {
|
|
220
259
|
const FILES = ['standalone-actors/lukaskrivka_test-standalone/.actor/actor.json'];
|
|
221
260
|
isCosmeticOnlyJsonSchemaSpy.mockReturnValue(true);
|
|
222
261
|
|
|
@@ -249,49 +288,67 @@ describe('Should build and test parser', () => {
|
|
|
249
288
|
const ACTOR_CONFIGS_GOOGLE_MAPS: ActorConfig[] = [
|
|
250
289
|
{
|
|
251
290
|
// Edge case of capitals in actor name :)
|
|
252
|
-
|
|
291
|
+
actorFullName: 'compass/Google-Maps-Reviews-Scraper',
|
|
253
292
|
folder: 'actors/compass_Google-Maps-Reviews-Scraper',
|
|
254
|
-
|
|
293
|
+
tokenEnvVar: 'APIFY_TOKEN_COMPASS',
|
|
294
|
+
dockerContextDir: '',
|
|
295
|
+
contextPaths: [''],
|
|
255
296
|
},
|
|
256
297
|
{
|
|
257
|
-
|
|
298
|
+
actorFullName: 'compass/crawler-google-places',
|
|
258
299
|
folder: 'actors/compass_crawler-google-places',
|
|
259
|
-
|
|
300
|
+
tokenEnvVar: 'APIFY_TOKEN_COMPASS',
|
|
301
|
+
dockerContextDir: '',
|
|
302
|
+
contextPaths: [''],
|
|
260
303
|
},
|
|
261
304
|
{
|
|
262
|
-
|
|
305
|
+
actorFullName: 'compass/easy-google-maps',
|
|
263
306
|
folder: 'actors/compass_easy-google-maps',
|
|
264
|
-
|
|
307
|
+
tokenEnvVar: 'APIFY_TOKEN_COMPASS',
|
|
308
|
+
dockerContextDir: '',
|
|
309
|
+
contextPaths: [''],
|
|
265
310
|
},
|
|
266
311
|
{
|
|
267
|
-
|
|
312
|
+
actorFullName: 'compass/google-maps-extractor',
|
|
268
313
|
folder: 'actors/compass_google-maps-extractor',
|
|
269
|
-
|
|
314
|
+
tokenEnvVar: 'APIFY_TOKEN_COMPASS',
|
|
315
|
+
dockerContextDir: '',
|
|
316
|
+
contextPaths: [''],
|
|
270
317
|
},
|
|
271
318
|
{
|
|
272
|
-
|
|
319
|
+
actorFullName: 'compass/google-places-api',
|
|
273
320
|
folder: 'actors/compass_google-places-api',
|
|
274
|
-
|
|
321
|
+
tokenEnvVar: 'APIFY_TOKEN_COMPASS',
|
|
322
|
+
dockerContextDir: '',
|
|
323
|
+
contextPaths: [''],
|
|
275
324
|
},
|
|
276
325
|
{
|
|
277
|
-
|
|
326
|
+
actorFullName: 'lukaskrivka/google-maps-with-contact-details',
|
|
278
327
|
folder: 'actors/lukaskrivka_google-maps-with-contact-details',
|
|
279
|
-
|
|
328
|
+
tokenEnvVar: 'APIFY_TOKEN_LUKASKRIVKA',
|
|
329
|
+
dockerContextDir: '',
|
|
330
|
+
contextPaths: [''],
|
|
280
331
|
},
|
|
281
332
|
{
|
|
282
|
-
|
|
333
|
+
actorFullName: 'natasha.lekh/gas-prices-scraper',
|
|
283
334
|
folder: 'actors/natasha.lekh_gas-prices-scraper',
|
|
284
|
-
|
|
335
|
+
tokenEnvVar: 'APIFY_TOKEN_NATASHA_LEKH',
|
|
336
|
+
dockerContextDir: '',
|
|
337
|
+
contextPaths: [''],
|
|
285
338
|
},
|
|
286
339
|
{
|
|
287
|
-
|
|
340
|
+
actorFullName: 'natasha.lekh/vegan-places-finder',
|
|
288
341
|
folder: 'actors/natasha.lekh_vegan-places-finder',
|
|
289
|
-
|
|
342
|
+
tokenEnvVar: 'APIFY_TOKEN_NATASHA_LEKH',
|
|
343
|
+
dockerContextDir: '',
|
|
344
|
+
contextPaths: [''],
|
|
290
345
|
},
|
|
291
346
|
{
|
|
292
|
-
|
|
347
|
+
actorFullName: 'lukaskrivka/google-maps-scraper-orchestrator',
|
|
293
348
|
folder: 'standalone-actors/lukaskrivka_google-maps-scraper-orchestrator',
|
|
294
|
-
|
|
349
|
+
tokenEnvVar: 'APIFY_TOKEN_LUKASKRIVKA',
|
|
350
|
+
dockerContextDir: 'standalone-actors/lukaskrivka_google-maps-scraper-orchestrator',
|
|
351
|
+
contextPaths: ['standalone-actors/lukaskrivka_google-maps-scraper-orchestrator'],
|
|
295
352
|
},
|
|
296
353
|
];
|
|
297
354
|
|
|
@@ -302,6 +359,6 @@ describe('Should build and test parser', () => {
|
|
|
302
359
|
commits,
|
|
303
360
|
});
|
|
304
361
|
|
|
305
|
-
expect(actorsChanged).toEqual(ACTOR_CONFIGS_GOOGLE_MAPS.
|
|
362
|
+
expect(actorsChanged).toEqual(ACTOR_CONFIGS_GOOGLE_MAPS.slice(0, 8));
|
|
306
363
|
});
|
|
307
364
|
});
|