apify-test-tools 0.10.2-beta.7 → 0.10.2-beta.8

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.
@@ -1,68 +1,55 @@
1
+ /** Items fetched per request, so no single response can exceed Node's string limit on large datasets. */
2
+ const DATASET_PAGE_SIZE = 1000;
3
+ /**
4
+ * Runs `fn` at most once and shares its promise, so repeated and concurrent calls are one request.
5
+ * A failure is not cached, the next call retries.
6
+ */
7
+ const once = (fn) => {
8
+ let promise;
9
+ return async () => {
10
+ promise ??= fn().catch((error) => {
11
+ promise = undefined;
12
+ throw error;
13
+ });
14
+ return promise;
15
+ };
16
+ };
1
17
  export class RunTestResult {
2
18
  apifyClient;
3
19
  run;
4
- log;
5
- dataset;
6
- keyValueStoreClient;
7
- statistics;
8
- runInfo;
9
- input;
10
20
  constructor(apifyClient, run) {
11
21
  this.apifyClient = apifyClient;
12
22
  this.run = run;
13
23
  /**/
14
24
  }
15
- getStatistics = async () => {
16
- if (this.statistics) {
17
- return this.statistics;
18
- }
19
- const kvs = this.apifyClient.keyValueStore(this.run.defaultKeyValueStoreId);
20
- const stats = await kvs.getRecord('SDK_CRAWLER_STATISTICS_0');
21
- this.statistics = stats?.value;
22
- return this.statistics;
23
- };
24
- getLog = async () => {
25
- if (this.log) {
26
- return this.log;
27
- }
28
- const runLog = await this.apifyClient.run(this.id).log().get();
29
- this.log = runLog;
30
- return runLog;
31
- };
32
- getDataset = async () => {
33
- if (this.dataset) {
34
- return this.dataset;
35
- }
25
+ getStatistics = once(async () => {
26
+ const record = await this.getKeyValueStoreClient().getRecord('SDK_CRAWLER_STATISTICS_0');
27
+ return record?.value;
28
+ });
29
+ getLog = once(async () => {
30
+ return (await this.apifyClient.run(this.id).log().get());
31
+ });
32
+ datasetItems = once(async () => {
36
33
  const dataset = this.apifyClient.dataset(this.run.defaultDatasetId);
37
- const items = (await dataset.listItems()).items;
38
- this.dataset = { items };
39
- return this.dataset;
40
- };
41
- getKeyValueStoreClient = () => {
42
- if (this.keyValueStoreClient) {
43
- return this.keyValueStoreClient;
44
- }
45
- const keyValueStoreClient = this.apifyClient.keyValueStore(this.run.defaultKeyValueStoreId);
46
- this.keyValueStoreClient = keyValueStoreClient;
47
- return keyValueStoreClient;
48
- };
49
- getInput = async () => {
50
- if (this.input) {
51
- return this.input;
34
+ const items = [];
35
+ for (;;) {
36
+ const page = await dataset.listItems({ offset: items.length, limit: DATASET_PAGE_SIZE });
37
+ items.push(...page.items);
38
+ if (page.items.length === 0 || items.length >= page.total) {
39
+ return items;
40
+ }
52
41
  }
53
- const kvs = this.apifyClient.keyValueStore(this.run.defaultKeyValueStoreId);
54
- const input = await kvs.getRecord('INPUT');
55
- this.input = input?.value;
56
- return this.input;
57
- };
58
- getRunInfo = async () => {
59
- if (this.runInfo) {
60
- return this.runInfo;
61
- }
62
- const run = this.apifyClient.run(this.run.id);
63
- this.runInfo = await run.get();
64
- return this.runInfo;
42
+ });
43
+ getDataset = async () => ({ items: (await this.datasetItems()) });
44
+ getKeyValueStoreClient = () => {
45
+ return this.apifyClient.keyValueStore(this.run.defaultKeyValueStoreId);
65
46
  };
47
+ inputRecord = once(async () => (await this.getKeyValueStoreClient().getRecord('INPUT'))?.value);
48
+ getInput = async () => (await this.inputRecord());
49
+ /** Fetches the run again, so unlike `id` and `status` it also reflects what changed after the run finished. */
50
+ getRunInfo = once(async () => {
51
+ return (await this.apifyClient.run(this.run.id).get());
52
+ });
66
53
  get id() {
67
54
  return this.run.id;
68
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"run-test-result.js","sourceRoot":"","sources":["../../lib/run-test-result.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-test-result.js","sourceRoot":"","sources":["../../lib/run-test-result.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=run-checks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-checks.test.d.ts","sourceRoot":"","sources":["../../../test/unit/run-checks.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { checkRun } from '../../lib/run-checks.js';
3
+ const fakeRun = (overrides = {}) => ({
4
+ status: overrides.status ?? 'SUCCEEDED',
5
+ getRunInfo: async () => ({
6
+ stats: { durationMillis: 5_000 },
7
+ chargedEventCounts: overrides.chargedEventCounts,
8
+ }),
9
+ getDataset: async () => ({ items: new Array(10) }),
10
+ getStatistics: async () => ({
11
+ requestsFailed: 0,
12
+ requestsRetries: 1,
13
+ requestRetryHistogram: [5, 1],
14
+ ...overrides.stats,
15
+ }),
16
+ getLog: async () => overrides.log ?? 'all good',
17
+ });
18
+ const failures = async (run, options) => (await checkRun(run, options)).filter(({ pass }) => !pass).map(({ name }) => name);
19
+ describe('checkRun()', () => {
20
+ it('passes a run matching the defaults', async () => {
21
+ expect(await failures(fakeRun(), { datasetItemCount: 10 })).toEqual([]);
22
+ });
23
+ it('reports every failing check at once', async () => {
24
+ const run = fakeRun({ status: 'FAILED', log: 'TypeError: x', stats: { requestsFailed: 2 } });
25
+ expect(await failures(run, { datasetItemCount: { min: 11 } })).toEqual([
26
+ 'status',
27
+ 'datasetItemCount',
28
+ 'failedRequests',
29
+ 'forbiddenLogs',
30
+ ]);
31
+ });
32
+ it('disables a check with null', async () => {
33
+ const run = fakeRun({ stats: { requestsFailed: 2 } });
34
+ expect(await failures(run, { datasetItemCount: 10, failedRequests: null })).toEqual([]);
35
+ });
36
+ it('treats explicitly undefined options as disabled checks', async () => {
37
+ const options = { datasetItemCount: 10, duration: undefined, maxRetriesPerRequest: undefined };
38
+ expect(await failures(fakeRun(), options)).toEqual([]);
39
+ });
40
+ it('checks the longest retry chain only when asked to', async () => {
41
+ expect(await failures(fakeRun(), { datasetItemCount: 10, maxRetriesPerRequest: 0 })).toEqual([
42
+ 'maxRetriesPerRequest',
43
+ ]);
44
+ expect(await failures(fakeRun(), { datasetItemCount: 10, maxRetriesPerRequest: 1 })).toEqual([]);
45
+ });
46
+ describe('chargedEventCounts', () => {
47
+ const run = fakeRun({ chargedEventCounts: { start: 1, item: 7 } });
48
+ it('passes matching counts and intervals', async () => {
49
+ const options = { datasetItemCount: 10, chargedEventCounts: { start: 1, item: { min: 5 } } };
50
+ expect(await failures(run, options)).toEqual([]);
51
+ });
52
+ it('expects unlisted charged events to not happen', async () => {
53
+ const options = { datasetItemCount: 10, chargedEventCounts: { start: 1 } };
54
+ expect(await failures(run, options)).toEqual(['chargedEventCounts.item']);
55
+ });
56
+ it('fails an expected event that was never charged', async () => {
57
+ const options = { datasetItemCount: 10, chargedEventCounts: { start: 1, item: 7, extra: { min: 0 } } };
58
+ expect(await failures(run, options)).toEqual(['chargedEventCounts.extra']);
59
+ });
60
+ });
61
+ });
62
+ //# sourceMappingURL=run-checks.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-checks.test.js","sourceRoot":"","sources":["../../../test/unit/run-checks.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=run-test-result.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-test-result.test.d.ts","sourceRoot":"","sources":["../../../test/unit/run-test-result.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { RunTestResult } from '../../lib/run-test-result.js';
3
+ const run = { id: 'run', status: 'SUCCEEDED', defaultDatasetId: 'ds', defaultKeyValueStoreId: 'kvs' };
4
+ describe('RunTestResult', () => {
5
+ it('fetches the log once, even when empty or requested concurrently', async () => {
6
+ const get = vi.fn(async () => '');
7
+ const client = { run: () => ({ log: () => ({ get }) }) };
8
+ const result = new RunTestResult(client, run);
9
+ await Promise.all([result.getLog(), result.getLog()]);
10
+ await result.getLog();
11
+ expect(get).toHaveBeenCalledTimes(1);
12
+ });
13
+ it('retries after a failed fetch', async () => {
14
+ const get = vi.fn().mockRejectedValueOnce(new Error('boom')).mockResolvedValueOnce('log');
15
+ const client = { run: () => ({ log: () => ({ get }) }) };
16
+ const result = new RunTestResult(client, run);
17
+ await expect(result.getLog()).rejects.toThrow('boom');
18
+ expect(await result.getLog()).toBe('log');
19
+ });
20
+ it('pages through the dataset instead of listing it in one response', async () => {
21
+ const total = 25_000;
22
+ const listItems = vi.fn(async ({ offset, limit }) => ({
23
+ total,
24
+ items: Array.from({ length: Math.min(limit, total - offset) }, (_, i) => offset + i),
25
+ }));
26
+ const client = { dataset: () => ({ listItems }) };
27
+ const result = new RunTestResult(client, run);
28
+ const { items } = await result.getDataset();
29
+ expect(items).toHaveLength(total);
30
+ expect(items[24_999]).toBe(24_999);
31
+ expect(listItems).toHaveBeenCalledTimes(25);
32
+ });
33
+ });
34
+ //# sourceMappingURL=run-test-result.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-test-result.test.js","sourceRoot":"","sources":["../../../test/unit/run-test-result.test.ts"],"names":[],"mappings":"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"}