-
Notifications
You must be signed in to change notification settings - Fork 55
/
interfaces.ts
601 lines (526 loc) · 14.2 KB
/
interfaces.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
import {Metadata} from '../../helpers/interfaces'
import {ProxyConfiguration} from '../../helpers/utils'
import {TunnelInfo} from './tunnel'
export type SupportedReporter = 'junit' | 'default'
export interface MainReporter {
log(log: string): void
error(error: string): void
initErrors(errors: string[]): void
testTrigger(test: Test, testId: string, executionRule: ExecutionRule, config: UserConfigOverride): void
testWait(test: Test): void
testsWait(tests: Test[], baseUrl: string, batchId: string, skippedCount?: number): void
resultReceived(result: ResultInBatch): void
resultEnd(result: Result, baseUrl: string, batchId: string): void
reportStart(timings: {startTime: number}): void
runEnd(summary: Summary, baseUrl: string, orgSettings?: SyntheticsOrgSettings): void
}
export type Reporter = Partial<MainReporter>
export interface BaseServerResult {
failure?: {
code: string
message: string
}
passed: boolean
unhealthy?: boolean
}
export interface Device {
height: number
id: string
width: number
}
export interface BrowserServerResult extends BaseServerResult {
device?: Device
duration: number
startUrl: string
stepDetails: Step[]
}
interface AssertionResult {
actual: any
expected?: any
valid: boolean
}
export interface ApiServerResult extends BaseServerResult {
assertionResults: AssertionResult[]
timings: {
total: number
}
}
export interface MultiStep {
allowFailure: boolean
assertionResults: AssertionResult[]
failure?: {
code: string
message: string
}
name: string
passed: boolean
skipped: boolean
subtype: string
timings: {
total: number
}
}
export interface MultiStepsServerResult extends BaseServerResult {
duration: number
steps: MultiStep[]
}
export type ServerResult = BrowserServerResult | ApiServerResult | MultiStepsServerResult
export interface PollResult {
check: Pick<Test, 'config' | 'subtype' | 'type'>
result: ServerResult
resultID: string
timestamp: number
}
export type PollResultMap = {[resultId: string]: PollResult}
/**
* Information required to convert a `PollResult` to a `Result`.
*/
export type ResultDisplayInfo = {
getLocation: (datacenterId: string, test: Test) => string
options: {
batchTimeout: number
datadogSite: string
failOnCriticalErrors?: boolean
failOnTimeout?: boolean
subdomain: string
}
tests: Test[]
}
export type SelectiveRerunDecision =
| {
decision: 'run'
reason: 'in_progress'
}
| {
decision: 'run'
reason: 'failed'
linked_result_id: string
}
| {
decision: 'run'
reason: 'edited'
}
| {
decision: 'run'
reason: 'new'
}
| {
decision: 'skip'
reason: 'passed'
linked_result_id: string
}
export interface BaseResult {
executionRule: ExecutionRule
initialResultId?: string
/** Whether the result is an intermediary result that is expected to be retried. */
isNonFinal?: boolean
location: string
/** Whether the result is passed or not, according to `failOnCriticalErrors` and `failOnTimeout`. */
passed: boolean
result: ServerResult
resultId: string
/** Number of retries, including this result. */
retries: number
maxRetries: number
selectiveRerun?: SelectiveRerunDecision
/** Original test for this result, including overrides if any. */
test: Test
timedOut: boolean
timestamp: number
}
// Inside this type, `.resultId` is a linked result ID from a previous batch.
export type ResultSkippedBySelectiveRerun = Omit<
BaseResult,
'location' | 'result' | 'retries' | 'maxRetries' | 'timestamp'
> & {
executionRule: ExecutionRule.SKIPPED
selectiveRerun: Extract<SelectiveRerunDecision, {decision: 'skip'}>
}
export type Result = BaseResult | ResultSkippedBySelectiveRerun
type Status = 'passed' | 'failed' | 'in_progress' | 'skipped'
type BatchStatus = 'passed' | 'failed' | 'in_progress'
export interface BaseResultInBatch {
execution_rule: ExecutionRule
initial_result_id?: string
location: string
result_id: string
retries: number | null
max_retries: number | null
selective_rerun?: SelectiveRerunDecision
status: Status
test_public_id: string
timed_out: boolean | null
}
type SkippedResultInBatch = Omit<BaseResultInBatch, 'location' | 'result_id'> & {
execution_rule: ExecutionRule.SKIPPED
status: 'skipped'
}
export type ResultInBatchSkippedBySelectiveRerun = SkippedResultInBatch & {
selective_rerun: Extract<SelectiveRerunDecision, {decision: 'skip'}>
}
export type ResultInBatch = BaseResultInBatch | ResultInBatchSkippedBySelectiveRerun
export interface Batch {
results: ResultInBatch[]
status: BatchStatus
}
type ServerResultInBatch = BaseResultInBatch | SkippedResultInBatch
export interface ServerBatch {
// The batch from the server contains skipped results, which we're going to remove since we don't
// care about skipped results internally (except when they are skipped by a selective re-run).
results: ServerResultInBatch[]
status: BatchStatus
}
export interface Vitals {
cls?: number
lcp?: number
url: string
}
export interface BrowserError {
description: string
name: string
type: string
}
export interface Step {
allowFailure: boolean
browserErrors: BrowserError[]
description: string
duration: number
error?: string
publicId?: string
skipped: boolean
stepId: number
subTestPublicId?: string
subTestStepDetails?: Step[]
type: string
url: string
value?: string | number
vitalsMetrics: Vitals[]
warnings?: {
message: string
type: string
}[]
}
export interface ServerTest {
config: {
assertions: Assertion[]
request: {
dnsServer?: string
headers: {[key: string]: string}
host?: string
method: string
port?: number
timeout: number
url: string
}
steps?: {subtype: string}[]
variables: string[]
}
created_at: string
created_by: User
locations: string[]
message: string
modified_at: string
modified_by: User
monitor_id: number
name: string
options: {
ci?: {
executionRule: ExecutionRule
}
device_ids?: string[]
min_failure_duration: number
min_location_failed: number
mobileApplication?: MobileApplication
tick_every: number
retry?: {
count?: number
}
}
overall_state: number
overall_state_modified: string
public_id: string
status: string
stepCount: number
subtype: string
tags: string[]
type: string
}
export interface Test extends ServerTest {
suite?: string
}
export interface Assertion {
actual: string | number | Date | {[key: string]: any}
errorMessage?: string
operator: Operator
property?: string
target: string | number | Date | {[key: string]: any}
type: string
valid: boolean
}
export enum Operator {
contains = 'contains',
doesNotContain = 'doesNotContain',
is = 'is',
isNot = 'isNot',
isInLessThan = 'isInLessThan',
isInMoreThan = 'isInMoreThan',
lessThan = 'lessThan',
lessThanOrEqual = 'lessThanOrEqual',
moreThan = 'moreThan',
moreThanOrEqual = 'moreThanOrEqual',
matches = 'matches',
doesNotMatch = 'doesNotMatch',
validatesJSONPath = 'validatesJSONPath',
validatesXPath = 'validatesXPath',
}
export interface User {
email: string
handle: string
id: number
name: string
}
export interface Location {
display_name: string
id: number
is_active: boolean
name: string
region: string
}
export interface LocationsMapping {
[key: string]: string
}
export interface Trigger {
batch_id: string
locations: Location[]
selective_rerun_rate_limited?: boolean
}
export interface RetryConfig {
count: number
interval: number
}
export interface MobileApplication {
applicationId: string
referenceId: string
referenceType: 'latest' | 'version' | 'temporary'
}
export interface CookiesObject {
append?: boolean
value: string
}
export interface BaseConfigOverride {
allowInsecureCertificates?: boolean
basicAuth?: BasicAuthCredentials
body?: string
bodyType?: string
cookies?: string | CookiesObject
setCookies?: string | CookiesObject
defaultStepTimeout?: number
deviceIds?: string[]
executionRule?: ExecutionRule
followRedirects?: boolean
headers?: {[key: string]: string}
locations?: string[]
// TODO SYNTH-12989: Clean up deprecated `pollingTimeout` in favor of `batchTimeout`
/** @deprecated This property is deprecated, please use `batchTimeout` in the global configuration file or `--batchTimeout` instead. */
pollingTimeout?: number
resourceUrlSubstitutionRegexes?: string[]
retry?: RetryConfig
startUrl?: string
startUrlSubstitutionRegex?: string
testTimeout?: number
tunnel?: TunnelInfo
variables?: {[key: string]: string}
}
export interface UserConfigOverride extends BaseConfigOverride {
mobileApplicationVersion?: string
mobileApplicationVersionFilePath?: string
}
export interface ServerConfigOverride extends BaseConfigOverride {
mobileApplication?: MobileApplication
appExtractedMetadata?: MobileAppExtractedMetadata
}
export interface BatchOptions {
batch_timeout?: number
selective_rerun?: boolean
}
export interface Payload {
metadata?: Metadata
tests: TestPayload[]
options?: BatchOptions
}
export interface TestPayload extends ServerConfigOverride {
executionRule?: ExecutionRule
public_id: string
}
export interface TestNotFound {
errorMessage: string
}
export interface TestSkipped {
overriddenConfig: TestPayload
}
export interface TestWithOverride {
test: Test
overriddenConfig: TestPayload
}
export interface MobileTestWithOverride extends TestWithOverride {
test: Test & {
type: 'mobile'
options: {
mobileApplication: MobileApplication
}
}
}
export interface BasicAuthCredentials {
password: string
username: string
}
export interface TriggerConfig {
// TODO SYNTH-12989: Clean up deprecated `config` in favor of `testOverrides`
/** @deprecated This property is deprecated, please use `testOverrides` instead. */
config?: UserConfigOverride
testOverrides?: UserConfigOverride
id: string
suite?: string
}
export enum ExecutionRule {
BLOCKING = 'blocking',
NON_BLOCKING = 'non_blocking',
SKIPPED = 'skipped',
}
export interface Suite {
content: {
tests: TriggerConfig[]
}
name?: string
}
export interface Summary {
// The batchId is associated to a full run of datadog-ci: multiple suites will be in the same batch.
batchId: string
criticalErrors: number
// Number of results expected by datadog-ci, prior to any selective re-run.
expected: number
failed: number
failedNonBlocking: number
passed: number
previouslyPassed: number
skipped: number
testsNotFound: Set<string>
timedOut: number
}
export interface TestSearchResult {
tests: {
public_id: string
}[]
}
export interface APIConfiguration {
apiKey: string
appKey: string
baseIntakeUrl: string
baseUnstableUrl: string
baseUrl: string
proxyOpts: ProxyConfiguration
}
export interface APIHelperConfig {
apiKey: string
appKey: string
datadogSite: string
proxy: ProxyConfiguration
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface SyntheticsCIConfig extends APIHelperConfig {}
export interface RunTestsCommandConfig extends SyntheticsCIConfig {
batchTimeout?: number
configPath: string
defaultTestOverrides?: UserConfigOverride
failOnCriticalErrors: boolean
failOnMissingTests: boolean
failOnTimeout: boolean
files: string[]
// TODO SYNTH-12989: Clean up deprecated `global` in favor of `defaultTestOverrides`
/** @deprecated This property is deprecated, please use `defaultTestOverrides` instead. */
global?: UserConfigOverride
jUnitReport?: string
// TODO SYNTH-12989: Clean up `locations` that should only be part of test overrides
/** @deprecated This property should only be used inside of `defaultTestOverrides` or `testOverrides`. */
locations?: string[]
mobileApplicationVersionFilePath?: string
// TODO SYNTH-12989: Clean up deprecated `pollingTimeout` in favor of `batchTimeout`
/** @deprecated This property is deprecated, please use `batchTimeout` in the global configuration file or `--batchTimeout` instead. */
pollingTimeout?: number
publicIds: string[]
selectiveRerun: boolean
subdomain: string
testSearchQuery?: string
tunnel: boolean
// TODO SYNTH-12989: Clean up deprecated `variableStrings` in favor of `variables` in `defaultTestOverrides`.
/** @deprecated This property is deprecated, please use `variables` inside of `defaultTestOverrides`. */
variableStrings: string[]
}
export type WrapperConfig = Partial<RunTestsCommandConfig>
export interface UploadApplicationCommandConfig extends SyntheticsCIConfig {
configPath: string
mobileApplicationVersionFilePath?: string
mobileApplicationId?: string
versionName?: string
latest?: boolean
}
export interface MobileApplicationUploadPart {
partNumber: number
md5: string
blob: Buffer
}
export interface MobileApplicationUploadPartResponse {
PartNumber: number
ETag: string
}
export interface MultipartPresignedUrlsResponse {
file_name: string
multipart_presigned_urls_params: {
key: string
upload_id: string
urls: {
[key: string]: string
}
}
}
export type MobileApplicationNewVersionParams = {
originalFileName: string
versionName: string
isLatest: boolean
}
export type AppUploadDetails = {appId: string; appPath: string; versionName?: string}
type MobileAppValidationStatus = 'pending' | 'complete' | 'error' | 'user_error'
type MobileInvalidAppResult = {
invalid_reason: string
invalid_message: string
}
export type MobileAppExtractedMetadata = Record<string, unknown>
type MobileValidAppResult = {
extracted_metadata: MobileAppExtractedMetadata
app_version_uuid: string
}
type MobileUserErrorResult = {
user_error_reason: string
user_error_message: string
}
export type MobileAppUploadResult = {
status: MobileAppValidationStatus
is_valid?: boolean
org_uuid?: string
invalid_app_result?: MobileInvalidAppResult
valid_app_result?: MobileValidAppResult
user_error_result?: MobileUserErrorResult
}
// Not the entire response, but only what's needed.
export interface SyntheticsOrgSettings {
onDemandConcurrencyCap: number
}
export interface MobileApplicationVersion {
id?: string
application_id: string
file_name: string
original_file_name: string
is_latest: boolean
version_name: string
created_at?: string
}