| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright Microsoft Corporation. All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  | import type { FixturePool } from './fixtures'; | 
					
						
							| 
									
										
										
										
											2022-04-06 13:57:14 -08:00
										 |  |  | import type * as reporterTypes from '../types/testReporter'; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | import type { TestTypeImpl } from './testType'; | 
					
						
							| 
									
										
										
										
											2022-04-06 13:57:14 -08:00
										 |  |  | import type { Annotation, FixturesWithLocation, FullProject, FullProjectInternal, Location } from './types'; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Base { | 
					
						
							|  |  |  |   title: string; | 
					
						
							|  |  |  |   _only = false; | 
					
						
							| 
									
										
										
										
											2021-06-21 11:25:15 -07:00
										 |  |  |   _requireFile: string = ''; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   constructor(title: string) { | 
					
						
							|  |  |  |     this.title = title; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-02 15:49:05 -07:00
										 |  |  | export type Modifier = { | 
					
						
							|  |  |  |   type: 'slow' | 'fixme' | 'skip' | 'fail', | 
					
						
							|  |  |  |   fn: Function, | 
					
						
							|  |  |  |   location: Location, | 
					
						
							|  |  |  |   description: string | undefined | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | export class Suite extends Base implements reporterTypes.Suite { | 
					
						
							|  |  |  |   suites: Suite[] = []; | 
					
						
							| 
									
										
										
										
											2021-07-19 14:54:18 -07:00
										 |  |  |   tests: TestCase[] = []; | 
					
						
							| 
									
										
										
										
											2021-07-18 17:40:59 -07:00
										 |  |  |   location?: Location; | 
					
						
							| 
									
										
										
										
											2021-10-19 08:38:04 -07:00
										 |  |  |   parent?: Suite; | 
					
						
							| 
									
										
										
										
											2021-08-10 16:32:32 -07:00
										 |  |  |   _use: FixturesWithLocation[] = []; | 
					
						
							| 
									
										
										
										
											2022-03-18 16:07:11 -07:00
										 |  |  |   _skipped = false; | 
					
						
							| 
									
										
										
										
											2021-07-19 14:54:18 -07:00
										 |  |  |   _entries: (Suite | TestCase)[] = []; | 
					
						
							| 
									
										
										
										
											2022-03-08 16:35:14 -08:00
										 |  |  |   _hooks: { type: 'beforeEach' | 'afterEach' | 'beforeAll' | 'afterAll', fn: Function, location: Location }[] = []; | 
					
						
							| 
									
										
										
										
											2021-06-29 13:33:13 -07:00
										 |  |  |   _timeout: number | undefined; | 
					
						
							| 
									
										
										
										
											2022-03-08 16:35:14 -08:00
										 |  |  |   _annotations: Annotation[] = []; | 
					
						
							| 
									
										
										
										
											2021-07-02 15:49:05 -07:00
										 |  |  |   _modifiers: Modifier[] = []; | 
					
						
							| 
									
										
										
										
											2021-09-02 15:42:07 -07:00
										 |  |  |   _parallelMode: 'default' | 'serial' | 'parallel' = 'default'; | 
					
						
							| 
									
										
										
										
											2022-04-04 16:07:04 -07:00
										 |  |  |   _projectConfig: FullProjectInternal | undefined; | 
					
						
							| 
									
										
										
										
											2022-02-01 15:34:16 -08:00
										 |  |  |   _loadError?: reporterTypes.TestError; | 
					
						
							| 
									
										
										
										
											2022-07-27 20:17:19 -07:00
										 |  |  |   _fileId: string | undefined; | 
					
						
							|  |  |  |   readonly _type: 'root' | 'project' | 'file' | 'describe'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor(title: string, type: 'root' | 'project' | 'file' | 'describe') { | 
					
						
							|  |  |  |     super(title); | 
					
						
							|  |  |  |     this._type = type; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 14:54:18 -07:00
										 |  |  |   _addTest(test: TestCase) { | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     test.parent = this; | 
					
						
							|  |  |  |     this.tests.push(test); | 
					
						
							|  |  |  |     this._entries.push(test); | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   _addSuite(suite: Suite) { | 
					
						
							|  |  |  |     suite.parent = this; | 
					
						
							|  |  |  |     this.suites.push(suite); | 
					
						
							|  |  |  |     this._entries.push(suite); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 14:54:18 -07:00
										 |  |  |   allTests(): TestCase[] { | 
					
						
							|  |  |  |     const result: TestCase[] = []; | 
					
						
							| 
									
										
										
										
											2021-07-16 12:40:33 -07:00
										 |  |  |     const visit = (suite: Suite) => { | 
					
						
							|  |  |  |       for (const entry of suite._entries) { | 
					
						
							|  |  |  |         if (entry instanceof Suite) | 
					
						
							|  |  |  |           visit(entry); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           result.push(entry); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     visit(this); | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |     return result; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 08:38:04 -07:00
										 |  |  |   titlePath(): string[] { | 
					
						
							|  |  |  |     const titlePath = this.parent ? this.parent.titlePath() : []; | 
					
						
							| 
									
										
										
										
											2022-07-06 13:54:11 -07:00
										 |  |  |     // Ignore anonymous describe blocks.
 | 
					
						
							| 
									
										
										
										
											2022-07-27 20:17:19 -07:00
										 |  |  |     if (this.title || this._type !== 'describe') | 
					
						
							| 
									
										
										
										
											2022-07-06 13:54:11 -07:00
										 |  |  |       titlePath.push(this.title); | 
					
						
							| 
									
										
										
										
											2021-10-19 08:38:04 -07:00
										 |  |  |     return titlePath; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 14:54:18 -07:00
										 |  |  |   _getOnlyItems(): (TestCase | Suite)[] { | 
					
						
							|  |  |  |     const items: (TestCase | Suite)[] = []; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |     if (this._only) | 
					
						
							| 
									
										
										
										
											2021-06-28 22:13:35 +02:00
										 |  |  |       items.push(this); | 
					
						
							|  |  |  |     for (const suite of this.suites) | 
					
						
							|  |  |  |       items.push(...suite._getOnlyItems()); | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     items.push(...this.tests.filter(test => test._only)); | 
					
						
							| 
									
										
										
										
											2021-06-28 22:13:35 +02:00
										 |  |  |     return items; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |   _clone(): Suite { | 
					
						
							| 
									
										
										
										
											2022-07-27 20:17:19 -07:00
										 |  |  |     const suite = new Suite(this.title, this._type); | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     suite._only = this._only; | 
					
						
							| 
									
										
										
										
											2021-07-16 12:40:33 -07:00
										 |  |  |     suite.location = this.location; | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     suite._requireFile = this._requireFile; | 
					
						
							| 
									
										
										
										
											2021-08-10 16:32:32 -07:00
										 |  |  |     suite._use = this._use.slice(); | 
					
						
							| 
									
										
										
										
											2022-03-08 16:35:14 -08:00
										 |  |  |     suite._hooks = this._hooks.slice(); | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     suite._timeout = this._timeout; | 
					
						
							|  |  |  |     suite._annotations = this._annotations.slice(); | 
					
						
							|  |  |  |     suite._modifiers = this._modifiers.slice(); | 
					
						
							| 
									
										
										
										
											2021-09-02 15:42:07 -07:00
										 |  |  |     suite._parallelMode = this._parallelMode; | 
					
						
							| 
									
										
										
										
											2021-10-19 08:38:04 -07:00
										 |  |  |     suite._projectConfig = this._projectConfig; | 
					
						
							| 
									
										
										
										
											2022-03-18 16:07:11 -07:00
										 |  |  |     suite._skipped = this._skipped; | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     return suite; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-10-19 08:38:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   project(): FullProject | undefined { | 
					
						
							|  |  |  |     return this._projectConfig || this.parent?.project(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 14:54:18 -07:00
										 |  |  | export class TestCase extends Base implements reporterTypes.TestCase { | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |   fn: Function; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |   results: reporterTypes.TestResult[] = []; | 
					
						
							| 
									
										
										
										
											2021-07-18 17:40:59 -07:00
										 |  |  |   location: Location; | 
					
						
							| 
									
										
										
										
											2021-10-19 08:38:04 -07:00
										 |  |  |   parent!: Suite; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   expectedStatus: reporterTypes.TestStatus = 'passed'; | 
					
						
							|  |  |  |   timeout = 0; | 
					
						
							| 
									
										
										
										
											2022-03-08 16:35:14 -08:00
										 |  |  |   annotations: Annotation[] = []; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |   retries = 0; | 
					
						
							| 
									
										
										
										
											2022-01-03 17:29:54 -08:00
										 |  |  |   repeatEachIndex = 0; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |   _testType: TestTypeImpl; | 
					
						
							| 
									
										
										
										
											2022-07-27 20:17:19 -07:00
										 |  |  |   id = ''; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |   _workerHash = ''; | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |   _pool: FixturePool | undefined; | 
					
						
							| 
									
										
										
										
											2022-07-27 20:17:19 -07:00
										 |  |  |   _projectId = ''; | 
					
						
							| 
									
										
										
										
											2022-07-05 10:46:30 -07:00
										 |  |  |   // Annotations that are not added from within a test (like fixme and skip), should not
 | 
					
						
							|  |  |  |   // be re-added each time we retry a test.
 | 
					
						
							|  |  |  |   _alreadyInheritedAnnotations: boolean = false; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-08 19:06:25 -08:00
										 |  |  |   constructor(title: string, fn: Function, testType: TestTypeImpl, location: Location) { | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     super(title); | 
					
						
							|  |  |  |     this.fn = fn; | 
					
						
							|  |  |  |     this._testType = testType; | 
					
						
							| 
									
										
										
										
											2021-07-18 17:40:59 -07:00
										 |  |  |     this.location = location; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-19 08:38:04 -07:00
										 |  |  |   titlePath(): string[] { | 
					
						
							|  |  |  |     const titlePath = this.parent ? this.parent.titlePath() : []; | 
					
						
							|  |  |  |     titlePath.push(this.title); | 
					
						
							|  |  |  |     return titlePath; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-18 17:40:59 -07:00
										 |  |  |   outcome(): 'skipped' | 'expected' | 'unexpected' | 'flaky' { | 
					
						
							| 
									
										
										
										
											2022-08-02 12:55:43 -07:00
										 |  |  |     const nonSkipped = this.results.filter(result => result.status !== 'skipped' && result.status !== 'interrupted'); | 
					
						
							| 
									
										
										
										
											2021-08-10 21:26:45 -07:00
										 |  |  |     if (!nonSkipped.length) | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |       return 'skipped'; | 
					
						
							| 
									
										
										
										
											2021-08-10 21:26:45 -07:00
										 |  |  |     if (nonSkipped.every(result => result.status === this.expectedStatus)) | 
					
						
							| 
									
										
										
										
											2021-07-28 15:43:37 -07:00
										 |  |  |       return 'expected'; | 
					
						
							| 
									
										
										
										
											2021-08-10 21:26:45 -07:00
										 |  |  |     if (nonSkipped.some(result => result.status === this.expectedStatus)) | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |       return 'flaky'; | 
					
						
							|  |  |  |     return 'unexpected'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ok(): boolean { | 
					
						
							| 
									
										
										
										
											2021-07-18 17:40:59 -07:00
										 |  |  |     const status = this.outcome(); | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |     return status === 'expected' || status === 'flaky' || status === 'skipped'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-19 14:54:18 -07:00
										 |  |  |   _clone(): TestCase { | 
					
						
							| 
									
										
										
										
											2022-03-08 19:06:25 -08:00
										 |  |  |     const test = new TestCase(this.title, this.fn, this._testType, this.location); | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     test._only = this._only; | 
					
						
							|  |  |  |     test._requireFile = this._requireFile; | 
					
						
							| 
									
										
										
										
											2021-07-29 14:33:37 -07:00
										 |  |  |     test.expectedStatus = this.expectedStatus; | 
					
						
							| 
									
										
										
										
											2022-07-05 10:46:30 -07:00
										 |  |  |     test.annotations = this.annotations.slice(); | 
					
						
							|  |  |  |     test._annotateWithInheritence = this._annotateWithInheritence; | 
					
						
							| 
									
										
										
										
											2021-07-15 22:02:10 -07:00
										 |  |  |     return test; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 10:46:30 -07:00
										 |  |  |   _annotateWithInheritence(annotations: Annotation[]) { | 
					
						
							|  |  |  |     if (this._alreadyInheritedAnnotations) { | 
					
						
							|  |  |  |       this.annotations = annotations; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       this._alreadyInheritedAnnotations = true; | 
					
						
							|  |  |  |       this.annotations = [...this.annotations, ...annotations]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |   _appendTestResult(): reporterTypes.TestResult { | 
					
						
							|  |  |  |     const result: reporterTypes.TestResult = { | 
					
						
							|  |  |  |       retry: this.results.length, | 
					
						
							| 
									
										
										
										
											2022-04-08 15:23:23 -07:00
										 |  |  |       workerIndex: -1, | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |       duration: 0, | 
					
						
							| 
									
										
										
										
											2021-07-18 17:40:59 -07:00
										 |  |  |       startTime: new Date(), | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |       stdout: [], | 
					
						
							|  |  |  |       stderr: [], | 
					
						
							| 
									
										
										
										
											2021-07-16 13:48:37 -07:00
										 |  |  |       attachments: [], | 
					
						
							| 
									
										
										
										
											2021-07-28 15:43:37 -07:00
										 |  |  |       status: 'skipped', | 
					
						
							| 
									
										
										
										
											2022-02-02 19:33:51 -07:00
										 |  |  |       steps: [], | 
					
						
							|  |  |  |       errors: [], | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  |     }; | 
					
						
							|  |  |  |     this.results.push(result); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |