From 784f1c1834236506ed919c45b3e8283f0e0a73e1 Mon Sep 17 00:00:00 2001 From: rconner46 Date: Fri, 16 Aug 2024 10:27:47 -0500 Subject: [PATCH] Fix ApplauseTestCycleId property naming for TestRun Creation --- dist/index.cjs | 2 +- dist/index.cjs.map | 2 +- dist/index.min.js | 2 +- dist/index.min.js.map | 2 +- dist/index.mjs | 2 +- dist/index.mjs.map | 2 +- src/auto-api/auto-api.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dist/index.cjs b/dist/index.cjs index 55fbb4b..b0d65af 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -200,7 +200,7 @@ class AutoApi { sdkVersion: `js:${API_VERSION}`, // Copy over the product id productId: this.options.productId, - applauseTestCycleId: this.options.applauseTestCycleId, + itwTestCycleId: this.options.applauseTestCycleId, // Copy over test rail parameters testRailReportingEnabled: this.options.testRailOptions !== undefined, addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan, diff --git a/dist/index.cjs.map b/dist/index.cjs.map index f241618..e39d2a2 100644 --- a/dist/index.cjs.map +++ b/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/auto-api/version.ts","../src/auto-api/auto-api-config.ts","../src/shared/logging.ts","../src/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/email-helper.ts","../src/auto-api/heartbeat.ts","../src/shared/test-case.ts","../src/auto-api/reporter.ts","../src/public-api/dto.ts","../src/public-api/public-api-config.ts","../src/public-api/public-api.ts","../src/config/config.ts"],"sourcesContent":["export const API_VERSION = '1.1.0';\n","import { TestRailOptions } from './dto.ts';\nimport Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface AutoApiConfig {\n readonly autoApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly testRailOptions?: TestRailOptions;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n\nexport const DEFAULT_AUTO_API_PROPERTIES: Partial = {\n autoApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isAutoApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialAutoApiConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validateAutoApiConfig(config: AutoApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import * as winston from 'winston';\nimport { TransformableInfo } from 'logform';\nimport TransportStream from 'winston-transport';\nconst MESSAGE = Symbol.for('message');\n\nexport const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf(\n ({ level, message, label, timestamp }) => {\n return `${timestamp} [${label}] ${level}: ${message}`;\n }\n);\n\nexport function constructDefaultLogger(): winston.Logger {\n return winston.createLogger({\n format: winston.format.combine(\n winston.format.label({ label: 'Applause Tests' }),\n winston.format.timestamp(),\n winston.format.splat(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n transports: [\n new winston.transports.File({ filename: 'error.log', level: 'error' }),\n new winston.transports.File({ filename: 'combined.log' }),\n new ApplauseTransport(),\n new winston.transports.Console({\n level: 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n }),\n ],\n });\n}\n\n/**\n * A simple Class for storing and retrieving log messages.\n */\nexport class LoggingContainer {\n private logs: string[] = [];\n\n /**\n * Retrieves all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public getLogs(): string[] {\n return this.logs;\n }\n\n /**\n * Retrieves and clears all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public drainLogs(): string[] {\n const logs = this.logs;\n this.clearLogs();\n return logs;\n }\n\n /**\n * Clears all logs stored in the container.\n */\n public clearLogs(): void {\n this.logs = [];\n }\n\n /**\n * Adds a log message to the container.\n *\n * @param log - The log message to add.\n */\n public addLog(log: string): void {\n this.logs.push(log);\n }\n}\n\n// Create a new Shared LoggingContainer to store logs\nexport const APPLAUSE_LOG_RECORDS: LoggingContainer = new LoggingContainer();\n\n/**\n * A Custom Winston Transport that sends logs to the Applause LoggingContainer\n */\nexport class ApplauseTransport extends TransportStream {\n constructor(opts?: TransportStream.TransportStreamOptions) {\n super(opts);\n }\n\n log(info: TransformableInfo, callback: () => void): void {\n setImmediate(() => {\n this.emit('logged', info);\n });\n\n this.format?.transform(info);\n APPLAUSE_LOG_RECORDS.addLog(\n (info[MESSAGE] as string | undefined) ?? (info.message as string)\n );\n\n // Continue to the next transport\n callback();\n }\n}\n","/**\n * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform.\n * The `AutoApi` class provides methods for starting and ending test runs, creating test cases, submitting test case results, and performing other operations related to test management.\n * It also includes properties and methods to track the number of HTTP calls in progress.\n */\n\nimport axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport {\n AssetType,\n CreateTestCaseResultDto,\n CreateTestCaseResultResponseDto,\n EmailAddressResponse,\n EmailFetchRequest,\n SubmitTestCaseResultDto,\n TestResultProviderInfo,\n TestRunCreateDto,\n TestRunCreateResponseDto,\n} from './dto.ts';\nimport { API_VERSION } from './version.ts';\nimport { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\nimport * as winston from 'winston';\n\nexport class AutoApi {\n private readonly client: AxiosInstance;\n\n private logger: winston.Logger;\n private callsInFlight: number;\n /**\n * Tracks the number of HTTP calls in progress.\n * This property is used by reporters that want to know when the async work is finished.\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n /**\n * Creates an instance of the `AutoApi` class.\n * @param options - The configuration options for the Applause API.\n */\n constructor(\n readonly options: AutoApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validateAutoApiConfig(options);\n this.client = axios.create({\n baseURL: options.autoApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * Starts a new test run.\n * @param info - The information for creating the test run.\n * @returns A promise that resolves to the response containing the created test run.\n */\n async startTestRun(\n info: TestRunCreateDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n '/api/v1.0/test-run/create',\n {\n // Provided params\n ...info,\n\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n\n // Copy over the product id\n productId: this.options.productId,\n\n applauseTestCycleId: this.options.applauseTestCycleId,\n\n // Copy over test rail parameters\n testRailReportingEnabled: this.options.testRailOptions !== undefined,\n addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan,\n testRailProjectId: this.options.testRailOptions?.projectId,\n testRailSuiteId: this.options.testRailOptions?.suiteId,\n testRailPlanName: this.options.testRailOptions?.planName,\n testRailRunName: this.options.testRailOptions?.runName,\n overrideTestRailRunNameUniqueness:\n this.options.testRailOptions?.overrideTestRailRunUniqueness,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Ends a test run.\n * @param testRunId - The ID of the test run to end.\n * @returns A promise that resolves to the response indicating the completion of the test run.\n */\n async endTestRun(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(\n `/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Starts a new test case.\n * @param params - The parameters for creating the test case.\n * @returns A promise that resolves to the response containing the created test case.\n */\n async startTestCase(\n params: CreateTestCaseResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post(\n '/api/v1.0/test-result/create-result',\n params\n );\n return res;\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Submits a test case result.\n * @param params - The parameters for submitting the test case result.\n * @returns A promise that resolves when the test case result is submitted.\n */\n async submitTestCaseResult(params: SubmitTestCaseResultDto): Promise {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the provider session links for the specified test results.\n * @param resultIds - The IDs of the test results.\n * @returns A promise that resolves to the response containing the provider session links.\n */\n async getProviderSessionLinks(\n resultIds: number[]\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds: number[] = resultIds.filter(id => id);\n return await this.client.post(\n '/api/v1.0/test-result/provider-info',\n validIds\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Sends a heartbeat for the specified test run.\n * @param testRunId - The ID of the test run.\n * @returns A promise that resolves to the response indicating the heartbeat was sent.\n */\n async sendSdkHeartbeat(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v2.0/sdk-heartbeat', {\n testRunId: testRunId,\n });\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the email address for the specified email prefix.\n * @param emailPrefix - The prefix of the email address.\n * @returns A promise that resolves to the response containing the email address.\n */\n async getEmailAddress(\n emailPrefix: string\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(\n `/api/v1.0/email/get-address?prefix=${emailPrefix}`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the content of the specified email.\n * @param request - The request parameters for retrieving the email content.\n * @returns A promise that resolves to the response containing the email content.\n */\n async getEmailContent(\n request: EmailFetchRequest\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post(\n '/api/v1.0/email/download-email',\n request\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Uploads an asset for the specified test result.\n * @param resultId - The ID of the test result.\n * @param file - The file to upload as an asset.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The GUID of the provider session.\n * @param assetType - The type of the asset.\n * @returns A promise that resolves to the response indicating the asset was uploaded.\n */\n async uploadAsset(\n resultId: number,\n file: Buffer,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType\n ): Promise> {\n this.callsInFlight += 1;\n\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.postForm(\n `/api/v1.0/test-result/${resultId}/upload`,\n {\n file,\n assetName,\n providerSessionGuid,\n assetType,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Configuration of the auto-api client\n */\nexport type ClientConfig = {\n readonly baseUrl: string;\n readonly apiKey: string;\n};\n\n/**\n * DTO used to create a new Applause test run\n */\nexport interface TestRunCreateDto {\n // Required: a list of test cases to pre-create\n tests: string[];\n}\n\n/**\n * DTO modeling the response to a test run creation request\n */\nexport interface TestRunCreateResponseDto {\n // The ID of the Applause Test Run\n runId: number;\n}\n\nexport interface AdditionalTestCaseParams {\n // A collection of provider session guids\n providerSessionIds?: string[];\n\n // Optional: TestRail Test Case Id\n testCaseId?: string;\n\n // Optional: Applause Test Case Id\n itwTestCaseId?: string;\n}\n\n/**\n * DTO used to mark the start of a test result\n */\nexport interface CreateTestCaseResultDto extends AdditionalTestCaseParams {\n // ID of the test run to submit this result to\n testRunId: number;\n\n // Name of the Test Case\n testCaseName: string;\n}\n\n/**\n * DTO response to a test result creation request\n */\nexport interface CreateTestCaseResultResponseDto {\n testResultId: number;\n}\n\nexport interface AdditionalTestCaseResultParams {\n // A list of selenium provider session ids to connect to the result\n providerSessionGuids?: string[];\n\n // An optional testrail test case id\n testRailCaseId?: number;\n\n // An optional applause test case id\n itwCaseId?: number;\n\n // The reason a test case failed\n failureReason?: string;\n}\n\n/**\n * DTO used to submit a status to an in progress test result.\n */\nexport interface SubmitTestCaseResultDto\n extends AdditionalTestCaseResultParams {\n // The id of the test result\n testResultId: number;\n\n // The ending status of the test.\n status: TestResultStatus;\n}\n\n/**\n * Enum representing a test result's status\n */\nexport enum TestResultStatus {\n NOT_RUN = 'NOT_RUN',\n IN_PROGRESS = 'IN_PROGRESS',\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\n/**\n * DTO representing test result info that is provided at the end of a test run\n */\nexport interface TestResultProviderInfo {\n testResultId: number;\n providerUrl: string;\n providerSessionId: string;\n}\n\n/**\n * DTO representing TestRail settings. The presence of this info signals that test rail reporting is enabled\n */\nexport interface TestRailOptions {\n projectId: number;\n suiteId: number;\n planName: string;\n runName: string;\n addAllTestsToPlan?: boolean;\n overrideTestRailRunUniqueness?: boolean;\n}\n\n/**\n * DTO containing a generated email address for testing\n */\nexport interface EmailAddressResponse {\n emailAddress: string;\n}\n\n/**\n * DTO used for fetching an email from a given email address\n */\nexport interface EmailFetchRequest {\n emailAddress: string;\n}\n\nexport enum AssetType {\n SCREENSHOT = 'SCREENSHOT',\n FAILURE_SCREENSHOT = 'FAILURE_SCREENSHOT',\n VIDEO = 'VIDEO',\n NETWORK_HAR = 'NETWORK_HAR',\n VITALS_LOG = 'VITALS_LOG',\n CONSOLE_LOG = 'CONSOLE_LOG',\n NETWORK_LOG = 'NETWORK_LOG',\n DEVICE_LOG = 'DEVICE_LOG',\n SELENIUM_LOG = 'SELENIUM_LOG',\n SELENIUM_LOG_JSON = 'SELENIUM_LOG_JSON',\n BROWSER_LOG = 'BROWSER_LOG',\n FRAMEWORK_LOG = 'FRAMEWORK_LOG',\n EMAIL = 'EMAIL',\n PAGE_SOURCE = 'PAGE_SOURCE',\n CODE_BUNDLE = 'CODE_BUNDLE',\n RESULTS_ZIP = 'RESULTS_ZIP',\n SESSION_DETAILS = 'SESSION_DETAILS',\n DEVICE_DETAILS = 'DEVICE_DETAILS',\n UNKNOWN = 'UNKNOWN',\n}\n","import { AutoApi } from '../auto-api.ts';\nimport { ParsedMail, simpleParser } from 'mailparser';\n\n/**\n * Represents an email inbox.\n */\nexport class Inbox {\n /**\n * Creates an instance of Inbox.\n * @param emailAddress - The email address associated with the inbox.\n * @param autoApi - An instance of the AutoApi class.\n */\n constructor(\n public readonly emailAddress: string,\n private autoApi: AutoApi\n ) {}\n\n /**\n * Retrieves the content of an email from the inbox.\n * @returns A Promise that resolves to the parsed email content.\n */\n async getEmail(): Promise {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n","import { AutoApi } from './auto-api.ts';\nimport { Inbox } from './email/inbox.ts';\n\n/**\n * Helper class for managing email functionality.\n */\nexport class EmailHelper {\n constructor(private autoApi: AutoApi) {}\n\n /**\n * Retrieves the inbox for the specified email prefix.\n *\n * @param emailPrefix - The prefix used to generate the email address.\n * @returns A Promise that resolves to an Inbox object.\n */\n async getInbox(emailPrefix: string): Promise {\n const generatedAddress: string = (\n await this.autoApi.getEmailAddress(emailPrefix)\n ).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\n\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n","import winston = require('winston');\nimport { AutoApi } from './auto-api.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents a service for sending heartbeats during a test run.\n */\nexport class TestRunHeartbeatService {\n private enabled = false;\n private nextHeartbeat?: Promise;\n private readonly logger: winston.Logger;\n\n /**\n * Creates an instance of TestRunHeartbeatService.\n * @param testRunId - The ID of the test run.\n * @param autoApi - The AutoApi instance used for sending heartbeats.\n */\n constructor(\n readonly testRunId: number,\n readonly autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts sending heartbeats.\n * @returns A promise that resolves when the heartbeats are started.\n */\n async start(): Promise {\n // End the current heartbeat if it has started\n await this.end();\n\n // Set up a new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Checks if the heartbeats are enabled.\n * @returns True if the heartbeats are enabled, false otherwise.\n */\n public isEnabled(): boolean {\n return this.enabled;\n }\n\n private scheduleNextHeartbeat(): void {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(\n () => this.sendHeartbeat()\n );\n }\n\n private async sendHeartbeat(): Promise {\n this.logger.debug('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n this.logger.debug('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Ends the heartbeats.\n * @returns A promise that resolves when the heartbeats are ended.\n */\n async end(): Promise {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n this.logger.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n this.logger.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n","import * as winston from 'winston';\n\nexport const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-';\n\nexport function parseTestCaseName(\n testCaseName: string,\n logger?: winston.Logger\n): ParsedTestCaseName {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds =\n matches\n ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX))\n .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? [];\n const applauseCaseIds =\n matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? [];\n\n if (testRailCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple TestRail case ids detected in testCase name'\n );\n }\n if (applauseCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple Applause case ids detected in testCase name'\n );\n }\n return {\n applauseTestCaseId: applauseCaseIds[0],\n testRailTestCaseId: testRailCaseIds[0],\n testCaseName: testCaseName\n .replace(/(TestRail-\\d+|Applause-\\d+)/g, '')\n .replace(/\\s+/g, ' ')\n .trim(),\n };\n}\n\nexport interface ParsedTestCaseName {\n testCaseName: string;\n testRailTestCaseId?: string;\n applauseTestCaseId?: string;\n}\n","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport {\n AdditionalTestCaseParams,\n AdditionalTestCaseResultParams,\n AssetType,\n TestResultStatus,\n} from './dto.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { AutoApiConfig } from './auto-api-config.ts';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents an Applause reporter.\n */\nexport class ApplauseReporter {\n private autoApi: AutoApi;\n private initializer: RunInitializer;\n private logger: winston.Logger;\n private reporter?: Promise;\n private runStarted: boolean = false;\n private runFinished: boolean = false;\n\n /**\n * Creates an instance of ApplauseReporter.\n * @param config - The Applause configuration.\n */\n constructor(config: AutoApiConfig, logger?: winston.Logger) {\n this.logger = logger ?? constructDefaultLogger();\n this.autoApi = new AutoApi(config, this.logger);\n this.initializer = new RunInitializer(this.autoApi, this.logger);\n const runId = process.env['APPLAUSE_RUN_ID'];\n if (runId !== undefined) {\n const r = new RunReporter(\n this.autoApi,\n parseInt(runId),\n undefined,\n this.logger\n );\n this.reporter = new Promise(resolve => resolve(r));\n this.runStarted = true;\n }\n }\n\n /**\n * Starts the Applause runner.\n * @param tests - Optional array of test names to run.\n * @returns A promise that resolves to the test run ID.\n * @throws Error if a run is already started or finished.\n */\n public async runnerStart(tests?: string[]): Promise {\n if (this.reporter !== undefined) {\n this.logger.error(\n 'Cannot start a run - run already started or run already finished'\n );\n throw new Error(\n 'Cannot start a run - run already started or run already finished'\n );\n }\n this.reporter = this.initializer.initializeRun(tests);\n const initializedReporter = await this.reporter;\n this.runStarted = true;\n process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString();\n return initializedReporter.testRunId;\n }\n\n /**\n * Starts a test case.\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Optional additional parameters for the test case.\n * @returns A promise that resolves to the test case ID.\n * @throws Error if a run was never initialized.\n */\n public async startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot start a test case for a run that was never initialized'\n );\n throw new Error(\n 'Cannot start a test case for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.startTestCase(id, testCaseName, params);\n }\n\n /**\n * Submits a test case result.\n * @param id - The ID of the test case.\n * @param status - The status of the test case result.\n * @param params - Optional additional parameters for the test case result.\n * @returns A promise that resolves to the test case result ID.\n * @throws Error if a run was never initialized.\n */\n public async submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n throw new Error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.submitTestCaseResult(id, status, params);\n }\n\n /**\n * Ends the Applause runner.\n * @returns A promise that resolves when the runner is ended.\n * @throws Error if a run was never initialized.\n */\n public async runnerEnd(): Promise {\n if (this.reporter === undefined) {\n this.logger.error('Cannot end a run that was never initialized');\n throw new Error('Cannot end a run that was never initialized');\n }\n await this.reporter\n .then(reporter => reporter.runnerEnd())\n .then(() => (this.runFinished = true));\n }\n\n /**\n * Attaches an asset to a test case.\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset data as a Buffer.\n * @returns A promise that resolves when the asset is attached.\n * @throws Error if a run was never initialized.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n throw new Error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n }\n return await this.reporter.then(reporter =>\n reporter.attachTestCaseAsset(\n id,\n assetName,\n providerSessionGuid,\n assetType,\n asset\n )\n );\n }\n\n /**\n * Checks if the Applause runner is synchronized.\n * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished.\n */\n public isSynchronized(): boolean {\n return (\n (!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0\n );\n }\n}\n\n/**\n * Represents a Run Initializer.\n */\nexport class RunInitializer {\n private logger: winston.Logger;\n constructor(\n private autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Initializes a test run.\n * @param tests - An optional array of test names to include in the run.\n * @returns A promise that resolves to a RunReporter instance.\n * @throws An error if unable to create the test run.\n */\n async initializeRun(tests?: string[]): Promise {\n const cleanedTests = tests\n ?.map(testName => parseTestCaseName(testName, this.logger))\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests ?? [],\n });\n if (\n testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300\n ) {\n this.logger.error(\n `Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`\n );\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n this.logger.info(`Test Run ${runId} initialized`);\n const heartbeatService = new TestRunHeartbeatService(\n runId,\n this.autoApi,\n this.logger\n );\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService, this.logger);\n }\n}\n\n/**\n * Handles reporting test results to the Applause API.\n */\nexport class RunReporter {\n private uidToResultIdMap: Record> = {};\n private resultSubmissionMap: Record> = {};\n private logger: winston.Logger;\n\n /**\n * Creates a new instance of the Reporter class.\n * @param autoApi - The AutoApi instance.\n * @param testRunId - The ID of the test run.\n * @param heartbeatService - (Optional) The TestRunHeartbeatService instance.\n */\n constructor(\n private autoApi: AutoApi,\n public readonly testRunId: number,\n private heartbeatService?: TestRunHeartbeatService,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts a test case and returns a promise that resolves to the test result ID.\n *\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Additional parameters for the test case.\n * @returns A promise that resolves to the test result ID.\n */\n public startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (!testCaseName) {\n this.logger.error('testCaseName is required');\n throw new Error('testCaseName is required');\n }\n const parsedTestCase = parseTestCaseName(testCaseName, this.logger);\n const submission = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\n\n testRunId: this.testRunId,\n // If the additional params provides either test case id, it will override the parsed value we set above\n ...Object.fromEntries(\n Object.entries(params || {}).filter(([_, v]) => v !== undefined)\n ),\n })\n .then(res => {\n return res.data.testResultId;\n });\n this.uidToResultIdMap[id] = submission;\n return submission;\n }\n\n /**\n * Submits the result of a test case.\n *\n * @param id - The ID of the test case.\n * @param status - The status of the test result.\n * @param params - Additional parameters for the test result.\n * @returns A promise that resolves to the result ID.\n */\n public submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n const submission = this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi\n .submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n })\n .then(() => resultId)\n );\n this.resultSubmissionMap[id] = submission;\n return submission;\n }\n\n /**\n * Attaches a test case asset to a result.\n *\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset to attach.\n * @returns A promise that resolves when the asset is attached.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n await this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi.uploadAsset(\n resultId,\n asset,\n assetName,\n providerSessionGuid,\n assetType\n )\n );\n }\n\n /**\n * Ends the test runner and performs necessary cleanup tasks.\n * @returns A promise that resolves when the runner has ended.\n */\n public async runnerEnd(): Promise {\n // Wait for all results to be created\n const resultIds =\n (await Promise.all(Object.values(this.uidToResultIdMap))) ?? [];\n\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n\n // Wait the heartbeat to be ended\n void (await this.heartbeatService?.end());\n void (await this.autoApi.endTestRun(this.testRunId));\n\n // Fetch the provider session asset links and save them off to a file\n const resp = await this.autoApi.getProviderSessionLinks(resultIds);\n const jsonArray = resp.data ?? [];\n if (jsonArray.length > 0) {\n this.logger.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(\n pathJoin(outputPath, 'providerUrls.txt'),\n JSON.stringify(jsonArray, null, 1)\n );\n }\n }\n}\n","export interface TestRunAutoResultDto {\n testCycleId: number;\n status: TestRunAutoResultStatus;\n failureReason?: string;\n sessionDetailsJson?: SessionDetails;\n startTime?: Date;\n endTime?: Date;\n}\n\nexport enum TestRunAutoResultStatus {\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\nexport interface SessionDetails {\n value: {\n deviceName?: string;\n orientation?: string;\n platformName?: string;\n platformVersion?: string;\n browserName?: string;\n browserVersion?: string;\n };\n}\n","import Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface PublicApiConfig {\n readonly publicApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://api.applause.com/';\n\nexport const DEFAULT_PUBLIC_API_PROPERTIES: Partial = {\n publicApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isPublicApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialPublicApiConfig(\n config: Partial\n) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validatePublicApiConfig(config: PublicApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport { TestRunAutoResultDto } from './dto.ts';\nimport {\n PublicApiConfig,\n validatePublicApiConfig,\n} from './public-api-config.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\nexport class PublicApi {\n private readonly client: AxiosInstance;\n\n private callsInFlight: number;\n private logger: winston.Logger;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n constructor(\n readonly options: PublicApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validatePublicApiConfig(options);\n this.client = axios.create({\n baseURL: options.publicApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n async submitResult(\n testCaseId: number,\n info: TestRunAutoResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n `v2/test-case-results/${testCaseId}/submit`,\n info\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Represents the configuration options for the Applause Reporter.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport path from 'path';\n\nimport {\n AutoApiConfig,\n DEFAULT_AUTO_API_PROPERTIES,\n isAutoApiConfigComplete,\n validateAutoApiConfig,\n} from '../auto-api/auto-api-config.ts';\nimport {\n DEFAULT_PUBLIC_API_PROPERTIES,\n isPublicApiConfigComplete,\n PublicApiConfig,\n validatePublicApiConfig,\n} from '../public-api/public-api-config.ts';\n\nexport type ApplauseConfig = AutoApiConfig & PublicApiConfig;\n\n/**\n * Represents the properties for loading the configuration.\n */\nexport interface ConfigLoadProperties {\n configFile?: string;\n properties?: Partial;\n}\n\n/**\n * Loads the configuration for the Applause Reporter.\n * @param loadOptions - The options for loading the configuration.\n * @returns The loaded Applause configuration.\n * @throws Error if the configuration is not complete or invalid.\n */\nexport function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig {\n // Setup the initial config with any default properties\n let config: Partial = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(\n config,\n loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))\n );\n } else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n\n // We know that the config is complete, so we can cast\n const finalConfig = config as ApplauseConfig;\n\n validateConfig(finalConfig);\n\n return finalConfig;\n}\n\n/**\n * Overrides the configuration with the provided overrides.\n * @param config - The base configuration.\n * @param overrides - The overrides to apply.\n * @returns The overridden configuration.\n */\nexport function overrideConfig(\n config: Partial,\n overrides?: Partial\n): Partial {\n return Object.assign(\n {},\n config,\n Object.fromEntries(\n Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined)\n )\n );\n}\n\n/**\n * Checks if the configuration is complete.\n * @param config - The configuration to check.\n * @returns True if the configuration is complete, false otherwise.\n */\nexport function isComplete(config: Partial): boolean {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\n\n/**\n * Loads the configuration from the specified file.\n * @param configFile - The path to the configuration file.\n * @returns The loaded configuration from the file.\n */\nexport function loadConfigFromFile(\n configFile?: string\n): Partial {\n const configFilePath = configFile ?? `${process.cwd()}/applause.json`;\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileContents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileContents) as Partial;\n}\n\n/**\n * Validates the configuration.\n * @param config - The configuration to validate.\n * @throws Error if the configuration is invalid.\n */\nexport function validateConfig(config: ApplauseConfig) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\n\n/**\n * Validates a partial configuration.\n * @param config - The partial configuration to validate.\n * @throws Error if the partial configuration is invalid.\n */\nexport function validatePartialConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n"],"names":["validator","DEFAULT_URL","winston","TestResultStatus","AssetType","simpleParser","writeFileSync","pathJoin","TestRunAutoResultStatus","existsSync","readFileSync"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.cjs","sources":["../src/auto-api/version.ts","../src/auto-api/auto-api-config.ts","../src/shared/logging.ts","../src/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/email-helper.ts","../src/auto-api/heartbeat.ts","../src/shared/test-case.ts","../src/auto-api/reporter.ts","../src/public-api/dto.ts","../src/public-api/public-api-config.ts","../src/public-api/public-api.ts","../src/config/config.ts"],"sourcesContent":["export const API_VERSION = '1.1.0';\n","import { TestRailOptions } from './dto.ts';\nimport Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface AutoApiConfig {\n readonly autoApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly testRailOptions?: TestRailOptions;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n\nexport const DEFAULT_AUTO_API_PROPERTIES: Partial = {\n autoApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isAutoApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialAutoApiConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validateAutoApiConfig(config: AutoApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import * as winston from 'winston';\nimport { TransformableInfo } from 'logform';\nimport TransportStream from 'winston-transport';\nconst MESSAGE = Symbol.for('message');\n\nexport const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf(\n ({ level, message, label, timestamp }) => {\n return `${timestamp} [${label}] ${level}: ${message}`;\n }\n);\n\nexport function constructDefaultLogger(): winston.Logger {\n return winston.createLogger({\n format: winston.format.combine(\n winston.format.label({ label: 'Applause Tests' }),\n winston.format.timestamp(),\n winston.format.splat(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n transports: [\n new winston.transports.File({ filename: 'error.log', level: 'error' }),\n new winston.transports.File({ filename: 'combined.log' }),\n new ApplauseTransport(),\n new winston.transports.Console({\n level: 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n }),\n ],\n });\n}\n\n/**\n * A simple Class for storing and retrieving log messages.\n */\nexport class LoggingContainer {\n private logs: string[] = [];\n\n /**\n * Retrieves all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public getLogs(): string[] {\n return this.logs;\n }\n\n /**\n * Retrieves and clears all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public drainLogs(): string[] {\n const logs = this.logs;\n this.clearLogs();\n return logs;\n }\n\n /**\n * Clears all logs stored in the container.\n */\n public clearLogs(): void {\n this.logs = [];\n }\n\n /**\n * Adds a log message to the container.\n *\n * @param log - The log message to add.\n */\n public addLog(log: string): void {\n this.logs.push(log);\n }\n}\n\n// Create a new Shared LoggingContainer to store logs\nexport const APPLAUSE_LOG_RECORDS: LoggingContainer = new LoggingContainer();\n\n/**\n * A Custom Winston Transport that sends logs to the Applause LoggingContainer\n */\nexport class ApplauseTransport extends TransportStream {\n constructor(opts?: TransportStream.TransportStreamOptions) {\n super(opts);\n }\n\n log(info: TransformableInfo, callback: () => void): void {\n setImmediate(() => {\n this.emit('logged', info);\n });\n\n this.format?.transform(info);\n APPLAUSE_LOG_RECORDS.addLog(\n (info[MESSAGE] as string | undefined) ?? (info.message as string)\n );\n\n // Continue to the next transport\n callback();\n }\n}\n","/**\n * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform.\n * The `AutoApi` class provides methods for starting and ending test runs, creating test cases, submitting test case results, and performing other operations related to test management.\n * It also includes properties and methods to track the number of HTTP calls in progress.\n */\n\nimport axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport {\n AssetType,\n CreateTestCaseResultDto,\n CreateTestCaseResultResponseDto,\n EmailAddressResponse,\n EmailFetchRequest,\n SubmitTestCaseResultDto,\n TestResultProviderInfo,\n TestRunCreateDto,\n TestRunCreateResponseDto,\n} from './dto.ts';\nimport { API_VERSION } from './version.ts';\nimport { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\nimport * as winston from 'winston';\n\nexport class AutoApi {\n private readonly client: AxiosInstance;\n\n private logger: winston.Logger;\n private callsInFlight: number;\n /**\n * Tracks the number of HTTP calls in progress.\n * This property is used by reporters that want to know when the async work is finished.\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n /**\n * Creates an instance of the `AutoApi` class.\n * @param options - The configuration options for the Applause API.\n */\n constructor(\n readonly options: AutoApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validateAutoApiConfig(options);\n this.client = axios.create({\n baseURL: options.autoApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * Starts a new test run.\n * @param info - The information for creating the test run.\n * @returns A promise that resolves to the response containing the created test run.\n */\n async startTestRun(\n info: TestRunCreateDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n '/api/v1.0/test-run/create',\n {\n // Provided params\n ...info,\n\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n\n // Copy over the product id\n productId: this.options.productId,\n\n itwTestCycleId: this.options.applauseTestCycleId,\n\n // Copy over test rail parameters\n testRailReportingEnabled: this.options.testRailOptions !== undefined,\n addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan,\n testRailProjectId: this.options.testRailOptions?.projectId,\n testRailSuiteId: this.options.testRailOptions?.suiteId,\n testRailPlanName: this.options.testRailOptions?.planName,\n testRailRunName: this.options.testRailOptions?.runName,\n overrideTestRailRunNameUniqueness:\n this.options.testRailOptions?.overrideTestRailRunUniqueness,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Ends a test run.\n * @param testRunId - The ID of the test run to end.\n * @returns A promise that resolves to the response indicating the completion of the test run.\n */\n async endTestRun(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(\n `/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Starts a new test case.\n * @param params - The parameters for creating the test case.\n * @returns A promise that resolves to the response containing the created test case.\n */\n async startTestCase(\n params: CreateTestCaseResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post(\n '/api/v1.0/test-result/create-result',\n params\n );\n return res;\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Submits a test case result.\n * @param params - The parameters for submitting the test case result.\n * @returns A promise that resolves when the test case result is submitted.\n */\n async submitTestCaseResult(params: SubmitTestCaseResultDto): Promise {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the provider session links for the specified test results.\n * @param resultIds - The IDs of the test results.\n * @returns A promise that resolves to the response containing the provider session links.\n */\n async getProviderSessionLinks(\n resultIds: number[]\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds: number[] = resultIds.filter(id => id);\n return await this.client.post(\n '/api/v1.0/test-result/provider-info',\n validIds\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Sends a heartbeat for the specified test run.\n * @param testRunId - The ID of the test run.\n * @returns A promise that resolves to the response indicating the heartbeat was sent.\n */\n async sendSdkHeartbeat(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v2.0/sdk-heartbeat', {\n testRunId: testRunId,\n });\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the email address for the specified email prefix.\n * @param emailPrefix - The prefix of the email address.\n * @returns A promise that resolves to the response containing the email address.\n */\n async getEmailAddress(\n emailPrefix: string\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(\n `/api/v1.0/email/get-address?prefix=${emailPrefix}`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the content of the specified email.\n * @param request - The request parameters for retrieving the email content.\n * @returns A promise that resolves to the response containing the email content.\n */\n async getEmailContent(\n request: EmailFetchRequest\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post(\n '/api/v1.0/email/download-email',\n request\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Uploads an asset for the specified test result.\n * @param resultId - The ID of the test result.\n * @param file - The file to upload as an asset.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The GUID of the provider session.\n * @param assetType - The type of the asset.\n * @returns A promise that resolves to the response indicating the asset was uploaded.\n */\n async uploadAsset(\n resultId: number,\n file: Buffer,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType\n ): Promise> {\n this.callsInFlight += 1;\n\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.postForm(\n `/api/v1.0/test-result/${resultId}/upload`,\n {\n file,\n assetName,\n providerSessionGuid,\n assetType,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Configuration of the auto-api client\n */\nexport type ClientConfig = {\n readonly baseUrl: string;\n readonly apiKey: string;\n};\n\n/**\n * DTO used to create a new Applause test run\n */\nexport interface TestRunCreateDto {\n // Required: a list of test cases to pre-create\n tests: string[];\n}\n\n/**\n * DTO modeling the response to a test run creation request\n */\nexport interface TestRunCreateResponseDto {\n // The ID of the Applause Test Run\n runId: number;\n}\n\nexport interface AdditionalTestCaseParams {\n // A collection of provider session guids\n providerSessionIds?: string[];\n\n // Optional: TestRail Test Case Id\n testCaseId?: string;\n\n // Optional: Applause Test Case Id\n itwTestCaseId?: string;\n}\n\n/**\n * DTO used to mark the start of a test result\n */\nexport interface CreateTestCaseResultDto extends AdditionalTestCaseParams {\n // ID of the test run to submit this result to\n testRunId: number;\n\n // Name of the Test Case\n testCaseName: string;\n}\n\n/**\n * DTO response to a test result creation request\n */\nexport interface CreateTestCaseResultResponseDto {\n testResultId: number;\n}\n\nexport interface AdditionalTestCaseResultParams {\n // A list of selenium provider session ids to connect to the result\n providerSessionGuids?: string[];\n\n // An optional testrail test case id\n testRailCaseId?: number;\n\n // An optional applause test case id\n itwCaseId?: number;\n\n // The reason a test case failed\n failureReason?: string;\n}\n\n/**\n * DTO used to submit a status to an in progress test result.\n */\nexport interface SubmitTestCaseResultDto\n extends AdditionalTestCaseResultParams {\n // The id of the test result\n testResultId: number;\n\n // The ending status of the test.\n status: TestResultStatus;\n}\n\n/**\n * Enum representing a test result's status\n */\nexport enum TestResultStatus {\n NOT_RUN = 'NOT_RUN',\n IN_PROGRESS = 'IN_PROGRESS',\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\n/**\n * DTO representing test result info that is provided at the end of a test run\n */\nexport interface TestResultProviderInfo {\n testResultId: number;\n providerUrl: string;\n providerSessionId: string;\n}\n\n/**\n * DTO representing TestRail settings. The presence of this info signals that test rail reporting is enabled\n */\nexport interface TestRailOptions {\n projectId: number;\n suiteId: number;\n planName: string;\n runName: string;\n addAllTestsToPlan?: boolean;\n overrideTestRailRunUniqueness?: boolean;\n}\n\n/**\n * DTO containing a generated email address for testing\n */\nexport interface EmailAddressResponse {\n emailAddress: string;\n}\n\n/**\n * DTO used for fetching an email from a given email address\n */\nexport interface EmailFetchRequest {\n emailAddress: string;\n}\n\nexport enum AssetType {\n SCREENSHOT = 'SCREENSHOT',\n FAILURE_SCREENSHOT = 'FAILURE_SCREENSHOT',\n VIDEO = 'VIDEO',\n NETWORK_HAR = 'NETWORK_HAR',\n VITALS_LOG = 'VITALS_LOG',\n CONSOLE_LOG = 'CONSOLE_LOG',\n NETWORK_LOG = 'NETWORK_LOG',\n DEVICE_LOG = 'DEVICE_LOG',\n SELENIUM_LOG = 'SELENIUM_LOG',\n SELENIUM_LOG_JSON = 'SELENIUM_LOG_JSON',\n BROWSER_LOG = 'BROWSER_LOG',\n FRAMEWORK_LOG = 'FRAMEWORK_LOG',\n EMAIL = 'EMAIL',\n PAGE_SOURCE = 'PAGE_SOURCE',\n CODE_BUNDLE = 'CODE_BUNDLE',\n RESULTS_ZIP = 'RESULTS_ZIP',\n SESSION_DETAILS = 'SESSION_DETAILS',\n DEVICE_DETAILS = 'DEVICE_DETAILS',\n UNKNOWN = 'UNKNOWN',\n}\n","import { AutoApi } from '../auto-api.ts';\nimport { ParsedMail, simpleParser } from 'mailparser';\n\n/**\n * Represents an email inbox.\n */\nexport class Inbox {\n /**\n * Creates an instance of Inbox.\n * @param emailAddress - The email address associated with the inbox.\n * @param autoApi - An instance of the AutoApi class.\n */\n constructor(\n public readonly emailAddress: string,\n private autoApi: AutoApi\n ) {}\n\n /**\n * Retrieves the content of an email from the inbox.\n * @returns A Promise that resolves to the parsed email content.\n */\n async getEmail(): Promise {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n","import { AutoApi } from './auto-api.ts';\nimport { Inbox } from './email/inbox.ts';\n\n/**\n * Helper class for managing email functionality.\n */\nexport class EmailHelper {\n constructor(private autoApi: AutoApi) {}\n\n /**\n * Retrieves the inbox for the specified email prefix.\n *\n * @param emailPrefix - The prefix used to generate the email address.\n * @returns A Promise that resolves to an Inbox object.\n */\n async getInbox(emailPrefix: string): Promise {\n const generatedAddress: string = (\n await this.autoApi.getEmailAddress(emailPrefix)\n ).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\n\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n","import winston = require('winston');\nimport { AutoApi } from './auto-api.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents a service for sending heartbeats during a test run.\n */\nexport class TestRunHeartbeatService {\n private enabled = false;\n private nextHeartbeat?: Promise;\n private readonly logger: winston.Logger;\n\n /**\n * Creates an instance of TestRunHeartbeatService.\n * @param testRunId - The ID of the test run.\n * @param autoApi - The AutoApi instance used for sending heartbeats.\n */\n constructor(\n readonly testRunId: number,\n readonly autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts sending heartbeats.\n * @returns A promise that resolves when the heartbeats are started.\n */\n async start(): Promise {\n // End the current heartbeat if it has started\n await this.end();\n\n // Set up a new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Checks if the heartbeats are enabled.\n * @returns True if the heartbeats are enabled, false otherwise.\n */\n public isEnabled(): boolean {\n return this.enabled;\n }\n\n private scheduleNextHeartbeat(): void {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(\n () => this.sendHeartbeat()\n );\n }\n\n private async sendHeartbeat(): Promise {\n this.logger.debug('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n this.logger.debug('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Ends the heartbeats.\n * @returns A promise that resolves when the heartbeats are ended.\n */\n async end(): Promise {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n this.logger.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n this.logger.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n","import * as winston from 'winston';\n\nexport const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-';\n\nexport function parseTestCaseName(\n testCaseName: string,\n logger?: winston.Logger\n): ParsedTestCaseName {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds =\n matches\n ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX))\n .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? [];\n const applauseCaseIds =\n matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? [];\n\n if (testRailCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple TestRail case ids detected in testCase name'\n );\n }\n if (applauseCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple Applause case ids detected in testCase name'\n );\n }\n return {\n applauseTestCaseId: applauseCaseIds[0],\n testRailTestCaseId: testRailCaseIds[0],\n testCaseName: testCaseName\n .replace(/(TestRail-\\d+|Applause-\\d+)/g, '')\n .replace(/\\s+/g, ' ')\n .trim(),\n };\n}\n\nexport interface ParsedTestCaseName {\n testCaseName: string;\n testRailTestCaseId?: string;\n applauseTestCaseId?: string;\n}\n","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport {\n AdditionalTestCaseParams,\n AdditionalTestCaseResultParams,\n AssetType,\n TestResultStatus,\n} from './dto.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { AutoApiConfig } from './auto-api-config.ts';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents an Applause reporter.\n */\nexport class ApplauseReporter {\n private autoApi: AutoApi;\n private initializer: RunInitializer;\n private logger: winston.Logger;\n private reporter?: Promise;\n private runStarted: boolean = false;\n private runFinished: boolean = false;\n\n /**\n * Creates an instance of ApplauseReporter.\n * @param config - The Applause configuration.\n */\n constructor(config: AutoApiConfig, logger?: winston.Logger) {\n this.logger = logger ?? constructDefaultLogger();\n this.autoApi = new AutoApi(config, this.logger);\n this.initializer = new RunInitializer(this.autoApi, this.logger);\n const runId = process.env['APPLAUSE_RUN_ID'];\n if (runId !== undefined) {\n const r = new RunReporter(\n this.autoApi,\n parseInt(runId),\n undefined,\n this.logger\n );\n this.reporter = new Promise(resolve => resolve(r));\n this.runStarted = true;\n }\n }\n\n /**\n * Starts the Applause runner.\n * @param tests - Optional array of test names to run.\n * @returns A promise that resolves to the test run ID.\n * @throws Error if a run is already started or finished.\n */\n public async runnerStart(tests?: string[]): Promise {\n if (this.reporter !== undefined) {\n this.logger.error(\n 'Cannot start a run - run already started or run already finished'\n );\n throw new Error(\n 'Cannot start a run - run already started or run already finished'\n );\n }\n this.reporter = this.initializer.initializeRun(tests);\n const initializedReporter = await this.reporter;\n this.runStarted = true;\n process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString();\n return initializedReporter.testRunId;\n }\n\n /**\n * Starts a test case.\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Optional additional parameters for the test case.\n * @returns A promise that resolves to the test case ID.\n * @throws Error if a run was never initialized.\n */\n public async startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot start a test case for a run that was never initialized'\n );\n throw new Error(\n 'Cannot start a test case for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.startTestCase(id, testCaseName, params);\n }\n\n /**\n * Submits a test case result.\n * @param id - The ID of the test case.\n * @param status - The status of the test case result.\n * @param params - Optional additional parameters for the test case result.\n * @returns A promise that resolves to the test case result ID.\n * @throws Error if a run was never initialized.\n */\n public async submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n throw new Error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.submitTestCaseResult(id, status, params);\n }\n\n /**\n * Ends the Applause runner.\n * @returns A promise that resolves when the runner is ended.\n * @throws Error if a run was never initialized.\n */\n public async runnerEnd(): Promise {\n if (this.reporter === undefined) {\n this.logger.error('Cannot end a run that was never initialized');\n throw new Error('Cannot end a run that was never initialized');\n }\n await this.reporter\n .then(reporter => reporter.runnerEnd())\n .then(() => (this.runFinished = true));\n }\n\n /**\n * Attaches an asset to a test case.\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset data as a Buffer.\n * @returns A promise that resolves when the asset is attached.\n * @throws Error if a run was never initialized.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n throw new Error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n }\n return await this.reporter.then(reporter =>\n reporter.attachTestCaseAsset(\n id,\n assetName,\n providerSessionGuid,\n assetType,\n asset\n )\n );\n }\n\n /**\n * Checks if the Applause runner is synchronized.\n * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished.\n */\n public isSynchronized(): boolean {\n return (\n (!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0\n );\n }\n}\n\n/**\n * Represents a Run Initializer.\n */\nexport class RunInitializer {\n private logger: winston.Logger;\n constructor(\n private autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Initializes a test run.\n * @param tests - An optional array of test names to include in the run.\n * @returns A promise that resolves to a RunReporter instance.\n * @throws An error if unable to create the test run.\n */\n async initializeRun(tests?: string[]): Promise {\n const cleanedTests = tests\n ?.map(testName => parseTestCaseName(testName, this.logger))\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests ?? [],\n });\n if (\n testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300\n ) {\n this.logger.error(\n `Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`\n );\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n this.logger.info(`Test Run ${runId} initialized`);\n const heartbeatService = new TestRunHeartbeatService(\n runId,\n this.autoApi,\n this.logger\n );\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService, this.logger);\n }\n}\n\n/**\n * Handles reporting test results to the Applause API.\n */\nexport class RunReporter {\n private uidToResultIdMap: Record> = {};\n private resultSubmissionMap: Record> = {};\n private logger: winston.Logger;\n\n /**\n * Creates a new instance of the Reporter class.\n * @param autoApi - The AutoApi instance.\n * @param testRunId - The ID of the test run.\n * @param heartbeatService - (Optional) The TestRunHeartbeatService instance.\n */\n constructor(\n private autoApi: AutoApi,\n public readonly testRunId: number,\n private heartbeatService?: TestRunHeartbeatService,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts a test case and returns a promise that resolves to the test result ID.\n *\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Additional parameters for the test case.\n * @returns A promise that resolves to the test result ID.\n */\n public startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (!testCaseName) {\n this.logger.error('testCaseName is required');\n throw new Error('testCaseName is required');\n }\n const parsedTestCase = parseTestCaseName(testCaseName, this.logger);\n const submission = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\n\n testRunId: this.testRunId,\n // If the additional params provides either test case id, it will override the parsed value we set above\n ...Object.fromEntries(\n Object.entries(params || {}).filter(([_, v]) => v !== undefined)\n ),\n })\n .then(res => {\n return res.data.testResultId;\n });\n this.uidToResultIdMap[id] = submission;\n return submission;\n }\n\n /**\n * Submits the result of a test case.\n *\n * @param id - The ID of the test case.\n * @param status - The status of the test result.\n * @param params - Additional parameters for the test result.\n * @returns A promise that resolves to the result ID.\n */\n public submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n const submission = this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi\n .submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n })\n .then(() => resultId)\n );\n this.resultSubmissionMap[id] = submission;\n return submission;\n }\n\n /**\n * Attaches a test case asset to a result.\n *\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset to attach.\n * @returns A promise that resolves when the asset is attached.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n await this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi.uploadAsset(\n resultId,\n asset,\n assetName,\n providerSessionGuid,\n assetType\n )\n );\n }\n\n /**\n * Ends the test runner and performs necessary cleanup tasks.\n * @returns A promise that resolves when the runner has ended.\n */\n public async runnerEnd(): Promise {\n // Wait for all results to be created\n const resultIds =\n (await Promise.all(Object.values(this.uidToResultIdMap))) ?? [];\n\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n\n // Wait the heartbeat to be ended\n void (await this.heartbeatService?.end());\n void (await this.autoApi.endTestRun(this.testRunId));\n\n // Fetch the provider session asset links and save them off to a file\n const resp = await this.autoApi.getProviderSessionLinks(resultIds);\n const jsonArray = resp.data ?? [];\n if (jsonArray.length > 0) {\n this.logger.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(\n pathJoin(outputPath, 'providerUrls.txt'),\n JSON.stringify(jsonArray, null, 1)\n );\n }\n }\n}\n","export interface TestRunAutoResultDto {\n testCycleId: number;\n status: TestRunAutoResultStatus;\n failureReason?: string;\n sessionDetailsJson?: SessionDetails;\n startTime?: Date;\n endTime?: Date;\n}\n\nexport enum TestRunAutoResultStatus {\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\nexport interface SessionDetails {\n value: {\n deviceName?: string;\n orientation?: string;\n platformName?: string;\n platformVersion?: string;\n browserName?: string;\n browserVersion?: string;\n };\n}\n","import Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface PublicApiConfig {\n readonly publicApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://api.applause.com/';\n\nexport const DEFAULT_PUBLIC_API_PROPERTIES: Partial = {\n publicApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isPublicApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialPublicApiConfig(\n config: Partial\n) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validatePublicApiConfig(config: PublicApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport { TestRunAutoResultDto } from './dto.ts';\nimport {\n PublicApiConfig,\n validatePublicApiConfig,\n} from './public-api-config.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\nexport class PublicApi {\n private readonly client: AxiosInstance;\n\n private callsInFlight: number;\n private logger: winston.Logger;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n constructor(\n readonly options: PublicApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validatePublicApiConfig(options);\n this.client = axios.create({\n baseURL: options.publicApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n async submitResult(\n testCaseId: number,\n info: TestRunAutoResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n `v2/test-case-results/${testCaseId}/submit`,\n info\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Represents the configuration options for the Applause Reporter.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport path from 'path';\n\nimport {\n AutoApiConfig,\n DEFAULT_AUTO_API_PROPERTIES,\n isAutoApiConfigComplete,\n validateAutoApiConfig,\n} from '../auto-api/auto-api-config.ts';\nimport {\n DEFAULT_PUBLIC_API_PROPERTIES,\n isPublicApiConfigComplete,\n PublicApiConfig,\n validatePublicApiConfig,\n} from '../public-api/public-api-config.ts';\n\nexport type ApplauseConfig = AutoApiConfig & PublicApiConfig;\n\n/**\n * Represents the properties for loading the configuration.\n */\nexport interface ConfigLoadProperties {\n configFile?: string;\n properties?: Partial;\n}\n\n/**\n * Loads the configuration for the Applause Reporter.\n * @param loadOptions - The options for loading the configuration.\n * @returns The loaded Applause configuration.\n * @throws Error if the configuration is not complete or invalid.\n */\nexport function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig {\n // Setup the initial config with any default properties\n let config: Partial = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(\n config,\n loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))\n );\n } else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n\n // We know that the config is complete, so we can cast\n const finalConfig = config as ApplauseConfig;\n\n validateConfig(finalConfig);\n\n return finalConfig;\n}\n\n/**\n * Overrides the configuration with the provided overrides.\n * @param config - The base configuration.\n * @param overrides - The overrides to apply.\n * @returns The overridden configuration.\n */\nexport function overrideConfig(\n config: Partial,\n overrides?: Partial\n): Partial {\n return Object.assign(\n {},\n config,\n Object.fromEntries(\n Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined)\n )\n );\n}\n\n/**\n * Checks if the configuration is complete.\n * @param config - The configuration to check.\n * @returns True if the configuration is complete, false otherwise.\n */\nexport function isComplete(config: Partial): boolean {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\n\n/**\n * Loads the configuration from the specified file.\n * @param configFile - The path to the configuration file.\n * @returns The loaded configuration from the file.\n */\nexport function loadConfigFromFile(\n configFile?: string\n): Partial {\n const configFilePath = configFile ?? `${process.cwd()}/applause.json`;\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileContents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileContents) as Partial;\n}\n\n/**\n * Validates the configuration.\n * @param config - The configuration to validate.\n * @throws Error if the configuration is invalid.\n */\nexport function validateConfig(config: ApplauseConfig) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\n\n/**\n * Validates a partial configuration.\n * @param config - The partial configuration to validate.\n * @throws Error if the partial configuration is invalid.\n */\nexport function validatePartialConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n"],"names":["validator","DEFAULT_URL","winston","TestResultStatus","AssetType","simpleParser","writeFileSync","pathJoin","TestRunAutoResultStatus","existsSync","readFileSync"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAO,MAAM,WAAW,GAAG,OAAO;;ACElC,MAAMA,WAAS,GAAG,SAAS,CAAC,OAAO,CAAC;AAU7B,MAAMC,aAAW,GAAG,2CAA2C,CAAC;AAEhE,MAAM,2BAA2B,GAA2B;AACjE,IAAA,cAAc,EAAEA,aAAW;CAC5B,CAAC;AAEI,SAAU,uBAAuB,CACrC,MAA8B,EAAA;AAE9B,IAAA,QACE,MAAM,CAAC,cAAc,KAAK,SAAS;QACnC,MAAM,CAAC,MAAM,KAAK,SAAS;AAC3B,QAAA,MAAM,CAAC,SAAS,KAAK,SAAS,EAC9B;AACJ,CAAC;AAaK,SAAU,qBAAqB,CAAC,MAAqB,EAAA;AACzD,IAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,EAAE;QAChE,MAAM,IAAI,KAAK,CACb,CAAA,4CAAA,EAA+C,MAAM,CAAC,SAAS,CAAG,CAAA,CAAA,CACnE,CAAC;KACH;IACD,IACE,CAACD,WAAS,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;AACtC,QAAA,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QAC5B,WAAW,EAAE,KAAK;AAClB,QAAA,sBAAsB,EAAE,KAAK;AAC7B,QAAA,aAAa,EAAE,IAAI;AACnB,QAAA,eAAe,EAAE,KAAK;AACtB,QAAA,4BAA4B,EAAE,KAAK;AACnC,QAAA,kBAAkB,EAAE,KAAK;AACzB,QAAA,YAAY,EAAE,IAAI;AAClB,QAAA,gBAAgB,EAAE,IAAI;AACvB,KAAA,CAAC,EACF;QACA,MAAM,IAAI,KAAK,CACb,CAAA,iDAAA,EAAoD,MAAM,CAAC,cAAc,CAAE,CAAA,CAC5E,CAAC;KACH;IAED,IAAIA,WAAS,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AACpC,QAAA,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;KAC/C;AACH;;AC/DA,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;MAEzB,0BAA0B,GAAGE,kBAAO,CAAC,MAAM,CAAC,MAAM,CAC7D,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAI;IACvC,OAAO,CAAA,EAAG,SAAS,CAAK,EAAA,EAAA,KAAK,KAAK,KAAK,CAAA,EAAA,EAAK,OAAO,CAAA,CAAE,CAAC;AACxD,CAAC,EACD;SAEc,sBAAsB,GAAA;IACpC,OAAOA,kBAAO,CAAC,YAAY,CAAC;AAC1B,QAAA,MAAM,EAAEA,kBAAO,CAAC,MAAM,CAAC,OAAO,CAC5BA,kBAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,EACjDA,kBAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAC1BA,kBAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EACtB,0BAA0B,CAC3B;AACD,QAAA,UAAU,EAAE;AACV,YAAA,IAAIA,kBAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;YACtE,IAAIA,kBAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AACzD,YAAA,IAAI,iBAAiB,EAAE;AACvB,YAAA,IAAIA,kBAAO,CAAC,UAAU,CAAC,OAAO,CAAC;AAC7B,gBAAA,KAAK,EAAE,MAAM;AACb,gBAAA,MAAM,EAAEA,kBAAO,CAAC,MAAM,CAAC,OAAO,CAC5BA,kBAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,EACzB,0BAA0B,CAC3B;aACF,CAAC;AACH,SAAA;AACF,KAAA,CAAC,CAAC;AACL,CAAC;AAED;;AAEG;MACU,gBAAgB,CAAA;IACnB,IAAI,GAAa,EAAE,CAAC;AAE5B;;;;AAIG;IACI,OAAO,GAAA;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC;KAClB;AAED;;;;AAIG;IACI,SAAS,GAAA;AACd,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,SAAS,EAAE,CAAC;AACjB,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;AAEG;IACI,SAAS,GAAA;AACd,QAAA,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;KAChB;AAED;;;;AAIG;AACI,IAAA,MAAM,CAAC,GAAW,EAAA;AACvB,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KACrB;AACF,CAAA;AAED;AACa,MAAA,oBAAoB,GAAqB,IAAI,gBAAgB,GAAG;AAE7E;;AAEG;AACG,MAAO,iBAAkB,SAAQ,eAAe,CAAA;AACpD,IAAA,WAAA,CAAY,IAA6C,EAAA;QACvD,KAAK,CAAC,IAAI,CAAC,CAAC;KACb;IAED,GAAG,CAAC,IAAuB,EAAE,QAAoB,EAAA;QAC/C,YAAY,CAAC,MAAK;AAChB,YAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC5B,SAAC,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;AAC7B,QAAA,oBAAoB,CAAC,MAAM,CACxB,IAAI,CAAC,OAAO,CAAwB,IAAK,IAAI,CAAC,OAAkB,CAClE,CAAC;;AAGF,QAAA,QAAQ,EAAE,CAAC;KACZ;AACF;;ACrGD;;;;AAIG;MAmBU,OAAO,CAAA;AAkBP,IAAA,OAAA,CAAA;AAjBM,IAAA,MAAM,CAAgB;AAE/B,IAAA,MAAM,CAAiB;AACvB,IAAA,aAAa,CAAS;AAC9B;;;AAGG;AACH,IAAA,IAAW,gBAAgB,GAAA;QACzB,OAAO,IAAI,CAAC,aAAa,CAAC;KAC3B;AAED;;;AAGG;IACH,WACW,CAAA,OAAsB,EAC/B,MAAuB,EAAA;QADd,IAAO,CAAA,OAAA,GAAP,OAAO,CAAe;AAG/B,QAAA,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;AACvB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,sBAAsB,EAAE,CAAC;QACjD,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YACzB,OAAO,EAAE,OAAO,CAAC,cAAc;AAC/B,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,OAAO,EAAE;gBACP,WAAW,EAAE,OAAO,CAAC,MAAM;AAC3B,gBAAA,cAAc,EAAE,kBAAkB;AACnC,aAAA;AACD,YAAA,YAAY,EAAE,MAAM;AACrB,SAAA,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CACnC,UAAU,QAAiC,EAAA;AACzC,YAAA,OAAO,QAAQ,CAAC;AAClB,SAAC,EACD,CAAC,KAAiB,KAAI;;AAEpB,YAAA,MAAM,OAAO;;AAEX,YAAA,KAAK,CAAC,QAAQ,EAAE,IAAI,KAAK,SAAS;kBAC9B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;AACrC,kBAAE,CAAA,YAAA,EAAe,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAiB,cAAA,EAAA,KAAK,CAAC,QAAQ,EAAE,UAAU,GAAG,CAAC;YAC1F,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAqB,kBAAA,EAAA,OAAO,CAAE,CAAA,CAAC,CAAC;AAClD,YAAA,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/B,SAAC,CACF,CAAC;KACH;AAED;;;;AAIG;IACH,MAAM,YAAY,CAChB,IAAsB,EAAA;AAEtB,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;YACF,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAC3B,2BAA2B,EAC3B;;AAEE,gBAAA,GAAG,IAAI;;gBAGP,UAAU,EAAE,CAAM,GAAA,EAAA,WAAW,CAAE,CAAA;;AAG/B,gBAAA,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;AAEjC,gBAAA,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB;;AAGhD,gBAAA,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,KAAK,SAAS;AACpE,gBAAA,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,iBAAiB;AAClE,gBAAA,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS;AAC1D,gBAAA,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO;AACtD,gBAAA,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,QAAQ;AACxD,gBAAA,eAAe,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO;AACtD,gBAAA,iCAAiC,EAC/B,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,6BAA6B;AAC9D,aAAA,CACF,CAAC;SACH;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;AAIG;IACH,MAAM,UAAU,CAAC,SAAiB,EAAA;AAChC,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;YACF,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAC7B,CAAsB,mBAAA,EAAA,SAAS,CAAwB,sBAAA,CAAA,CACxD,CAAC;SACH;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;AAIG;IACH,MAAM,aAAa,CACjB,MAA+B,EAAA;AAE/B,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAChC,qCAAqC,EACrC,MAAM,CACP,CAAC;AACF,YAAA,OAAO,GAAG,CAAC;SACZ;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;AAIG;IACH,MAAM,oBAAoB,CAAC,MAA+B,EAAA;AACxD,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;YACF,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;SACzD;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;AAIG;IACH,MAAM,uBAAuB,CAC3B,SAAmB,EAAA;AAEnB,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;;AAEF,YAAA,MAAM,QAAQ,GAAa,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAC3B,qCAAqC,EACrC,QAAQ,CACT,CAAC;SACH;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;AAIG;IACH,MAAM,gBAAgB,CAAC,SAAiB,EAAA;AACtC,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;;YAEF,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAO,yBAAyB,EAAE;AAC7D,gBAAA,SAAS,EAAE,SAAS;AACrB,aAAA,CAAC,CAAC;SACJ;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;AAIG;IACH,MAAM,eAAe,CACnB,WAAmB,EAAA;AAEnB,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;;YAEF,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAC1B,CAAsC,mCAAA,EAAA,WAAW,CAAE,CAAA,CACpD,CAAC;SACH;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;AAIG;IACH,MAAM,eAAe,CACnB,OAA0B,EAAA;AAE1B,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;;YAEF,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAC3B,gCAAgC,EAChC,OAAO,CACR,CAAC;SACH;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AAED;;;;;;;;AAQG;IACH,MAAM,WAAW,CACf,QAAgB,EAChB,IAAY,EACZ,SAAiB,EACjB,mBAA2B,EAC3B,SAAoB,EAAA;AAEpB,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AAExB,QAAA,IAAI;;YAEF,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAC/B,CAAA,sBAAA,EAAyB,QAAQ,CAAA,OAAA,CAAS,EAC1C;gBACE,IAAI;gBACJ,SAAS;gBACT,mBAAmB;gBACnB,SAAS;AACV,aAAA,CACF,CAAC;SACH;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AACF;;ACnMD;;AAEG;AACSC,kCAQX;AARD,CAAA,UAAY,gBAAgB,EAAA;AAC1B,IAAA,gBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,gBAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,gBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,gBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACrB,IAAA,gBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACjB,CAAC,EARWA,wBAAgB,KAAhBA,wBAAgB,GAQ3B,EAAA,CAAA,CAAA,CAAA;AAqCWC,2BAoBX;AApBD,CAAA,UAAY,SAAS,EAAA;AACnB,IAAA,SAAA,CAAA,YAAA,CAAA,GAAA,YAAyB,CAAA;AACzB,IAAA,SAAA,CAAA,oBAAA,CAAA,GAAA,oBAAyC,CAAA;AACzC,IAAA,SAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,SAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,SAAA,CAAA,YAAA,CAAA,GAAA,YAAyB,CAAA;AACzB,IAAA,SAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,SAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,SAAA,CAAA,YAAA,CAAA,GAAA,YAAyB,CAAA;AACzB,IAAA,SAAA,CAAA,cAAA,CAAA,GAAA,cAA6B,CAAA;AAC7B,IAAA,SAAA,CAAA,mBAAA,CAAA,GAAA,mBAAuC,CAAA;AACvC,IAAA,SAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,SAAA,CAAA,eAAA,CAAA,GAAA,eAA+B,CAAA;AAC/B,IAAA,SAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,SAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,SAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,SAAA,CAAA,aAAA,CAAA,GAAA,aAA2B,CAAA;AAC3B,IAAA,SAAA,CAAA,iBAAA,CAAA,GAAA,iBAAmC,CAAA;AACnC,IAAA,SAAA,CAAA,gBAAA,CAAA,GAAA,gBAAiC,CAAA;AACjC,IAAA,SAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACrB,CAAC,EApBWA,iBAAS,KAATA,iBAAS,GAoBpB,EAAA,CAAA,CAAA;;AChJD;;AAEG;MACU,KAAK,CAAA;AAOE,IAAA,YAAA,CAAA;AACR,IAAA,OAAA,CAAA;AAPV;;;;AAIG;IACH,WACkB,CAAA,YAAoB,EAC5B,OAAgB,EAAA;QADR,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAQ;QAC5B,IAAO,CAAA,OAAA,GAAP,OAAO,CAAS;KACtB;AAEJ;;;AAGG;AACH,IAAA,MAAM,QAAQ,GAAA;QACZ,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;YAC7C,YAAY,EAAE,IAAI,CAAC,YAAY;AAChC,SAAA,CAAC,CAAC;AACH,QAAA,OAAO,MAAMC,uBAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KACrC;AACF;;ACxBD;;AAEG;MACU,WAAW,CAAA;AACF,IAAA,OAAA,CAAA;AAApB,IAAA,WAAA,CAAoB,OAAgB,EAAA;QAAhB,IAAO,CAAA,OAAA,GAAP,OAAO,CAAS;KAAI;AAExC;;;;;AAKG;IACH,MAAM,QAAQ,CAAC,WAAmB,EAAA;AAChC,QAAA,MAAM,gBAAgB,GAAW,CAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,EAC/C,IAAI,CAAC,YAAY,CAAC;QACpB,OAAO,IAAI,KAAK,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;KAClD;AACF;;ACjBD;;AAEG;MACU,uBAAuB,CAAA;AAWvB,IAAA,SAAA,CAAA;AACA,IAAA,OAAA,CAAA;IAXH,OAAO,GAAG,KAAK,CAAC;AAChB,IAAA,aAAa,CAAiB;AACrB,IAAA,MAAM,CAAiB;AAExC;;;;AAIG;AACH,IAAA,WAAA,CACW,SAAiB,EACjB,OAAgB,EACzB,MAAuB,EAAA;QAFd,IAAS,CAAA,SAAA,GAAT,SAAS,CAAQ;QACjB,IAAO,CAAA,OAAA,GAAP,OAAO,CAAS;AAGzB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,sBAAsB,EAAE,CAAC;KAClD;AAED;;;AAGG;AACH,IAAA,MAAM,KAAK,GAAA;;AAET,QAAA,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;;AAGjB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,qBAAqB,EAAE,CAAC;KAC9B;AAED;;;AAGG;IACI,SAAS,GAAA;QACd,OAAO,IAAI,CAAC,OAAO,CAAC;KACrB;IAEO,qBAAqB,GAAA;AAC3B,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,OAAO;SACR;AACD,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACzE,MAAM,IAAI,CAAC,aAAa,EAAE,CAC3B,CAAC;KACH;AAEO,IAAA,MAAM,aAAa,GAAA;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACpD,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,IAAI,CAAC,qBAAqB,EAAE,CAAC;KAC9B;AAED;;;AAGG;AACH,IAAA,MAAM,GAAG,GAAA;AACP,QAAA,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE;AACpC,YAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;AACrB,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACnD,MAAM,IAAI,CAAC,aAAa,CAAC;AACzB,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;SAChE;AACD,QAAA,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;KAChC;AACF;;ACzEM,MAAM,wBAAwB,GAAW,YAAY;AACrD,MAAM,uBAAuB,GAAW,YAAY;AAE3C,SAAA,iBAAiB,CAC/B,YAAoB,EACpB,MAAuB,EAAA;IAEvB,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACnE,MAAM,eAAe,GACnB,OAAO;AACL,UAAE,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;AAC5D,SAAA,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1E,MAAM,eAAe,GACnB,OAAO;AACL,UAAE,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;AAC3D,SAAA,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;AAEzE,IAAA,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;QAC9B,CAAC,MAAM,IAAI,OAAO,EAAE,IAAI,CACtB,sDAAsD,CACvD,CAAC;KACH;AACD,IAAA,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;QAC9B,CAAC,MAAM,IAAI,OAAO,EAAE,IAAI,CACtB,sDAAsD,CACvD,CAAC;KACH;IACD,OAAO;AACL,QAAA,kBAAkB,EAAE,eAAe,CAAC,CAAC,CAAC;AACtC,QAAA,kBAAkB,EAAE,eAAe,CAAC,CAAC,CAAC;AACtC,QAAA,YAAY,EAAE,YAAY;AACvB,aAAA,OAAO,CAAC,8BAA8B,EAAE,EAAE,CAAC;AAC3C,aAAA,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;AACpB,aAAA,IAAI,EAAE;KACV,CAAC;AACJ;;ACtBA;;AAEG;MACU,gBAAgB,CAAA;AACnB,IAAA,OAAO,CAAU;AACjB,IAAA,WAAW,CAAiB;AAC5B,IAAA,MAAM,CAAiB;AACvB,IAAA,QAAQ,CAAwB;IAChC,UAAU,GAAY,KAAK,CAAC;IAC5B,WAAW,GAAY,KAAK,CAAC;AAErC;;;AAGG;IACH,WAAY,CAAA,MAAqB,EAAE,MAAuB,EAAA;AACxD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,sBAAsB,EAAE,CAAC;AACjD,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAChD,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC7C,QAAA,IAAI,KAAK,KAAK,SAAS,EAAE;YACvB,MAAM,CAAC,GAAG,IAAI,WAAW,CACvB,IAAI,CAAC,OAAO,EACZ,QAAQ,CAAC,KAAK,CAAC,EACf,SAAS,EACT,IAAI,CAAC,MAAM,CACZ,CAAC;AACF,YAAA,IAAI,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;SACxB;KACF;AAED;;;;;AAKG;IACI,MAAM,WAAW,CAAC,KAAgB,EAAA;AACvC,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,kEAAkE,CACnE,CAAC;AACF,YAAA,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;SACH;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AACtD,QAAA,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;AAChD,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;AACvB,QAAA,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,GAAG,mBAAmB,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC1E,OAAO,mBAAmB,CAAC,SAAS,CAAC;KACtC;AAED;;;;;;;AAOG;AACI,IAAA,MAAM,aAAa,CACxB,EAAU,EACV,YAAoB,EACpB,MAAiC,EAAA;AAEjC,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,+DAA+D,CAChE,CAAC;AACF,YAAA,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;SACH;AACD,QAAA,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;QACrC,OAAO,QAAQ,CAAC,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;KACzD;AAED;;;;;;;AAOG;AACI,IAAA,MAAM,oBAAoB,CAC/B,EAAU,EACV,MAAwB,EACxB,MAAuC,EAAA;AAEvC,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,qEAAqE,CACtE,CAAC;AACF,YAAA,MAAM,IAAI,KAAK,CACb,qEAAqE,CACtE,CAAC;SACH;AACD,QAAA,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;QACrC,OAAO,QAAQ,CAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;KAC1D;AAED;;;;AAIG;AACI,IAAA,MAAM,SAAS,GAAA;AACpB,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;AACjE,YAAA,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;SAChE;QACD,MAAM,IAAI,CAAC,QAAQ;aAChB,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;AACtC,aAAA,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC;KAC1C;AAED;;;;;;;;;AASG;IACI,MAAM,mBAAmB,CAC9B,EAAU,EACV,SAAiB,EACjB,mBAA2B,EAC3B,SAAoB,EACpB,KAAa,EAAA;AAEb,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,6DAA6D,CAC9D,CAAC;AACF,YAAA,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;SACH;QACD,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,IACtC,QAAQ,CAAC,mBAAmB,CAC1B,EAAE,EACF,SAAS,EACT,mBAAmB,EACnB,SAAS,EACT,KAAK,CACN,CACF,CAAC;KACH;AAED;;;AAGG;IACI,cAAc,GAAA;AACnB,QAAA,QACE,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC;AAC1D,YAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,EAClC;KACH;AACF,CAAA;AAED;;AAEG;MACU,cAAc,CAAA;AAGf,IAAA,OAAA,CAAA;AAFF,IAAA,MAAM,CAAiB;IAC/B,WACU,CAAA,OAAgB,EACxB,MAAuB,EAAA;QADf,IAAO,CAAA,OAAA,GAAP,OAAO,CAAS;AAGxB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,sBAAsB,EAAE,CAAC;KAClD;AAED;;;;;AAKG;IACH,MAAM,aAAa,CAAC,KAAgB,EAAA;QAClC,MAAM,YAAY,GAAG,KAAK;AACxB,cAAE,GAAG,CAAC,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAC1D,aAAA,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,qBAAqB,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;YAC5D,KAAK,EAAE,YAAY,IAAI,EAAE;AAC1B,SAAA,CAAC,CAAC;AACH,QAAA,IACE,qBAAqB,CAAC,MAAM,GAAG,GAAG;AAClC,YAAA,qBAAqB,CAAC,MAAM,GAAG,GAAG,EAClC;YACA,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,CAA2E,wEAAA,EAAA,qBAAqB,CAAC,MAAM,CAAG,CAAA,CAAA,CAC3G,CAAC;AACF,YAAA,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;SAC9C;AACD,QAAA,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAY,SAAA,EAAA,KAAK,CAAc,YAAA,CAAA,CAAC,CAAC;AAClD,QAAA,MAAM,gBAAgB,GAAG,IAAI,uBAAuB,CAClD,KAAK,EACL,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,MAAM,CACZ,CAAC;AACF,QAAA,MAAM,gBAAgB,CAAC,KAAK,EAAE,CAAC;AAC/B,QAAA,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;KAC5E;AACF,CAAA;AAED;;AAEG;MACU,WAAW,CAAA;AAYZ,IAAA,OAAA,CAAA;AACQ,IAAA,SAAA,CAAA;AACR,IAAA,gBAAA,CAAA;IAbF,gBAAgB,GAAoC,EAAE,CAAC;IACvD,mBAAmB,GAAoC,EAAE,CAAC;AAC1D,IAAA,MAAM,CAAiB;AAE/B;;;;;AAKG;AACH,IAAA,WAAA,CACU,OAAgB,EACR,SAAiB,EACzB,gBAA0C,EAClD,MAAuB,EAAA;QAHf,IAAO,CAAA,OAAA,GAAP,OAAO,CAAS;QACR,IAAS,CAAA,SAAA,GAAT,SAAS,CAAQ;QACzB,IAAgB,CAAA,gBAAA,GAAhB,gBAAgB,CAA0B;AAGlD,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,sBAAsB,EAAE,CAAC;KAClD;AAED;;;;;;;AAOG;AACI,IAAA,aAAa,CAClB,EAAU,EACV,YAAoB,EACpB,MAAiC,EAAA;QAEjC,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAC9C,YAAA,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;SAC7C;QACD,MAAM,cAAc,GAAG,iBAAiB,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AACpE,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO;AAC5B,aAAA,aAAa,CAAC;YACb,YAAY,EAAE,cAAc,CAAC,YAAY;YACzC,UAAU,EAAE,cAAc,CAAC,kBAAkB;YAC7C,aAAa,EAAE,cAAc,CAAC,kBAAkB;YAEhD,SAAS,EAAE,IAAI,CAAC,SAAS;;AAEzB,YAAA,GAAG,MAAM,CAAC,WAAW,CACnB,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CACjE;SACF,CAAC;aACD,IAAI,CAAC,GAAG,IAAG;AACV,YAAA,OAAO,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,SAAC,CAAC,CAAC;AACL,QAAA,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC;AACvC,QAAA,OAAO,UAAU,CAAC;KACnB;AAED;;;;;;;AAOG;AACI,IAAA,oBAAoB,CACzB,EAAU,EACV,MAAwB,EACxB,MAAuC,EAAA;AAEvC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,IACzD,IAAI,CAAC,OAAO;AACT,aAAA,oBAAoB,CAAC;AACpB,YAAA,MAAM,EAAE,MAAM;AACd,YAAA,YAAY,EAAE,QAAQ;AACtB,YAAA,GAAG,MAAM;SACV,CAAC;AACD,aAAA,IAAI,CAAC,MAAM,QAAQ,CAAC,CACxB,CAAC;AACF,QAAA,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC;AAC1C,QAAA,OAAO,UAAU,CAAC;KACnB;AAED;;;;;;;;;AASG;IACI,MAAM,mBAAmB,CAC9B,EAAU,EACV,SAAiB,EACjB,mBAA2B,EAC3B,SAAoB,EACpB,KAAa,EAAA;AAEb,QAAA,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,IAC5C,IAAI,CAAC,OAAO,CAAC,WAAW,CACtB,QAAQ,EACR,KAAK,EACL,SAAS,EACT,mBAAmB,EACnB,SAAS,CACV,CACF,CAAC;KACH;AAED;;;AAGG;AACI,IAAA,MAAM,SAAS,GAAA;;QAEpB,MAAM,SAAS,GACb,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,EAAE,CAAC;;AAGlE,QAAA,MAAM,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;;QAGlE,MAAM,MAAM,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;AAC1C,QAAA,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;;QAGrD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;AACnE,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;AAClC,QAAA,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;AACxB,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;;YAE5C,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,YAAAC,gBAAa,CACXC,SAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC,EACxC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CACnC,CAAC;SACH;KACF;AACF;;AC1WWC,yCAMX;AAND,CAAA,UAAY,uBAAuB,EAAA;AACjC,IAAA,uBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,uBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,uBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,uBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACrB,IAAA,uBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACjB,CAAC,EANWA,+BAAuB,KAAvBA,+BAAuB,GAMlC,EAAA,CAAA,CAAA;;ACdD,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC;AAS7B,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEhD,MAAM,6BAA6B,GAA6B;AACrE,IAAA,gBAAgB,EAAE,WAAW;CAC9B,CAAC;AAEI,SAAU,yBAAyB,CACvC,MAAgC,EAAA;AAEhC,IAAA,QACE,MAAM,CAAC,gBAAgB,KAAK,SAAS;QACrC,MAAM,CAAC,MAAM,KAAK,SAAS;AAC3B,QAAA,MAAM,CAAC,SAAS,KAAK,SAAS,EAC9B;AACJ,CAAC;AAeK,SAAU,uBAAuB,CAAC,MAAuB,EAAA;AAC7D,IAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,EAAE;QAChE,MAAM,IAAI,KAAK,CACb,CAAA,4CAAA,EAA+C,MAAM,CAAC,SAAS,CAAG,CAAA,CAAA,CACnE,CAAC;KACH;IACD,IACE,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE;AACxC,QAAA,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;QAC5B,WAAW,EAAE,KAAK;AAClB,QAAA,sBAAsB,EAAE,KAAK;AAC7B,QAAA,aAAa,EAAE,IAAI;AACnB,QAAA,eAAe,EAAE,KAAK;AACtB,QAAA,4BAA4B,EAAE,KAAK;AACnC,QAAA,kBAAkB,EAAE,KAAK;AACzB,QAAA,YAAY,EAAE,IAAI;AAClB,QAAA,gBAAgB,EAAE,IAAI;AACvB,KAAA,CAAC,EACF;QACA,MAAM,IAAI,KAAK,CACb,CAAA,mDAAA,EAAsD,MAAM,CAAC,gBAAgB,CAAE,CAAA,CAChF,CAAC;KACH;IAED,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AACpC,QAAA,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;KAC/C;AACH;;MCzDa,SAAS,CAAA;AAaT,IAAA,OAAA,CAAA;AAZM,IAAA,MAAM,CAAgB;AAE/B,IAAA,aAAa,CAAS;AACtB,IAAA,MAAM,CAAiB;AAC/B;;AAEG;AACH,IAAA,IAAW,gBAAgB,GAAA;QACzB,OAAO,IAAI,CAAC,aAAa,CAAC;KAC3B;IAED,WACW,CAAA,OAAwB,EACjC,MAAuB,EAAA;QADd,IAAO,CAAA,OAAA,GAAP,OAAO,CAAiB;AAGjC,QAAA,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;AACvB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,sBAAsB,EAAE,CAAC;QACjD,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YACzB,OAAO,EAAE,OAAO,CAAC,gBAAgB;AACjC,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,OAAO,EAAE;gBACP,WAAW,EAAE,OAAO,CAAC,MAAM;AAC3B,gBAAA,cAAc,EAAE,kBAAkB;AACnC,aAAA;AACD,YAAA,YAAY,EAAE,MAAM;AACrB,SAAA,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CACnC,UAAU,QAAiC,EAAA;AACzC,YAAA,OAAO,QAAQ,CAAC;AAClB,SAAC,EACD,CAAC,KAAiB,KAAI;;AAEpB,YAAA,MAAM,OAAO;;AAEX,YAAA,KAAK,CAAC,QAAQ,EAAE,IAAI,KAAK,SAAS;kBAC9B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;AACrC,kBAAE,CAAA,YAAA,EAAe,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAiB,cAAA,EAAA,KAAK,CAAC,QAAQ,EAAE,UAAU,GAAG,CAAC;YAC1F,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAuB,oBAAA,EAAA,OAAO,CAAE,CAAA,CAAC,CAAC;AACpD,YAAA,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/B,SAAC,CACF,CAAC;KACH;AAED,IAAA,MAAM,YAAY,CAChB,UAAkB,EAClB,IAA0B,EAAA;AAE1B,QAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI;AACF,YAAA,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAC3B,CAAA,qBAAA,EAAwB,UAAU,CAAA,OAAA,CAAS,EAC3C,IAAI,CACL,CAAC;SACH;gBAAS;AACR,YAAA,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC;SACzB;KACF;AACF;;ACpED;;AAEG;AA2BH;;;;;AAKG;AACG,SAAU,UAAU,CAAC,WAAkC,EAAA;;AAE3D,IAAA,IAAI,MAAM,GAA4B;AACpC,QAAA,GAAG,6BAA6B;AAChC,QAAA,GAAG,2BAA2B;KAC/B,CAAC;;IAGF,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,CAAC,UAAU,KAAK,SAAS,EAAE;QACrE,MAAM,GAAG,cAAc,CACrB,MAAM,EACN,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CACrE,CAAC;KACH;SAAM;;QAEL,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;KACvD;;IAGD,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,CAAC,UAAU,KAAK,SAAS,EAAE;QACrE,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;KACzD;AAED,IAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;AACvB,QAAA,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;KAC3C;;IAGD,MAAM,WAAW,GAAG,MAAwB,CAAC;IAE7C,cAAc,CAAC,WAAW,CAAC,CAAC;AAE5B,IAAA,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;AAKG;AACa,SAAA,cAAc,CAC5B,MAA+B,EAC/B,SAAmC,EAAA;AAEnC,IAAA,OAAO,MAAM,CAAC,MAAM,CAClB,EAAE,EACF,MAAM,EACN,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CACpE,CACF,CAAC;AACJ,CAAC;AAED;;;;AAIG;AACG,SAAU,UAAU,CAAC,MAA+B,EAAA;IACxD,OAAO,uBAAuB,CAAC,MAAM,CAAC,IAAI,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAC9E,CAAC;AAED;;;;AAIG;AACG,SAAU,kBAAkB,CAChC,UAAmB,EAAA;IAEnB,MAAM,cAAc,GAAG,UAAU,IAAI,CAAA,EAAG,OAAO,CAAC,GAAG,EAAE,CAAA,cAAA,CAAgB,CAAC;AACtE,IAAA,IAAI,CAACC,aAAU,CAAC,cAAc,CAAC,EAAE;AAC/B,QAAA,OAAO,EAAE,CAAC;KACX;IACD,MAAM,YAAY,GAAGC,eAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AAC1D,IAAA,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAA4B,CAAC;AAC7D,CAAC;AAED;;;;AAIG;AACG,SAAU,cAAc,CAAC,MAAsB,EAAA;IACnD,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;;;AAIG;AACG,SAAU,qBAAqB,CAAC,MAA+B,EAAA;AACnE,IAAA,IACE,MAAM,CAAC,SAAS,KAAK,SAAS;AAC9B,SAAC,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,EAC9D;QACA,MAAM,IAAI,KAAK,CACb,CAAA,4CAAA,EAA+C,MAAM,CAAC,SAAS,CAAG,CAAA,CAAA,CACnE,CAAC;KACH;AACH;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/dist/index.min.js b/dist/index.min.js index 6e9497c..a85414c 100644 --- a/dist/index.min.js +++ b/dist/index.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("axios"),require("validator"),require("winston"),require("winston-transport"),require("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","winston","winston-transport","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.winston,t.TransportStream,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,r,a,n,o){"use strict";function l(t){var e=Object.create(null);return t&&Object.keys(t).forEach((function(s){if("default"!==s){var i=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,i.get?i:{enumerable:!0,get:function(){return t[s]}})}})),e.default=t,Object.freeze(e)}var u=l(i);const p=s.default,d={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function c(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!p.isURL(t.autoApiBaseUrl,{protocols:["http","https"],require_tld:!1,allow_query_components:!1,disallow_auth:!0,allow_fragments:!1,allow_protocol_relative_urls:!1,allow_trailing_dot:!1,require_host:!0,require_protocol:!0}))throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${t.autoApiBaseUrl}`);if(p.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}const h=Symbol.for("message"),g=u.format.printf((({level:t,message:e,label:s,timestamp:i})=>`${i} [${s}] ${t}: ${e}`));function E(){return u.createLogger({format:u.format.combine(u.format.label({label:"Applause Tests"}),u.format.timestamp(),u.format.splat(),g),transports:[new u.transports.File({filename:"error.log",level:"error"}),new u.transports.File({filename:"combined.log"}),new f,new u.transports.Console({level:"info",format:u.format.combine(u.format.colorize(),g)})]})}class I{logs=[];getLogs(){return this.logs}drainLogs(){const t=this.logs;return this.clearLogs(),t}clearLogs(){this.logs=[]}addLog(t){this.logs.push(t)}}const R=new I;class f extends r{constructor(t){super(t)}log(t,e){setImmediate((()=>{this.emit("logged",t)})),this.format?.transform(t),R.addLog(t[h]??t.message),e()}}class A{options;client;logger;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t,s){this.options=t,this.callsInFlight=0,this.logger=s??E(),c(t),this.client=e.create({baseURL:t.autoApiBaseUrl,timeout:1e4,headers:{"X-Api-Key":t.apiKey,"Context-Type":"application/json"},responseType:"json"}),this.client.interceptors.response.use((function(t){return t}),(t=>{const e=void 0!==t.response?.data?JSON.stringify(t.response.data):`error-code [${t.response?.status}] with error [${t.response?.statusText}]`;return this.logger.error(`Auto-Api returned ${e}`),Promise.reject(t)}))}async startTestRun(t){this.callsInFlight+=1;try{return await this.client.post("/api/v1.0/test-run/create",{...t,sdkVersion:"js:1.1.0",productId:this.options.productId,applauseTestCycleId:this.options.applauseTestCycleId,testRailReportingEnabled:void 0!==this.options.testRailOptions,addAllTestsToPlan:this.options.testRailOptions?.addAllTestsToPlan,testRailProjectId:this.options.testRailOptions?.projectId,testRailSuiteId:this.options.testRailOptions?.suiteId,testRailPlanName:this.options.testRailOptions?.planName,testRailRunName:this.options.testRailOptions?.runName,overrideTestRailRunNameUniqueness:this.options.testRailOptions?.overrideTestRailRunUniqueness})}finally{this.callsInFlight-=1}}async endTestRun(t){this.callsInFlight+=1;try{return await this.client.delete(`/api/v1.0/test-run/${t}?endingStatus=COMPLETE`)}finally{this.callsInFlight-=1}}async startTestCase(t){this.callsInFlight+=1;try{return await this.client.post("/api/v1.0/test-result/create-result",t)}finally{this.callsInFlight-=1}}async submitTestCaseResult(t){this.callsInFlight+=1;try{await this.client.post("/api/v1.0/test-result",t)}finally{this.callsInFlight-=1}}async getProviderSessionLinks(t){this.callsInFlight+=1;try{const e=t.filter((t=>t));return await this.client.post("/api/v1.0/test-result/provider-info",e)}finally{this.callsInFlight-=1}}async sendSdkHeartbeat(t){this.callsInFlight+=1;try{return await this.client.post("/api/v2.0/sdk-heartbeat",{testRunId:t})}finally{this.callsInFlight-=1}}async getEmailAddress(t){this.callsInFlight+=1;try{return await this.client.get(`/api/v1.0/email/get-address?prefix=${t}`)}finally{this.callsInFlight-=1}}async getEmailContent(t){this.callsInFlight+=1;try{return await this.client.post("/api/v1.0/email/download-email",t)}finally{this.callsInFlight-=1}}async uploadAsset(t,e,s,i,r){this.callsInFlight+=1;try{return await this.client.postForm(`/api/v1.0/test-result/${t}/upload`,{file:e,assetName:s,providerSessionGuid:i,assetType:r})}finally{this.callsInFlight-=1}}}var m,w;t.TestResultStatus=void 0,(m=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",m.IN_PROGRESS="IN_PROGRESS",m.PASSED="PASSED",m.FAILED="FAILED",m.SKIPPED="SKIPPED",m.CANCELED="CANCELED",m.ERROR="ERROR",t.AssetType=void 0,(w=t.AssetType||(t.AssetType={})).SCREENSHOT="SCREENSHOT",w.FAILURE_SCREENSHOT="FAILURE_SCREENSHOT",w.VIDEO="VIDEO",w.NETWORK_HAR="NETWORK_HAR",w.VITALS_LOG="VITALS_LOG",w.CONSOLE_LOG="CONSOLE_LOG",w.NETWORK_LOG="NETWORK_LOG",w.DEVICE_LOG="DEVICE_LOG",w.SELENIUM_LOG="SELENIUM_LOG",w.SELENIUM_LOG_JSON="SELENIUM_LOG_JSON",w.BROWSER_LOG="BROWSER_LOG",w.FRAMEWORK_LOG="FRAMEWORK_LOG",w.EMAIL="EMAIL",w.PAGE_SOURCE="PAGE_SOURCE",w.CODE_BUNDLE="CODE_BUNDLE",w.RESULTS_ZIP="RESULTS_ZIP",w.SESSION_DETAILS="SESSION_DETAILS",w.DEVICE_DETAILS="DEVICE_DETAILS",w.UNKNOWN="UNKNOWN";class S{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await a.simpleParser(t.data)}}class T{testRunId;autoApi;enabled=!1;nextHeartbeat;logger;constructor(t,e,s){this.testRunId=t,this.autoApi=e,this.logger=s??E()}async start(){await this.end(),this.enabled=!0,this.scheduleNextHeartbeat()}isEnabled(){return this.enabled}scheduleNextHeartbeat(){this.enabled&&(this.nextHeartbeat=new Promise((t=>setTimeout(t,5e3))).then((()=>this.sendHeartbeat())))}async sendHeartbeat(){this.logger.debug("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),this.logger.debug("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,this.logger.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,this.logger.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}const y="TestRail-",b="Applause-";function O(t,e){const s=t.match(/(TestRail-\d+|Applause-\d+)/g),i=s?.filter((t=>t.startsWith(y))).map((t=>t.substring(9)))??[],r=s?.filter((t=>t.startsWith(b))).map((t=>t.substring(9)))??[];return i.length>1&&(e??console).warn("Multiple TestRail case ids detected in testCase name"),r.length>1&&(e??console).warn("Multiple Applause case ids detected in testCase name"),{applauseTestCaseId:r[0],testRailTestCaseId:i[0],testCaseName:t.replace(/(TestRail-\d+|Applause-\d+)/g,"").replace(/\s+/g," ").trim()}}class v{autoApi;logger;constructor(t,e){this.autoApi=t,this.logger=e??E()}async initializeRun(t){const e=t?.map((t=>O(t,this.logger))).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e??[]});if(s.status<200||s.status>300)throw this.logger.error(`Failed to create Applause Test Run: received error response with status ${s.status}.`),new Error("Unable to create test run");const i=s.data.runId;this.logger.info(`Test Run ${i} initialized`);const r=new T(i,this.autoApi,this.logger);return await r.start(),new C(this.autoApi,i,r,this.logger)}}class C{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};logger;constructor(t,e,s,i){this.autoApi=t,this.testRunId=e,this.heartbeatService=s,this.logger=i??E()}startTestCase(t,e,s){if(!e)throw this.logger.error("testCaseName is required"),new Error("testCaseName is required");const i=O(e,this.logger),r=this.autoApi.startTestCase({testCaseName:i.testCaseName,testCaseId:i.testRailTestCaseId,itwTestCaseId:i.applauseTestCaseId,testRunId:this.testRunId,...Object.fromEntries(Object.entries(s||{}).filter((([t,e])=>void 0!==e)))}).then((t=>t.data.testResultId));return this.uidToResultIdMap[t]=r,r}submitTestCaseResult(t,e,s){const i=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s}).then((()=>t))));return this.resultSubmissionMap[t]=i,i}async attachTestCaseAsset(t,e,s,i,r){await(this.uidToResultIdMap[t]?.then((t=>this.autoApi.uploadAsset(t,r,e,s,i))))}async runnerEnd(){const t=await Promise.all(Object.values(this.uidToResultIdMap))??[];await Promise.all(Object.values(this.resultSubmissionMap)),await(this.heartbeatService?.end()),await this.autoApi.endTestRun(this.testRunId);const e=(await this.autoApi.getProviderSessionLinks(t)).data??[];if(e.length>0){this.logger.info(JSON.stringify(e));const t=".";n.writeFileSync(o.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}var _;t.TestRunAutoResultStatus=void 0,(_=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",_.FAILED="FAILED",_.SKIPPED="SKIPPED",_.CANCELED="CANCELED",_.ERROR="ERROR";const L=s.default,N={publicApiBaseUrl:"https://api.applause.com/"};function F(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!L.isURL(t.publicApiBaseUrl,{protocols:["http","https"],require_tld:!1,allow_query_components:!1,disallow_auth:!0,allow_fragments:!1,allow_protocol_relative_urls:!1,allow_trailing_dot:!1,require_host:!0,require_protocol:!0}))throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${t.publicApiBaseUrl}`);if(L.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function P(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e??{}).filter((([t,e])=>void 0!==e))))}function U(t){return function(t){return void 0!==t.autoApiBaseUrl&&void 0!==t.apiKey&&void 0!==t.productId}(t)&&function(t){return void 0!==t.publicApiBaseUrl&&void 0!==t.apiKey&&void 0!==t.productId}(t)}function D(t){const e=t??`${process.cwd()}/applause.json`;if(!n.existsSync(e))return{};const s=n.readFileSync(e,"utf8");return JSON.parse(s)}function H(t){c(t),F(t)}t.APPLAUSE_CASE_ID_PREFIX=b,t.APPLAUSE_LOG_RECORDS=R,t.ApplauseReporter=class{autoApi;initializer;logger;reporter;runStarted=!1;runFinished=!1;constructor(t,e){this.logger=e??E(),this.autoApi=new A(t,this.logger),this.initializer=new v(this.autoApi,this.logger);const s=process.env.APPLAUSE_RUN_ID;if(void 0!==s){const t=new C(this.autoApi,parseInt(s),void 0,this.logger);this.reporter=new Promise((e=>e(t))),this.runStarted=!0}}async runnerStart(t){if(void 0!==this.reporter)throw this.logger.error("Cannot start a run - run already started or run already finished"),new Error("Cannot start a run - run already started or run already finished");this.reporter=this.initializer.initializeRun(t);const e=await this.reporter;return this.runStarted=!0,process.env.APPLAUSE_RUN_ID=e.testRunId.toString(),e.testRunId}async startTestCase(t,e,s){if(void 0===this.reporter)throw this.logger.error("Cannot start a test case for a run that was never initialized"),new Error("Cannot start a test case for a run that was never initialized");return(await this.reporter).startTestCase(t,e,s)}async submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw this.logger.error("Cannot submit test case result for a run that was never initialized"),new Error("Cannot submit test case result for a run that was never initialized");return(await this.reporter).submitTestCaseResult(t,e,s)}async runnerEnd(){if(void 0===this.reporter)throw this.logger.error("Cannot end a run that was never initialized"),new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}async attachTestCaseAsset(t,e,s,i,r){if(void 0===this.reporter)throw this.logger.error("Cannot attach an asset for a run that was never initialized"),new Error("Cannot attach an asset for a run that was never initialized");return await this.reporter.then((a=>a.attachTestCaseAsset(t,e,s,i,r)))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.ApplauseTransport=f,t.AutoApi=A,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new S(e,this.autoApi)}},t.Inbox=S,t.LoggingContainer=I,t.PublicApi=class{options;client;callsInFlight;logger;get getCallsInFlight(){return this.callsInFlight}constructor(t,s){this.options=t,this.callsInFlight=0,this.logger=s??E(),F(t),this.client=e.create({baseURL:t.publicApiBaseUrl,timeout:1e4,headers:{"X-Api-Key":t.apiKey,"Context-Type":"application/json"},responseType:"json"}),this.client.interceptors.response.use((function(t){return t}),(t=>{const e=void 0!==t.response?.data?JSON.stringify(t.response.data):`error-code [${t.response?.status}] with error [${t.response?.statusText}]`;return this.logger.error(`Public-Api returned ${e}`),Promise.reject(t)}))}async submitResult(t,e){this.callsInFlight+=1;try{return await this.client.post(`v2/test-case-results/${t}/submit`,e)}finally{this.callsInFlight-=1}}},t.RunInitializer=v,t.RunReporter=C,t.TEST_RAIL_CASE_ID_PREFIX=y,t.TestRunHeartbeatService=T,t.WINSTON_DEFAULT_LOG_FORMAT=g,t.constructDefaultLogger=E,t.isComplete=U,t.loadConfig=function(t){let e={...N,...d};if(e=void 0!==t&&void 0!==t.configFile?P(e,D(o.join(process.cwd(),t.configFile))):P(e,D()),void 0!==t&&void 0!==t.properties&&(e=P(e,t.properties)),!U(e))throw new Error("Config is not complete");const s=e;return H(s),s},t.loadConfigFromFile=D,t.overrideConfig=P,t.parseTestCaseName=O,t.validateConfig=H,t.validatePartialConfig=function(t){if(void 0!==t.productId&&(!Number.isInteger(t.productId)||t.productId<=0))throw new Error(`productId must be a positive integer, was: '${t.productId}'`)}})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("axios"),require("validator"),require("winston"),require("winston-transport"),require("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","winston","winston-transport","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.winston,t.TransportStream,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,r,a,n,o){"use strict";function l(t){var e=Object.create(null);return t&&Object.keys(t).forEach((function(s){if("default"!==s){var i=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,i.get?i:{enumerable:!0,get:function(){return t[s]}})}})),e.default=t,Object.freeze(e)}var u=l(i);const p=s.default,d={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function c(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!p.isURL(t.autoApiBaseUrl,{protocols:["http","https"],require_tld:!1,allow_query_components:!1,disallow_auth:!0,allow_fragments:!1,allow_protocol_relative_urls:!1,allow_trailing_dot:!1,require_host:!0,require_protocol:!0}))throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${t.autoApiBaseUrl}`);if(p.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}const h=Symbol.for("message"),g=u.format.printf((({level:t,message:e,label:s,timestamp:i})=>`${i} [${s}] ${t}: ${e}`));function E(){return u.createLogger({format:u.format.combine(u.format.label({label:"Applause Tests"}),u.format.timestamp(),u.format.splat(),g),transports:[new u.transports.File({filename:"error.log",level:"error"}),new u.transports.File({filename:"combined.log"}),new f,new u.transports.Console({level:"info",format:u.format.combine(u.format.colorize(),g)})]})}class I{logs=[];getLogs(){return this.logs}drainLogs(){const t=this.logs;return this.clearLogs(),t}clearLogs(){this.logs=[]}addLog(t){this.logs.push(t)}}const R=new I;class f extends r{constructor(t){super(t)}log(t,e){setImmediate((()=>{this.emit("logged",t)})),this.format?.transform(t),R.addLog(t[h]??t.message),e()}}class A{options;client;logger;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t,s){this.options=t,this.callsInFlight=0,this.logger=s??E(),c(t),this.client=e.create({baseURL:t.autoApiBaseUrl,timeout:1e4,headers:{"X-Api-Key":t.apiKey,"Context-Type":"application/json"},responseType:"json"}),this.client.interceptors.response.use((function(t){return t}),(t=>{const e=void 0!==t.response?.data?JSON.stringify(t.response.data):`error-code [${t.response?.status}] with error [${t.response?.statusText}]`;return this.logger.error(`Auto-Api returned ${e}`),Promise.reject(t)}))}async startTestRun(t){this.callsInFlight+=1;try{return await this.client.post("/api/v1.0/test-run/create",{...t,sdkVersion:"js:1.1.0",productId:this.options.productId,itwTestCycleId:this.options.applauseTestCycleId,testRailReportingEnabled:void 0!==this.options.testRailOptions,addAllTestsToPlan:this.options.testRailOptions?.addAllTestsToPlan,testRailProjectId:this.options.testRailOptions?.projectId,testRailSuiteId:this.options.testRailOptions?.suiteId,testRailPlanName:this.options.testRailOptions?.planName,testRailRunName:this.options.testRailOptions?.runName,overrideTestRailRunNameUniqueness:this.options.testRailOptions?.overrideTestRailRunUniqueness})}finally{this.callsInFlight-=1}}async endTestRun(t){this.callsInFlight+=1;try{return await this.client.delete(`/api/v1.0/test-run/${t}?endingStatus=COMPLETE`)}finally{this.callsInFlight-=1}}async startTestCase(t){this.callsInFlight+=1;try{return await this.client.post("/api/v1.0/test-result/create-result",t)}finally{this.callsInFlight-=1}}async submitTestCaseResult(t){this.callsInFlight+=1;try{await this.client.post("/api/v1.0/test-result",t)}finally{this.callsInFlight-=1}}async getProviderSessionLinks(t){this.callsInFlight+=1;try{const e=t.filter((t=>t));return await this.client.post("/api/v1.0/test-result/provider-info",e)}finally{this.callsInFlight-=1}}async sendSdkHeartbeat(t){this.callsInFlight+=1;try{return await this.client.post("/api/v2.0/sdk-heartbeat",{testRunId:t})}finally{this.callsInFlight-=1}}async getEmailAddress(t){this.callsInFlight+=1;try{return await this.client.get(`/api/v1.0/email/get-address?prefix=${t}`)}finally{this.callsInFlight-=1}}async getEmailContent(t){this.callsInFlight+=1;try{return await this.client.post("/api/v1.0/email/download-email",t)}finally{this.callsInFlight-=1}}async uploadAsset(t,e,s,i,r){this.callsInFlight+=1;try{return await this.client.postForm(`/api/v1.0/test-result/${t}/upload`,{file:e,assetName:s,providerSessionGuid:i,assetType:r})}finally{this.callsInFlight-=1}}}var m,w;t.TestResultStatus=void 0,(m=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",m.IN_PROGRESS="IN_PROGRESS",m.PASSED="PASSED",m.FAILED="FAILED",m.SKIPPED="SKIPPED",m.CANCELED="CANCELED",m.ERROR="ERROR",t.AssetType=void 0,(w=t.AssetType||(t.AssetType={})).SCREENSHOT="SCREENSHOT",w.FAILURE_SCREENSHOT="FAILURE_SCREENSHOT",w.VIDEO="VIDEO",w.NETWORK_HAR="NETWORK_HAR",w.VITALS_LOG="VITALS_LOG",w.CONSOLE_LOG="CONSOLE_LOG",w.NETWORK_LOG="NETWORK_LOG",w.DEVICE_LOG="DEVICE_LOG",w.SELENIUM_LOG="SELENIUM_LOG",w.SELENIUM_LOG_JSON="SELENIUM_LOG_JSON",w.BROWSER_LOG="BROWSER_LOG",w.FRAMEWORK_LOG="FRAMEWORK_LOG",w.EMAIL="EMAIL",w.PAGE_SOURCE="PAGE_SOURCE",w.CODE_BUNDLE="CODE_BUNDLE",w.RESULTS_ZIP="RESULTS_ZIP",w.SESSION_DETAILS="SESSION_DETAILS",w.DEVICE_DETAILS="DEVICE_DETAILS",w.UNKNOWN="UNKNOWN";class S{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await a.simpleParser(t.data)}}class T{testRunId;autoApi;enabled=!1;nextHeartbeat;logger;constructor(t,e,s){this.testRunId=t,this.autoApi=e,this.logger=s??E()}async start(){await this.end(),this.enabled=!0,this.scheduleNextHeartbeat()}isEnabled(){return this.enabled}scheduleNextHeartbeat(){this.enabled&&(this.nextHeartbeat=new Promise((t=>setTimeout(t,5e3))).then((()=>this.sendHeartbeat())))}async sendHeartbeat(){this.logger.debug("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),this.logger.debug("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,this.logger.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,this.logger.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}const y="TestRail-",b="Applause-";function O(t,e){const s=t.match(/(TestRail-\d+|Applause-\d+)/g),i=s?.filter((t=>t.startsWith(y))).map((t=>t.substring(9)))??[],r=s?.filter((t=>t.startsWith(b))).map((t=>t.substring(9)))??[];return i.length>1&&(e??console).warn("Multiple TestRail case ids detected in testCase name"),r.length>1&&(e??console).warn("Multiple Applause case ids detected in testCase name"),{applauseTestCaseId:r[0],testRailTestCaseId:i[0],testCaseName:t.replace(/(TestRail-\d+|Applause-\d+)/g,"").replace(/\s+/g," ").trim()}}class v{autoApi;logger;constructor(t,e){this.autoApi=t,this.logger=e??E()}async initializeRun(t){const e=t?.map((t=>O(t,this.logger))).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e??[]});if(s.status<200||s.status>300)throw this.logger.error(`Failed to create Applause Test Run: received error response with status ${s.status}.`),new Error("Unable to create test run");const i=s.data.runId;this.logger.info(`Test Run ${i} initialized`);const r=new T(i,this.autoApi,this.logger);return await r.start(),new C(this.autoApi,i,r,this.logger)}}class C{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};logger;constructor(t,e,s,i){this.autoApi=t,this.testRunId=e,this.heartbeatService=s,this.logger=i??E()}startTestCase(t,e,s){if(!e)throw this.logger.error("testCaseName is required"),new Error("testCaseName is required");const i=O(e,this.logger),r=this.autoApi.startTestCase({testCaseName:i.testCaseName,testCaseId:i.testRailTestCaseId,itwTestCaseId:i.applauseTestCaseId,testRunId:this.testRunId,...Object.fromEntries(Object.entries(s||{}).filter((([t,e])=>void 0!==e)))}).then((t=>t.data.testResultId));return this.uidToResultIdMap[t]=r,r}submitTestCaseResult(t,e,s){const i=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s}).then((()=>t))));return this.resultSubmissionMap[t]=i,i}async attachTestCaseAsset(t,e,s,i,r){await(this.uidToResultIdMap[t]?.then((t=>this.autoApi.uploadAsset(t,r,e,s,i))))}async runnerEnd(){const t=await Promise.all(Object.values(this.uidToResultIdMap))??[];await Promise.all(Object.values(this.resultSubmissionMap)),await(this.heartbeatService?.end()),await this.autoApi.endTestRun(this.testRunId);const e=(await this.autoApi.getProviderSessionLinks(t)).data??[];if(e.length>0){this.logger.info(JSON.stringify(e));const t=".";n.writeFileSync(o.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}var _;t.TestRunAutoResultStatus=void 0,(_=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",_.FAILED="FAILED",_.SKIPPED="SKIPPED",_.CANCELED="CANCELED",_.ERROR="ERROR";const L=s.default,N={publicApiBaseUrl:"https://api.applause.com/"};function F(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!L.isURL(t.publicApiBaseUrl,{protocols:["http","https"],require_tld:!1,allow_query_components:!1,disallow_auth:!0,allow_fragments:!1,allow_protocol_relative_urls:!1,allow_trailing_dot:!1,require_host:!0,require_protocol:!0}))throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${t.publicApiBaseUrl}`);if(L.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function P(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e??{}).filter((([t,e])=>void 0!==e))))}function U(t){return function(t){return void 0!==t.autoApiBaseUrl&&void 0!==t.apiKey&&void 0!==t.productId}(t)&&function(t){return void 0!==t.publicApiBaseUrl&&void 0!==t.apiKey&&void 0!==t.productId}(t)}function D(t){const e=t??`${process.cwd()}/applause.json`;if(!n.existsSync(e))return{};const s=n.readFileSync(e,"utf8");return JSON.parse(s)}function H(t){c(t),F(t)}t.APPLAUSE_CASE_ID_PREFIX=b,t.APPLAUSE_LOG_RECORDS=R,t.ApplauseReporter=class{autoApi;initializer;logger;reporter;runStarted=!1;runFinished=!1;constructor(t,e){this.logger=e??E(),this.autoApi=new A(t,this.logger),this.initializer=new v(this.autoApi,this.logger);const s=process.env.APPLAUSE_RUN_ID;if(void 0!==s){const t=new C(this.autoApi,parseInt(s),void 0,this.logger);this.reporter=new Promise((e=>e(t))),this.runStarted=!0}}async runnerStart(t){if(void 0!==this.reporter)throw this.logger.error("Cannot start a run - run already started or run already finished"),new Error("Cannot start a run - run already started or run already finished");this.reporter=this.initializer.initializeRun(t);const e=await this.reporter;return this.runStarted=!0,process.env.APPLAUSE_RUN_ID=e.testRunId.toString(),e.testRunId}async startTestCase(t,e,s){if(void 0===this.reporter)throw this.logger.error("Cannot start a test case for a run that was never initialized"),new Error("Cannot start a test case for a run that was never initialized");return(await this.reporter).startTestCase(t,e,s)}async submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw this.logger.error("Cannot submit test case result for a run that was never initialized"),new Error("Cannot submit test case result for a run that was never initialized");return(await this.reporter).submitTestCaseResult(t,e,s)}async runnerEnd(){if(void 0===this.reporter)throw this.logger.error("Cannot end a run that was never initialized"),new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}async attachTestCaseAsset(t,e,s,i,r){if(void 0===this.reporter)throw this.logger.error("Cannot attach an asset for a run that was never initialized"),new Error("Cannot attach an asset for a run that was never initialized");return await this.reporter.then((a=>a.attachTestCaseAsset(t,e,s,i,r)))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.ApplauseTransport=f,t.AutoApi=A,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new S(e,this.autoApi)}},t.Inbox=S,t.LoggingContainer=I,t.PublicApi=class{options;client;callsInFlight;logger;get getCallsInFlight(){return this.callsInFlight}constructor(t,s){this.options=t,this.callsInFlight=0,this.logger=s??E(),F(t),this.client=e.create({baseURL:t.publicApiBaseUrl,timeout:1e4,headers:{"X-Api-Key":t.apiKey,"Context-Type":"application/json"},responseType:"json"}),this.client.interceptors.response.use((function(t){return t}),(t=>{const e=void 0!==t.response?.data?JSON.stringify(t.response.data):`error-code [${t.response?.status}] with error [${t.response?.statusText}]`;return this.logger.error(`Public-Api returned ${e}`),Promise.reject(t)}))}async submitResult(t,e){this.callsInFlight+=1;try{return await this.client.post(`v2/test-case-results/${t}/submit`,e)}finally{this.callsInFlight-=1}}},t.RunInitializer=v,t.RunReporter=C,t.TEST_RAIL_CASE_ID_PREFIX=y,t.TestRunHeartbeatService=T,t.WINSTON_DEFAULT_LOG_FORMAT=g,t.constructDefaultLogger=E,t.isComplete=U,t.loadConfig=function(t){let e={...N,...d};if(e=void 0!==t&&void 0!==t.configFile?P(e,D(o.join(process.cwd(),t.configFile))):P(e,D()),void 0!==t&&void 0!==t.properties&&(e=P(e,t.properties)),!U(e))throw new Error("Config is not complete");const s=e;return H(s),s},t.loadConfigFromFile=D,t.overrideConfig=P,t.parseTestCaseName=O,t.validateConfig=H,t.validatePartialConfig=function(t){if(void 0!==t.productId&&(!Number.isInteger(t.productId)||t.productId<=0))throw new Error(`productId must be a positive integer, was: '${t.productId}'`)}})); //# sourceMappingURL=index.min.js.map diff --git a/dist/index.min.js.map b/dist/index.min.js.map index a3580a7..11d0c26 100644 --- a/dist/index.min.js.map +++ b/dist/index.min.js.map @@ -1 +1 @@ -{"version":3,"file":"index.min.js","sources":["../src/auto-api/version.ts","../src/auto-api/auto-api-config.ts","../src/shared/logging.ts","../src/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/heartbeat.ts","../src/shared/test-case.ts","../src/auto-api/reporter.ts","../src/public-api/dto.ts","../src/public-api/public-api-config.ts","../src/config/config.ts","../src/auto-api/email-helper.ts","../src/public-api/public-api.ts"],"sourcesContent":["export const API_VERSION = '1.1.0';\n","import { TestRailOptions } from './dto.ts';\nimport Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface AutoApiConfig {\n readonly autoApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly testRailOptions?: TestRailOptions;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n\nexport const DEFAULT_AUTO_API_PROPERTIES: Partial = {\n autoApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isAutoApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialAutoApiConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validateAutoApiConfig(config: AutoApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import * as winston from 'winston';\nimport { TransformableInfo } from 'logform';\nimport TransportStream from 'winston-transport';\nconst MESSAGE = Symbol.for('message');\n\nexport const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf(\n ({ level, message, label, timestamp }) => {\n return `${timestamp} [${label}] ${level}: ${message}`;\n }\n);\n\nexport function constructDefaultLogger(): winston.Logger {\n return winston.createLogger({\n format: winston.format.combine(\n winston.format.label({ label: 'Applause Tests' }),\n winston.format.timestamp(),\n winston.format.splat(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n transports: [\n new winston.transports.File({ filename: 'error.log', level: 'error' }),\n new winston.transports.File({ filename: 'combined.log' }),\n new ApplauseTransport(),\n new winston.transports.Console({\n level: 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n }),\n ],\n });\n}\n\n/**\n * A simple Class for storing and retrieving log messages.\n */\nexport class LoggingContainer {\n private logs: string[] = [];\n\n /**\n * Retrieves all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public getLogs(): string[] {\n return this.logs;\n }\n\n /**\n * Retrieves and clears all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public drainLogs(): string[] {\n const logs = this.logs;\n this.clearLogs();\n return logs;\n }\n\n /**\n * Clears all logs stored in the container.\n */\n public clearLogs(): void {\n this.logs = [];\n }\n\n /**\n * Adds a log message to the container.\n *\n * @param log - The log message to add.\n */\n public addLog(log: string): void {\n this.logs.push(log);\n }\n}\n\n// Create a new Shared LoggingContainer to store logs\nexport const APPLAUSE_LOG_RECORDS: LoggingContainer = new LoggingContainer();\n\n/**\n * A Custom Winston Transport that sends logs to the Applause LoggingContainer\n */\nexport class ApplauseTransport extends TransportStream {\n constructor(opts?: TransportStream.TransportStreamOptions) {\n super(opts);\n }\n\n log(info: TransformableInfo, callback: () => void): void {\n setImmediate(() => {\n this.emit('logged', info);\n });\n\n this.format?.transform(info);\n APPLAUSE_LOG_RECORDS.addLog(\n (info[MESSAGE] as string | undefined) ?? (info.message as string)\n );\n\n // Continue to the next transport\n callback();\n }\n}\n","/**\n * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform.\n * The `AutoApi` class provides methods for starting and ending test runs, creating test cases, submitting test case results, and performing other operations related to test management.\n * It also includes properties and methods to track the number of HTTP calls in progress.\n */\n\nimport axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport {\n AssetType,\n CreateTestCaseResultDto,\n CreateTestCaseResultResponseDto,\n EmailAddressResponse,\n EmailFetchRequest,\n SubmitTestCaseResultDto,\n TestResultProviderInfo,\n TestRunCreateDto,\n TestRunCreateResponseDto,\n} from './dto.ts';\nimport { API_VERSION } from './version.ts';\nimport { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\nimport * as winston from 'winston';\n\nexport class AutoApi {\n private readonly client: AxiosInstance;\n\n private logger: winston.Logger;\n private callsInFlight: number;\n /**\n * Tracks the number of HTTP calls in progress.\n * This property is used by reporters that want to know when the async work is finished.\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n /**\n * Creates an instance of the `AutoApi` class.\n * @param options - The configuration options for the Applause API.\n */\n constructor(\n readonly options: AutoApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validateAutoApiConfig(options);\n this.client = axios.create({\n baseURL: options.autoApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * Starts a new test run.\n * @param info - The information for creating the test run.\n * @returns A promise that resolves to the response containing the created test run.\n */\n async startTestRun(\n info: TestRunCreateDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n '/api/v1.0/test-run/create',\n {\n // Provided params\n ...info,\n\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n\n // Copy over the product id\n productId: this.options.productId,\n\n applauseTestCycleId: this.options.applauseTestCycleId,\n\n // Copy over test rail parameters\n testRailReportingEnabled: this.options.testRailOptions !== undefined,\n addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan,\n testRailProjectId: this.options.testRailOptions?.projectId,\n testRailSuiteId: this.options.testRailOptions?.suiteId,\n testRailPlanName: this.options.testRailOptions?.planName,\n testRailRunName: this.options.testRailOptions?.runName,\n overrideTestRailRunNameUniqueness:\n this.options.testRailOptions?.overrideTestRailRunUniqueness,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Ends a test run.\n * @param testRunId - The ID of the test run to end.\n * @returns A promise that resolves to the response indicating the completion of the test run.\n */\n async endTestRun(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(\n `/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Starts a new test case.\n * @param params - The parameters for creating the test case.\n * @returns A promise that resolves to the response containing the created test case.\n */\n async startTestCase(\n params: CreateTestCaseResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post(\n '/api/v1.0/test-result/create-result',\n params\n );\n return res;\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Submits a test case result.\n * @param params - The parameters for submitting the test case result.\n * @returns A promise that resolves when the test case result is submitted.\n */\n async submitTestCaseResult(params: SubmitTestCaseResultDto): Promise {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the provider session links for the specified test results.\n * @param resultIds - The IDs of the test results.\n * @returns A promise that resolves to the response containing the provider session links.\n */\n async getProviderSessionLinks(\n resultIds: number[]\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds: number[] = resultIds.filter(id => id);\n return await this.client.post(\n '/api/v1.0/test-result/provider-info',\n validIds\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Sends a heartbeat for the specified test run.\n * @param testRunId - The ID of the test run.\n * @returns A promise that resolves to the response indicating the heartbeat was sent.\n */\n async sendSdkHeartbeat(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v2.0/sdk-heartbeat', {\n testRunId: testRunId,\n });\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the email address for the specified email prefix.\n * @param emailPrefix - The prefix of the email address.\n * @returns A promise that resolves to the response containing the email address.\n */\n async getEmailAddress(\n emailPrefix: string\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(\n `/api/v1.0/email/get-address?prefix=${emailPrefix}`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the content of the specified email.\n * @param request - The request parameters for retrieving the email content.\n * @returns A promise that resolves to the response containing the email content.\n */\n async getEmailContent(\n request: EmailFetchRequest\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post(\n '/api/v1.0/email/download-email',\n request\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Uploads an asset for the specified test result.\n * @param resultId - The ID of the test result.\n * @param file - The file to upload as an asset.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The GUID of the provider session.\n * @param assetType - The type of the asset.\n * @returns A promise that resolves to the response indicating the asset was uploaded.\n */\n async uploadAsset(\n resultId: number,\n file: Buffer,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType\n ): Promise> {\n this.callsInFlight += 1;\n\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.postForm(\n `/api/v1.0/test-result/${resultId}/upload`,\n {\n file,\n assetName,\n providerSessionGuid,\n assetType,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Configuration of the auto-api client\n */\nexport type ClientConfig = {\n readonly baseUrl: string;\n readonly apiKey: string;\n};\n\n/**\n * DTO used to create a new Applause test run\n */\nexport interface TestRunCreateDto {\n // Required: a list of test cases to pre-create\n tests: string[];\n}\n\n/**\n * DTO modeling the response to a test run creation request\n */\nexport interface TestRunCreateResponseDto {\n // The ID of the Applause Test Run\n runId: number;\n}\n\nexport interface AdditionalTestCaseParams {\n // A collection of provider session guids\n providerSessionIds?: string[];\n\n // Optional: TestRail Test Case Id\n testCaseId?: string;\n\n // Optional: Applause Test Case Id\n itwTestCaseId?: string;\n}\n\n/**\n * DTO used to mark the start of a test result\n */\nexport interface CreateTestCaseResultDto extends AdditionalTestCaseParams {\n // ID of the test run to submit this result to\n testRunId: number;\n\n // Name of the Test Case\n testCaseName: string;\n}\n\n/**\n * DTO response to a test result creation request\n */\nexport interface CreateTestCaseResultResponseDto {\n testResultId: number;\n}\n\nexport interface AdditionalTestCaseResultParams {\n // A list of selenium provider session ids to connect to the result\n providerSessionGuids?: string[];\n\n // An optional testrail test case id\n testRailCaseId?: number;\n\n // An optional applause test case id\n itwCaseId?: number;\n\n // The reason a test case failed\n failureReason?: string;\n}\n\n/**\n * DTO used to submit a status to an in progress test result.\n */\nexport interface SubmitTestCaseResultDto\n extends AdditionalTestCaseResultParams {\n // The id of the test result\n testResultId: number;\n\n // The ending status of the test.\n status: TestResultStatus;\n}\n\n/**\n * Enum representing a test result's status\n */\nexport enum TestResultStatus {\n NOT_RUN = 'NOT_RUN',\n IN_PROGRESS = 'IN_PROGRESS',\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\n/**\n * DTO representing test result info that is provided at the end of a test run\n */\nexport interface TestResultProviderInfo {\n testResultId: number;\n providerUrl: string;\n providerSessionId: string;\n}\n\n/**\n * DTO representing TestRail settings. The presence of this info signals that test rail reporting is enabled\n */\nexport interface TestRailOptions {\n projectId: number;\n suiteId: number;\n planName: string;\n runName: string;\n addAllTestsToPlan?: boolean;\n overrideTestRailRunUniqueness?: boolean;\n}\n\n/**\n * DTO containing a generated email address for testing\n */\nexport interface EmailAddressResponse {\n emailAddress: string;\n}\n\n/**\n * DTO used for fetching an email from a given email address\n */\nexport interface EmailFetchRequest {\n emailAddress: string;\n}\n\nexport enum AssetType {\n SCREENSHOT = 'SCREENSHOT',\n FAILURE_SCREENSHOT = 'FAILURE_SCREENSHOT',\n VIDEO = 'VIDEO',\n NETWORK_HAR = 'NETWORK_HAR',\n VITALS_LOG = 'VITALS_LOG',\n CONSOLE_LOG = 'CONSOLE_LOG',\n NETWORK_LOG = 'NETWORK_LOG',\n DEVICE_LOG = 'DEVICE_LOG',\n SELENIUM_LOG = 'SELENIUM_LOG',\n SELENIUM_LOG_JSON = 'SELENIUM_LOG_JSON',\n BROWSER_LOG = 'BROWSER_LOG',\n FRAMEWORK_LOG = 'FRAMEWORK_LOG',\n EMAIL = 'EMAIL',\n PAGE_SOURCE = 'PAGE_SOURCE',\n CODE_BUNDLE = 'CODE_BUNDLE',\n RESULTS_ZIP = 'RESULTS_ZIP',\n SESSION_DETAILS = 'SESSION_DETAILS',\n DEVICE_DETAILS = 'DEVICE_DETAILS',\n UNKNOWN = 'UNKNOWN',\n}\n","import { AutoApi } from '../auto-api.ts';\nimport { ParsedMail, simpleParser } from 'mailparser';\n\n/**\n * Represents an email inbox.\n */\nexport class Inbox {\n /**\n * Creates an instance of Inbox.\n * @param emailAddress - The email address associated with the inbox.\n * @param autoApi - An instance of the AutoApi class.\n */\n constructor(\n public readonly emailAddress: string,\n private autoApi: AutoApi\n ) {}\n\n /**\n * Retrieves the content of an email from the inbox.\n * @returns A Promise that resolves to the parsed email content.\n */\n async getEmail(): Promise {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n","import winston = require('winston');\nimport { AutoApi } from './auto-api.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents a service for sending heartbeats during a test run.\n */\nexport class TestRunHeartbeatService {\n private enabled = false;\n private nextHeartbeat?: Promise;\n private readonly logger: winston.Logger;\n\n /**\n * Creates an instance of TestRunHeartbeatService.\n * @param testRunId - The ID of the test run.\n * @param autoApi - The AutoApi instance used for sending heartbeats.\n */\n constructor(\n readonly testRunId: number,\n readonly autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts sending heartbeats.\n * @returns A promise that resolves when the heartbeats are started.\n */\n async start(): Promise {\n // End the current heartbeat if it has started\n await this.end();\n\n // Set up a new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Checks if the heartbeats are enabled.\n * @returns True if the heartbeats are enabled, false otherwise.\n */\n public isEnabled(): boolean {\n return this.enabled;\n }\n\n private scheduleNextHeartbeat(): void {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(\n () => this.sendHeartbeat()\n );\n }\n\n private async sendHeartbeat(): Promise {\n this.logger.debug('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n this.logger.debug('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Ends the heartbeats.\n * @returns A promise that resolves when the heartbeats are ended.\n */\n async end(): Promise {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n this.logger.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n this.logger.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n","import * as winston from 'winston';\n\nexport const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-';\n\nexport function parseTestCaseName(\n testCaseName: string,\n logger?: winston.Logger\n): ParsedTestCaseName {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds =\n matches\n ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX))\n .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? [];\n const applauseCaseIds =\n matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? [];\n\n if (testRailCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple TestRail case ids detected in testCase name'\n );\n }\n if (applauseCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple Applause case ids detected in testCase name'\n );\n }\n return {\n applauseTestCaseId: applauseCaseIds[0],\n testRailTestCaseId: testRailCaseIds[0],\n testCaseName: testCaseName\n .replace(/(TestRail-\\d+|Applause-\\d+)/g, '')\n .replace(/\\s+/g, ' ')\n .trim(),\n };\n}\n\nexport interface ParsedTestCaseName {\n testCaseName: string;\n testRailTestCaseId?: string;\n applauseTestCaseId?: string;\n}\n","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport {\n AdditionalTestCaseParams,\n AdditionalTestCaseResultParams,\n AssetType,\n TestResultStatus,\n} from './dto.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { AutoApiConfig } from './auto-api-config.ts';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents an Applause reporter.\n */\nexport class ApplauseReporter {\n private autoApi: AutoApi;\n private initializer: RunInitializer;\n private logger: winston.Logger;\n private reporter?: Promise;\n private runStarted: boolean = false;\n private runFinished: boolean = false;\n\n /**\n * Creates an instance of ApplauseReporter.\n * @param config - The Applause configuration.\n */\n constructor(config: AutoApiConfig, logger?: winston.Logger) {\n this.logger = logger ?? constructDefaultLogger();\n this.autoApi = new AutoApi(config, this.logger);\n this.initializer = new RunInitializer(this.autoApi, this.logger);\n const runId = process.env['APPLAUSE_RUN_ID'];\n if (runId !== undefined) {\n const r = new RunReporter(\n this.autoApi,\n parseInt(runId),\n undefined,\n this.logger\n );\n this.reporter = new Promise(resolve => resolve(r));\n this.runStarted = true;\n }\n }\n\n /**\n * Starts the Applause runner.\n * @param tests - Optional array of test names to run.\n * @returns A promise that resolves to the test run ID.\n * @throws Error if a run is already started or finished.\n */\n public async runnerStart(tests?: string[]): Promise {\n if (this.reporter !== undefined) {\n this.logger.error(\n 'Cannot start a run - run already started or run already finished'\n );\n throw new Error(\n 'Cannot start a run - run already started or run already finished'\n );\n }\n this.reporter = this.initializer.initializeRun(tests);\n const initializedReporter = await this.reporter;\n this.runStarted = true;\n process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString();\n return initializedReporter.testRunId;\n }\n\n /**\n * Starts a test case.\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Optional additional parameters for the test case.\n * @returns A promise that resolves to the test case ID.\n * @throws Error if a run was never initialized.\n */\n public async startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot start a test case for a run that was never initialized'\n );\n throw new Error(\n 'Cannot start a test case for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.startTestCase(id, testCaseName, params);\n }\n\n /**\n * Submits a test case result.\n * @param id - The ID of the test case.\n * @param status - The status of the test case result.\n * @param params - Optional additional parameters for the test case result.\n * @returns A promise that resolves to the test case result ID.\n * @throws Error if a run was never initialized.\n */\n public async submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n throw new Error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.submitTestCaseResult(id, status, params);\n }\n\n /**\n * Ends the Applause runner.\n * @returns A promise that resolves when the runner is ended.\n * @throws Error if a run was never initialized.\n */\n public async runnerEnd(): Promise {\n if (this.reporter === undefined) {\n this.logger.error('Cannot end a run that was never initialized');\n throw new Error('Cannot end a run that was never initialized');\n }\n await this.reporter\n .then(reporter => reporter.runnerEnd())\n .then(() => (this.runFinished = true));\n }\n\n /**\n * Attaches an asset to a test case.\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset data as a Buffer.\n * @returns A promise that resolves when the asset is attached.\n * @throws Error if a run was never initialized.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n throw new Error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n }\n return await this.reporter.then(reporter =>\n reporter.attachTestCaseAsset(\n id,\n assetName,\n providerSessionGuid,\n assetType,\n asset\n )\n );\n }\n\n /**\n * Checks if the Applause runner is synchronized.\n * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished.\n */\n public isSynchronized(): boolean {\n return (\n (!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0\n );\n }\n}\n\n/**\n * Represents a Run Initializer.\n */\nexport class RunInitializer {\n private logger: winston.Logger;\n constructor(\n private autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Initializes a test run.\n * @param tests - An optional array of test names to include in the run.\n * @returns A promise that resolves to a RunReporter instance.\n * @throws An error if unable to create the test run.\n */\n async initializeRun(tests?: string[]): Promise {\n const cleanedTests = tests\n ?.map(testName => parseTestCaseName(testName, this.logger))\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests ?? [],\n });\n if (\n testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300\n ) {\n this.logger.error(\n `Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`\n );\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n this.logger.info(`Test Run ${runId} initialized`);\n const heartbeatService = new TestRunHeartbeatService(\n runId,\n this.autoApi,\n this.logger\n );\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService, this.logger);\n }\n}\n\n/**\n * Handles reporting test results to the Applause API.\n */\nexport class RunReporter {\n private uidToResultIdMap: Record> = {};\n private resultSubmissionMap: Record> = {};\n private logger: winston.Logger;\n\n /**\n * Creates a new instance of the Reporter class.\n * @param autoApi - The AutoApi instance.\n * @param testRunId - The ID of the test run.\n * @param heartbeatService - (Optional) The TestRunHeartbeatService instance.\n */\n constructor(\n private autoApi: AutoApi,\n public readonly testRunId: number,\n private heartbeatService?: TestRunHeartbeatService,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts a test case and returns a promise that resolves to the test result ID.\n *\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Additional parameters for the test case.\n * @returns A promise that resolves to the test result ID.\n */\n public startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (!testCaseName) {\n this.logger.error('testCaseName is required');\n throw new Error('testCaseName is required');\n }\n const parsedTestCase = parseTestCaseName(testCaseName, this.logger);\n const submission = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\n\n testRunId: this.testRunId,\n // If the additional params provides either test case id, it will override the parsed value we set above\n ...Object.fromEntries(\n Object.entries(params || {}).filter(([_, v]) => v !== undefined)\n ),\n })\n .then(res => {\n return res.data.testResultId;\n });\n this.uidToResultIdMap[id] = submission;\n return submission;\n }\n\n /**\n * Submits the result of a test case.\n *\n * @param id - The ID of the test case.\n * @param status - The status of the test result.\n * @param params - Additional parameters for the test result.\n * @returns A promise that resolves to the result ID.\n */\n public submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n const submission = this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi\n .submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n })\n .then(() => resultId)\n );\n this.resultSubmissionMap[id] = submission;\n return submission;\n }\n\n /**\n * Attaches a test case asset to a result.\n *\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset to attach.\n * @returns A promise that resolves when the asset is attached.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n await this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi.uploadAsset(\n resultId,\n asset,\n assetName,\n providerSessionGuid,\n assetType\n )\n );\n }\n\n /**\n * Ends the test runner and performs necessary cleanup tasks.\n * @returns A promise that resolves when the runner has ended.\n */\n public async runnerEnd(): Promise {\n // Wait for all results to be created\n const resultIds =\n (await Promise.all(Object.values(this.uidToResultIdMap))) ?? [];\n\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n\n // Wait the heartbeat to be ended\n void (await this.heartbeatService?.end());\n void (await this.autoApi.endTestRun(this.testRunId));\n\n // Fetch the provider session asset links and save them off to a file\n const resp = await this.autoApi.getProviderSessionLinks(resultIds);\n const jsonArray = resp.data ?? [];\n if (jsonArray.length > 0) {\n this.logger.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(\n pathJoin(outputPath, 'providerUrls.txt'),\n JSON.stringify(jsonArray, null, 1)\n );\n }\n }\n}\n","export interface TestRunAutoResultDto {\n testCycleId: number;\n status: TestRunAutoResultStatus;\n failureReason?: string;\n sessionDetailsJson?: SessionDetails;\n startTime?: Date;\n endTime?: Date;\n}\n\nexport enum TestRunAutoResultStatus {\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\nexport interface SessionDetails {\n value: {\n deviceName?: string;\n orientation?: string;\n platformName?: string;\n platformVersion?: string;\n browserName?: string;\n browserVersion?: string;\n };\n}\n","import Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface PublicApiConfig {\n readonly publicApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://api.applause.com/';\n\nexport const DEFAULT_PUBLIC_API_PROPERTIES: Partial = {\n publicApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isPublicApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialPublicApiConfig(\n config: Partial\n) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validatePublicApiConfig(config: PublicApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","/**\n * Represents the configuration options for the Applause Reporter.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport path from 'path';\n\nimport {\n AutoApiConfig,\n DEFAULT_AUTO_API_PROPERTIES,\n isAutoApiConfigComplete,\n validateAutoApiConfig,\n} from '../auto-api/auto-api-config.ts';\nimport {\n DEFAULT_PUBLIC_API_PROPERTIES,\n isPublicApiConfigComplete,\n PublicApiConfig,\n validatePublicApiConfig,\n} from '../public-api/public-api-config.ts';\n\nexport type ApplauseConfig = AutoApiConfig & PublicApiConfig;\n\n/**\n * Represents the properties for loading the configuration.\n */\nexport interface ConfigLoadProperties {\n configFile?: string;\n properties?: Partial;\n}\n\n/**\n * Loads the configuration for the Applause Reporter.\n * @param loadOptions - The options for loading the configuration.\n * @returns The loaded Applause configuration.\n * @throws Error if the configuration is not complete or invalid.\n */\nexport function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig {\n // Setup the initial config with any default properties\n let config: Partial = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(\n config,\n loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))\n );\n } else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n\n // We know that the config is complete, so we can cast\n const finalConfig = config as ApplauseConfig;\n\n validateConfig(finalConfig);\n\n return finalConfig;\n}\n\n/**\n * Overrides the configuration with the provided overrides.\n * @param config - The base configuration.\n * @param overrides - The overrides to apply.\n * @returns The overridden configuration.\n */\nexport function overrideConfig(\n config: Partial,\n overrides?: Partial\n): Partial {\n return Object.assign(\n {},\n config,\n Object.fromEntries(\n Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined)\n )\n );\n}\n\n/**\n * Checks if the configuration is complete.\n * @param config - The configuration to check.\n * @returns True if the configuration is complete, false otherwise.\n */\nexport function isComplete(config: Partial): boolean {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\n\n/**\n * Loads the configuration from the specified file.\n * @param configFile - The path to the configuration file.\n * @returns The loaded configuration from the file.\n */\nexport function loadConfigFromFile(\n configFile?: string\n): Partial {\n const configFilePath = configFile ?? `${process.cwd()}/applause.json`;\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileContents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileContents) as Partial;\n}\n\n/**\n * Validates the configuration.\n * @param config - The configuration to validate.\n * @throws Error if the configuration is invalid.\n */\nexport function validateConfig(config: ApplauseConfig) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\n\n/**\n * Validates a partial configuration.\n * @param config - The partial configuration to validate.\n * @throws Error if the partial configuration is invalid.\n */\nexport function validatePartialConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n","import { AutoApi } from './auto-api.ts';\nimport { Inbox } from './email/inbox.ts';\n\n/**\n * Helper class for managing email functionality.\n */\nexport class EmailHelper {\n constructor(private autoApi: AutoApi) {}\n\n /**\n * Retrieves the inbox for the specified email prefix.\n *\n * @param emailPrefix - The prefix used to generate the email address.\n * @returns A Promise that resolves to an Inbox object.\n */\n async getInbox(emailPrefix: string): Promise {\n const generatedAddress: string = (\n await this.autoApi.getEmailAddress(emailPrefix)\n ).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\n\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n","import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport { TestRunAutoResultDto } from './dto.ts';\nimport {\n PublicApiConfig,\n validatePublicApiConfig,\n} from './public-api-config.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\nexport class PublicApi {\n private readonly client: AxiosInstance;\n\n private callsInFlight: number;\n private logger: winston.Logger;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n constructor(\n readonly options: PublicApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validatePublicApiConfig(options);\n this.client = axios.create({\n baseURL: options.publicApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n async submitResult(\n testCaseId: number,\n info: TestRunAutoResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n `v2/test-case-results/${testCaseId}/submit`,\n info\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n"],"names":["validator","Validator","default","DEFAULT_AUTO_API_PROPERTIES","autoApiBaseUrl","validateAutoApiConfig","config","Number","isInteger","productId","Error","isURL","protocols","require_tld","allow_query_components","disallow_auth","allow_fragments","allow_protocol_relative_urls","allow_trailing_dot","require_host","require_protocol","isEmpty","apiKey","MESSAGE","Symbol","for","WINSTON_DEFAULT_LOG_FORMAT","winston","format","printf","level","message","label","timestamp","constructDefaultLogger","createLogger","combine","splat","transports","File","filename","ApplauseTransport","Console","colorize","LoggingContainer","logs","getLogs","this","drainLogs","clearLogs","addLog","log","push","APPLAUSE_LOG_RECORDS","TransportStream","constructor","opts","super","info","callback","setImmediate","emit","transform","AutoApi","options","client","logger","callsInFlight","getCallsInFlight","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","JSON","stringify","status","statusText","Promise","reject","startTestRun","post","sdkVersion","applauseTestCycleId","testRailReportingEnabled","testRailOptions","addAllTestsToPlan","testRailProjectId","projectId","testRailSuiteId","suiteId","testRailPlanName","planName","testRailRunName","runName","overrideTestRailRunNameUniqueness","overrideTestRailRunUniqueness","endTestRun","testRunId","delete","startTestCase","params","submitTestCaseResult","getProviderSessionLinks","resultIds","validIds","filter","id","sendSdkHeartbeat","getEmailAddress","emailPrefix","get","getEmailContent","request","uploadAsset","resultId","file","assetName","providerSessionGuid","assetType","postForm","TestResultStatus","AssetType","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","debug","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","parseTestCaseName","testCaseName","matches","match","testRailCaseIds","startsWith","map","substring","applauseCaseIds","length","console","warn","applauseTestCaseId","testRailTestCaseId","replace","trim","RunInitializer","initializeRun","tests","cleanedTests","testName","parsed","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","submission","testCaseId","itwTestCaseId","Object","fromEntries","entries","_","v","testResultId","attachTestCaseAsset","asset","runnerEnd","all","values","jsonArray","outputPath","writeFileSync","pathJoin","join","TestRunAutoResultStatus","DEFAULT_PUBLIC_API_PROPERTIES","publicApiBaseUrl","validatePublicApiConfig","overrideConfig","overrides","assign","isComplete","isAutoApiConfigComplete","isPublicApiConfigComplete","loadConfigFromFile","configFile","configFilePath","process","cwd","existsSync","fileContents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","env","r","parseInt","runnerStart","initializedReporter","toString","isSynchronized","getInbox","generatedAddress","submitResult","loadOptions","path","properties","finalConfig"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.min.js","sources":["../src/auto-api/version.ts","../src/auto-api/auto-api-config.ts","../src/shared/logging.ts","../src/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/heartbeat.ts","../src/shared/test-case.ts","../src/auto-api/reporter.ts","../src/public-api/dto.ts","../src/public-api/public-api-config.ts","../src/config/config.ts","../src/auto-api/email-helper.ts","../src/public-api/public-api.ts"],"sourcesContent":["export const API_VERSION = '1.1.0';\n","import { TestRailOptions } from './dto.ts';\nimport Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface AutoApiConfig {\n readonly autoApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly testRailOptions?: TestRailOptions;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n\nexport const DEFAULT_AUTO_API_PROPERTIES: Partial = {\n autoApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isAutoApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialAutoApiConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validateAutoApiConfig(config: AutoApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import * as winston from 'winston';\nimport { TransformableInfo } from 'logform';\nimport TransportStream from 'winston-transport';\nconst MESSAGE = Symbol.for('message');\n\nexport const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf(\n ({ level, message, label, timestamp }) => {\n return `${timestamp} [${label}] ${level}: ${message}`;\n }\n);\n\nexport function constructDefaultLogger(): winston.Logger {\n return winston.createLogger({\n format: winston.format.combine(\n winston.format.label({ label: 'Applause Tests' }),\n winston.format.timestamp(),\n winston.format.splat(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n transports: [\n new winston.transports.File({ filename: 'error.log', level: 'error' }),\n new winston.transports.File({ filename: 'combined.log' }),\n new ApplauseTransport(),\n new winston.transports.Console({\n level: 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n }),\n ],\n });\n}\n\n/**\n * A simple Class for storing and retrieving log messages.\n */\nexport class LoggingContainer {\n private logs: string[] = [];\n\n /**\n * Retrieves all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public getLogs(): string[] {\n return this.logs;\n }\n\n /**\n * Retrieves and clears all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public drainLogs(): string[] {\n const logs = this.logs;\n this.clearLogs();\n return logs;\n }\n\n /**\n * Clears all logs stored in the container.\n */\n public clearLogs(): void {\n this.logs = [];\n }\n\n /**\n * Adds a log message to the container.\n *\n * @param log - The log message to add.\n */\n public addLog(log: string): void {\n this.logs.push(log);\n }\n}\n\n// Create a new Shared LoggingContainer to store logs\nexport const APPLAUSE_LOG_RECORDS: LoggingContainer = new LoggingContainer();\n\n/**\n * A Custom Winston Transport that sends logs to the Applause LoggingContainer\n */\nexport class ApplauseTransport extends TransportStream {\n constructor(opts?: TransportStream.TransportStreamOptions) {\n super(opts);\n }\n\n log(info: TransformableInfo, callback: () => void): void {\n setImmediate(() => {\n this.emit('logged', info);\n });\n\n this.format?.transform(info);\n APPLAUSE_LOG_RECORDS.addLog(\n (info[MESSAGE] as string | undefined) ?? (info.message as string)\n );\n\n // Continue to the next transport\n callback();\n }\n}\n","/**\n * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform.\n * The `AutoApi` class provides methods for starting and ending test runs, creating test cases, submitting test case results, and performing other operations related to test management.\n * It also includes properties and methods to track the number of HTTP calls in progress.\n */\n\nimport axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport {\n AssetType,\n CreateTestCaseResultDto,\n CreateTestCaseResultResponseDto,\n EmailAddressResponse,\n EmailFetchRequest,\n SubmitTestCaseResultDto,\n TestResultProviderInfo,\n TestRunCreateDto,\n TestRunCreateResponseDto,\n} from './dto.ts';\nimport { API_VERSION } from './version.ts';\nimport { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\nimport * as winston from 'winston';\n\nexport class AutoApi {\n private readonly client: AxiosInstance;\n\n private logger: winston.Logger;\n private callsInFlight: number;\n /**\n * Tracks the number of HTTP calls in progress.\n * This property is used by reporters that want to know when the async work is finished.\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n /**\n * Creates an instance of the `AutoApi` class.\n * @param options - The configuration options for the Applause API.\n */\n constructor(\n readonly options: AutoApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validateAutoApiConfig(options);\n this.client = axios.create({\n baseURL: options.autoApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * Starts a new test run.\n * @param info - The information for creating the test run.\n * @returns A promise that resolves to the response containing the created test run.\n */\n async startTestRun(\n info: TestRunCreateDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n '/api/v1.0/test-run/create',\n {\n // Provided params\n ...info,\n\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n\n // Copy over the product id\n productId: this.options.productId,\n\n itwTestCycleId: this.options.applauseTestCycleId,\n\n // Copy over test rail parameters\n testRailReportingEnabled: this.options.testRailOptions !== undefined,\n addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan,\n testRailProjectId: this.options.testRailOptions?.projectId,\n testRailSuiteId: this.options.testRailOptions?.suiteId,\n testRailPlanName: this.options.testRailOptions?.planName,\n testRailRunName: this.options.testRailOptions?.runName,\n overrideTestRailRunNameUniqueness:\n this.options.testRailOptions?.overrideTestRailRunUniqueness,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Ends a test run.\n * @param testRunId - The ID of the test run to end.\n * @returns A promise that resolves to the response indicating the completion of the test run.\n */\n async endTestRun(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(\n `/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Starts a new test case.\n * @param params - The parameters for creating the test case.\n * @returns A promise that resolves to the response containing the created test case.\n */\n async startTestCase(\n params: CreateTestCaseResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post(\n '/api/v1.0/test-result/create-result',\n params\n );\n return res;\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Submits a test case result.\n * @param params - The parameters for submitting the test case result.\n * @returns A promise that resolves when the test case result is submitted.\n */\n async submitTestCaseResult(params: SubmitTestCaseResultDto): Promise {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the provider session links for the specified test results.\n * @param resultIds - The IDs of the test results.\n * @returns A promise that resolves to the response containing the provider session links.\n */\n async getProviderSessionLinks(\n resultIds: number[]\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds: number[] = resultIds.filter(id => id);\n return await this.client.post(\n '/api/v1.0/test-result/provider-info',\n validIds\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Sends a heartbeat for the specified test run.\n * @param testRunId - The ID of the test run.\n * @returns A promise that resolves to the response indicating the heartbeat was sent.\n */\n async sendSdkHeartbeat(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v2.0/sdk-heartbeat', {\n testRunId: testRunId,\n });\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the email address for the specified email prefix.\n * @param emailPrefix - The prefix of the email address.\n * @returns A promise that resolves to the response containing the email address.\n */\n async getEmailAddress(\n emailPrefix: string\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(\n `/api/v1.0/email/get-address?prefix=${emailPrefix}`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the content of the specified email.\n * @param request - The request parameters for retrieving the email content.\n * @returns A promise that resolves to the response containing the email content.\n */\n async getEmailContent(\n request: EmailFetchRequest\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post(\n '/api/v1.0/email/download-email',\n request\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Uploads an asset for the specified test result.\n * @param resultId - The ID of the test result.\n * @param file - The file to upload as an asset.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The GUID of the provider session.\n * @param assetType - The type of the asset.\n * @returns A promise that resolves to the response indicating the asset was uploaded.\n */\n async uploadAsset(\n resultId: number,\n file: Buffer,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType\n ): Promise> {\n this.callsInFlight += 1;\n\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.postForm(\n `/api/v1.0/test-result/${resultId}/upload`,\n {\n file,\n assetName,\n providerSessionGuid,\n assetType,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Configuration of the auto-api client\n */\nexport type ClientConfig = {\n readonly baseUrl: string;\n readonly apiKey: string;\n};\n\n/**\n * DTO used to create a new Applause test run\n */\nexport interface TestRunCreateDto {\n // Required: a list of test cases to pre-create\n tests: string[];\n}\n\n/**\n * DTO modeling the response to a test run creation request\n */\nexport interface TestRunCreateResponseDto {\n // The ID of the Applause Test Run\n runId: number;\n}\n\nexport interface AdditionalTestCaseParams {\n // A collection of provider session guids\n providerSessionIds?: string[];\n\n // Optional: TestRail Test Case Id\n testCaseId?: string;\n\n // Optional: Applause Test Case Id\n itwTestCaseId?: string;\n}\n\n/**\n * DTO used to mark the start of a test result\n */\nexport interface CreateTestCaseResultDto extends AdditionalTestCaseParams {\n // ID of the test run to submit this result to\n testRunId: number;\n\n // Name of the Test Case\n testCaseName: string;\n}\n\n/**\n * DTO response to a test result creation request\n */\nexport interface CreateTestCaseResultResponseDto {\n testResultId: number;\n}\n\nexport interface AdditionalTestCaseResultParams {\n // A list of selenium provider session ids to connect to the result\n providerSessionGuids?: string[];\n\n // An optional testrail test case id\n testRailCaseId?: number;\n\n // An optional applause test case id\n itwCaseId?: number;\n\n // The reason a test case failed\n failureReason?: string;\n}\n\n/**\n * DTO used to submit a status to an in progress test result.\n */\nexport interface SubmitTestCaseResultDto\n extends AdditionalTestCaseResultParams {\n // The id of the test result\n testResultId: number;\n\n // The ending status of the test.\n status: TestResultStatus;\n}\n\n/**\n * Enum representing a test result's status\n */\nexport enum TestResultStatus {\n NOT_RUN = 'NOT_RUN',\n IN_PROGRESS = 'IN_PROGRESS',\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\n/**\n * DTO representing test result info that is provided at the end of a test run\n */\nexport interface TestResultProviderInfo {\n testResultId: number;\n providerUrl: string;\n providerSessionId: string;\n}\n\n/**\n * DTO representing TestRail settings. The presence of this info signals that test rail reporting is enabled\n */\nexport interface TestRailOptions {\n projectId: number;\n suiteId: number;\n planName: string;\n runName: string;\n addAllTestsToPlan?: boolean;\n overrideTestRailRunUniqueness?: boolean;\n}\n\n/**\n * DTO containing a generated email address for testing\n */\nexport interface EmailAddressResponse {\n emailAddress: string;\n}\n\n/**\n * DTO used for fetching an email from a given email address\n */\nexport interface EmailFetchRequest {\n emailAddress: string;\n}\n\nexport enum AssetType {\n SCREENSHOT = 'SCREENSHOT',\n FAILURE_SCREENSHOT = 'FAILURE_SCREENSHOT',\n VIDEO = 'VIDEO',\n NETWORK_HAR = 'NETWORK_HAR',\n VITALS_LOG = 'VITALS_LOG',\n CONSOLE_LOG = 'CONSOLE_LOG',\n NETWORK_LOG = 'NETWORK_LOG',\n DEVICE_LOG = 'DEVICE_LOG',\n SELENIUM_LOG = 'SELENIUM_LOG',\n SELENIUM_LOG_JSON = 'SELENIUM_LOG_JSON',\n BROWSER_LOG = 'BROWSER_LOG',\n FRAMEWORK_LOG = 'FRAMEWORK_LOG',\n EMAIL = 'EMAIL',\n PAGE_SOURCE = 'PAGE_SOURCE',\n CODE_BUNDLE = 'CODE_BUNDLE',\n RESULTS_ZIP = 'RESULTS_ZIP',\n SESSION_DETAILS = 'SESSION_DETAILS',\n DEVICE_DETAILS = 'DEVICE_DETAILS',\n UNKNOWN = 'UNKNOWN',\n}\n","import { AutoApi } from '../auto-api.ts';\nimport { ParsedMail, simpleParser } from 'mailparser';\n\n/**\n * Represents an email inbox.\n */\nexport class Inbox {\n /**\n * Creates an instance of Inbox.\n * @param emailAddress - The email address associated with the inbox.\n * @param autoApi - An instance of the AutoApi class.\n */\n constructor(\n public readonly emailAddress: string,\n private autoApi: AutoApi\n ) {}\n\n /**\n * Retrieves the content of an email from the inbox.\n * @returns A Promise that resolves to the parsed email content.\n */\n async getEmail(): Promise {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n","import winston = require('winston');\nimport { AutoApi } from './auto-api.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents a service for sending heartbeats during a test run.\n */\nexport class TestRunHeartbeatService {\n private enabled = false;\n private nextHeartbeat?: Promise;\n private readonly logger: winston.Logger;\n\n /**\n * Creates an instance of TestRunHeartbeatService.\n * @param testRunId - The ID of the test run.\n * @param autoApi - The AutoApi instance used for sending heartbeats.\n */\n constructor(\n readonly testRunId: number,\n readonly autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts sending heartbeats.\n * @returns A promise that resolves when the heartbeats are started.\n */\n async start(): Promise {\n // End the current heartbeat if it has started\n await this.end();\n\n // Set up a new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Checks if the heartbeats are enabled.\n * @returns True if the heartbeats are enabled, false otherwise.\n */\n public isEnabled(): boolean {\n return this.enabled;\n }\n\n private scheduleNextHeartbeat(): void {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(\n () => this.sendHeartbeat()\n );\n }\n\n private async sendHeartbeat(): Promise {\n this.logger.debug('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n this.logger.debug('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Ends the heartbeats.\n * @returns A promise that resolves when the heartbeats are ended.\n */\n async end(): Promise {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n this.logger.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n this.logger.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n","import * as winston from 'winston';\n\nexport const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-';\n\nexport function parseTestCaseName(\n testCaseName: string,\n logger?: winston.Logger\n): ParsedTestCaseName {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds =\n matches\n ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX))\n .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? [];\n const applauseCaseIds =\n matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? [];\n\n if (testRailCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple TestRail case ids detected in testCase name'\n );\n }\n if (applauseCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple Applause case ids detected in testCase name'\n );\n }\n return {\n applauseTestCaseId: applauseCaseIds[0],\n testRailTestCaseId: testRailCaseIds[0],\n testCaseName: testCaseName\n .replace(/(TestRail-\\d+|Applause-\\d+)/g, '')\n .replace(/\\s+/g, ' ')\n .trim(),\n };\n}\n\nexport interface ParsedTestCaseName {\n testCaseName: string;\n testRailTestCaseId?: string;\n applauseTestCaseId?: string;\n}\n","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport {\n AdditionalTestCaseParams,\n AdditionalTestCaseResultParams,\n AssetType,\n TestResultStatus,\n} from './dto.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { AutoApiConfig } from './auto-api-config.ts';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents an Applause reporter.\n */\nexport class ApplauseReporter {\n private autoApi: AutoApi;\n private initializer: RunInitializer;\n private logger: winston.Logger;\n private reporter?: Promise;\n private runStarted: boolean = false;\n private runFinished: boolean = false;\n\n /**\n * Creates an instance of ApplauseReporter.\n * @param config - The Applause configuration.\n */\n constructor(config: AutoApiConfig, logger?: winston.Logger) {\n this.logger = logger ?? constructDefaultLogger();\n this.autoApi = new AutoApi(config, this.logger);\n this.initializer = new RunInitializer(this.autoApi, this.logger);\n const runId = process.env['APPLAUSE_RUN_ID'];\n if (runId !== undefined) {\n const r = new RunReporter(\n this.autoApi,\n parseInt(runId),\n undefined,\n this.logger\n );\n this.reporter = new Promise(resolve => resolve(r));\n this.runStarted = true;\n }\n }\n\n /**\n * Starts the Applause runner.\n * @param tests - Optional array of test names to run.\n * @returns A promise that resolves to the test run ID.\n * @throws Error if a run is already started or finished.\n */\n public async runnerStart(tests?: string[]): Promise {\n if (this.reporter !== undefined) {\n this.logger.error(\n 'Cannot start a run - run already started or run already finished'\n );\n throw new Error(\n 'Cannot start a run - run already started or run already finished'\n );\n }\n this.reporter = this.initializer.initializeRun(tests);\n const initializedReporter = await this.reporter;\n this.runStarted = true;\n process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString();\n return initializedReporter.testRunId;\n }\n\n /**\n * Starts a test case.\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Optional additional parameters for the test case.\n * @returns A promise that resolves to the test case ID.\n * @throws Error if a run was never initialized.\n */\n public async startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot start a test case for a run that was never initialized'\n );\n throw new Error(\n 'Cannot start a test case for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.startTestCase(id, testCaseName, params);\n }\n\n /**\n * Submits a test case result.\n * @param id - The ID of the test case.\n * @param status - The status of the test case result.\n * @param params - Optional additional parameters for the test case result.\n * @returns A promise that resolves to the test case result ID.\n * @throws Error if a run was never initialized.\n */\n public async submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n throw new Error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.submitTestCaseResult(id, status, params);\n }\n\n /**\n * Ends the Applause runner.\n * @returns A promise that resolves when the runner is ended.\n * @throws Error if a run was never initialized.\n */\n public async runnerEnd(): Promise {\n if (this.reporter === undefined) {\n this.logger.error('Cannot end a run that was never initialized');\n throw new Error('Cannot end a run that was never initialized');\n }\n await this.reporter\n .then(reporter => reporter.runnerEnd())\n .then(() => (this.runFinished = true));\n }\n\n /**\n * Attaches an asset to a test case.\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset data as a Buffer.\n * @returns A promise that resolves when the asset is attached.\n * @throws Error if a run was never initialized.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n throw new Error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n }\n return await this.reporter.then(reporter =>\n reporter.attachTestCaseAsset(\n id,\n assetName,\n providerSessionGuid,\n assetType,\n asset\n )\n );\n }\n\n /**\n * Checks if the Applause runner is synchronized.\n * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished.\n */\n public isSynchronized(): boolean {\n return (\n (!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0\n );\n }\n}\n\n/**\n * Represents a Run Initializer.\n */\nexport class RunInitializer {\n private logger: winston.Logger;\n constructor(\n private autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Initializes a test run.\n * @param tests - An optional array of test names to include in the run.\n * @returns A promise that resolves to a RunReporter instance.\n * @throws An error if unable to create the test run.\n */\n async initializeRun(tests?: string[]): Promise {\n const cleanedTests = tests\n ?.map(testName => parseTestCaseName(testName, this.logger))\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests ?? [],\n });\n if (\n testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300\n ) {\n this.logger.error(\n `Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`\n );\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n this.logger.info(`Test Run ${runId} initialized`);\n const heartbeatService = new TestRunHeartbeatService(\n runId,\n this.autoApi,\n this.logger\n );\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService, this.logger);\n }\n}\n\n/**\n * Handles reporting test results to the Applause API.\n */\nexport class RunReporter {\n private uidToResultIdMap: Record> = {};\n private resultSubmissionMap: Record> = {};\n private logger: winston.Logger;\n\n /**\n * Creates a new instance of the Reporter class.\n * @param autoApi - The AutoApi instance.\n * @param testRunId - The ID of the test run.\n * @param heartbeatService - (Optional) The TestRunHeartbeatService instance.\n */\n constructor(\n private autoApi: AutoApi,\n public readonly testRunId: number,\n private heartbeatService?: TestRunHeartbeatService,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts a test case and returns a promise that resolves to the test result ID.\n *\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Additional parameters for the test case.\n * @returns A promise that resolves to the test result ID.\n */\n public startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (!testCaseName) {\n this.logger.error('testCaseName is required');\n throw new Error('testCaseName is required');\n }\n const parsedTestCase = parseTestCaseName(testCaseName, this.logger);\n const submission = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\n\n testRunId: this.testRunId,\n // If the additional params provides either test case id, it will override the parsed value we set above\n ...Object.fromEntries(\n Object.entries(params || {}).filter(([_, v]) => v !== undefined)\n ),\n })\n .then(res => {\n return res.data.testResultId;\n });\n this.uidToResultIdMap[id] = submission;\n return submission;\n }\n\n /**\n * Submits the result of a test case.\n *\n * @param id - The ID of the test case.\n * @param status - The status of the test result.\n * @param params - Additional parameters for the test result.\n * @returns A promise that resolves to the result ID.\n */\n public submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n const submission = this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi\n .submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n })\n .then(() => resultId)\n );\n this.resultSubmissionMap[id] = submission;\n return submission;\n }\n\n /**\n * Attaches a test case asset to a result.\n *\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset to attach.\n * @returns A promise that resolves when the asset is attached.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n await this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi.uploadAsset(\n resultId,\n asset,\n assetName,\n providerSessionGuid,\n assetType\n )\n );\n }\n\n /**\n * Ends the test runner and performs necessary cleanup tasks.\n * @returns A promise that resolves when the runner has ended.\n */\n public async runnerEnd(): Promise {\n // Wait for all results to be created\n const resultIds =\n (await Promise.all(Object.values(this.uidToResultIdMap))) ?? [];\n\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n\n // Wait the heartbeat to be ended\n void (await this.heartbeatService?.end());\n void (await this.autoApi.endTestRun(this.testRunId));\n\n // Fetch the provider session asset links and save them off to a file\n const resp = await this.autoApi.getProviderSessionLinks(resultIds);\n const jsonArray = resp.data ?? [];\n if (jsonArray.length > 0) {\n this.logger.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(\n pathJoin(outputPath, 'providerUrls.txt'),\n JSON.stringify(jsonArray, null, 1)\n );\n }\n }\n}\n","export interface TestRunAutoResultDto {\n testCycleId: number;\n status: TestRunAutoResultStatus;\n failureReason?: string;\n sessionDetailsJson?: SessionDetails;\n startTime?: Date;\n endTime?: Date;\n}\n\nexport enum TestRunAutoResultStatus {\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\nexport interface SessionDetails {\n value: {\n deviceName?: string;\n orientation?: string;\n platformName?: string;\n platformVersion?: string;\n browserName?: string;\n browserVersion?: string;\n };\n}\n","import Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface PublicApiConfig {\n readonly publicApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://api.applause.com/';\n\nexport const DEFAULT_PUBLIC_API_PROPERTIES: Partial = {\n publicApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isPublicApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialPublicApiConfig(\n config: Partial\n) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validatePublicApiConfig(config: PublicApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","/**\n * Represents the configuration options for the Applause Reporter.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport path from 'path';\n\nimport {\n AutoApiConfig,\n DEFAULT_AUTO_API_PROPERTIES,\n isAutoApiConfigComplete,\n validateAutoApiConfig,\n} from '../auto-api/auto-api-config.ts';\nimport {\n DEFAULT_PUBLIC_API_PROPERTIES,\n isPublicApiConfigComplete,\n PublicApiConfig,\n validatePublicApiConfig,\n} from '../public-api/public-api-config.ts';\n\nexport type ApplauseConfig = AutoApiConfig & PublicApiConfig;\n\n/**\n * Represents the properties for loading the configuration.\n */\nexport interface ConfigLoadProperties {\n configFile?: string;\n properties?: Partial;\n}\n\n/**\n * Loads the configuration for the Applause Reporter.\n * @param loadOptions - The options for loading the configuration.\n * @returns The loaded Applause configuration.\n * @throws Error if the configuration is not complete or invalid.\n */\nexport function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig {\n // Setup the initial config with any default properties\n let config: Partial = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(\n config,\n loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))\n );\n } else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n\n // We know that the config is complete, so we can cast\n const finalConfig = config as ApplauseConfig;\n\n validateConfig(finalConfig);\n\n return finalConfig;\n}\n\n/**\n * Overrides the configuration with the provided overrides.\n * @param config - The base configuration.\n * @param overrides - The overrides to apply.\n * @returns The overridden configuration.\n */\nexport function overrideConfig(\n config: Partial,\n overrides?: Partial\n): Partial {\n return Object.assign(\n {},\n config,\n Object.fromEntries(\n Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined)\n )\n );\n}\n\n/**\n * Checks if the configuration is complete.\n * @param config - The configuration to check.\n * @returns True if the configuration is complete, false otherwise.\n */\nexport function isComplete(config: Partial): boolean {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\n\n/**\n * Loads the configuration from the specified file.\n * @param configFile - The path to the configuration file.\n * @returns The loaded configuration from the file.\n */\nexport function loadConfigFromFile(\n configFile?: string\n): Partial {\n const configFilePath = configFile ?? `${process.cwd()}/applause.json`;\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileContents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileContents) as Partial;\n}\n\n/**\n * Validates the configuration.\n * @param config - The configuration to validate.\n * @throws Error if the configuration is invalid.\n */\nexport function validateConfig(config: ApplauseConfig) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\n\n/**\n * Validates a partial configuration.\n * @param config - The partial configuration to validate.\n * @throws Error if the partial configuration is invalid.\n */\nexport function validatePartialConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n","import { AutoApi } from './auto-api.ts';\nimport { Inbox } from './email/inbox.ts';\n\n/**\n * Helper class for managing email functionality.\n */\nexport class EmailHelper {\n constructor(private autoApi: AutoApi) {}\n\n /**\n * Retrieves the inbox for the specified email prefix.\n *\n * @param emailPrefix - The prefix used to generate the email address.\n * @returns A Promise that resolves to an Inbox object.\n */\n async getInbox(emailPrefix: string): Promise {\n const generatedAddress: string = (\n await this.autoApi.getEmailAddress(emailPrefix)\n ).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\n\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n","import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport { TestRunAutoResultDto } from './dto.ts';\nimport {\n PublicApiConfig,\n validatePublicApiConfig,\n} from './public-api-config.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\nexport class PublicApi {\n private readonly client: AxiosInstance;\n\n private callsInFlight: number;\n private logger: winston.Logger;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n constructor(\n readonly options: PublicApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validatePublicApiConfig(options);\n this.client = axios.create({\n baseURL: options.publicApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n async submitResult(\n testCaseId: number,\n info: TestRunAutoResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n `v2/test-case-results/${testCaseId}/submit`,\n info\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n"],"names":["validator","Validator","default","DEFAULT_AUTO_API_PROPERTIES","autoApiBaseUrl","validateAutoApiConfig","config","Number","isInteger","productId","Error","isURL","protocols","require_tld","allow_query_components","disallow_auth","allow_fragments","allow_protocol_relative_urls","allow_trailing_dot","require_host","require_protocol","isEmpty","apiKey","MESSAGE","Symbol","for","WINSTON_DEFAULT_LOG_FORMAT","winston","format","printf","level","message","label","timestamp","constructDefaultLogger","createLogger","combine","splat","transports","File","filename","ApplauseTransport","Console","colorize","LoggingContainer","logs","getLogs","this","drainLogs","clearLogs","addLog","log","push","APPLAUSE_LOG_RECORDS","TransportStream","constructor","opts","super","info","callback","setImmediate","emit","transform","AutoApi","options","client","logger","callsInFlight","getCallsInFlight","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","JSON","stringify","status","statusText","Promise","reject","startTestRun","post","sdkVersion","itwTestCycleId","applauseTestCycleId","testRailReportingEnabled","testRailOptions","addAllTestsToPlan","testRailProjectId","projectId","testRailSuiteId","suiteId","testRailPlanName","planName","testRailRunName","runName","overrideTestRailRunNameUniqueness","overrideTestRailRunUniqueness","endTestRun","testRunId","delete","startTestCase","params","submitTestCaseResult","getProviderSessionLinks","resultIds","validIds","filter","id","sendSdkHeartbeat","getEmailAddress","emailPrefix","get","getEmailContent","request","uploadAsset","resultId","file","assetName","providerSessionGuid","assetType","postForm","TestResultStatus","AssetType","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","debug","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","parseTestCaseName","testCaseName","matches","match","testRailCaseIds","startsWith","map","substring","applauseCaseIds","length","console","warn","applauseTestCaseId","testRailTestCaseId","replace","trim","RunInitializer","initializeRun","tests","cleanedTests","testName","parsed","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","submission","testCaseId","itwTestCaseId","Object","fromEntries","entries","_","v","testResultId","attachTestCaseAsset","asset","runnerEnd","all","values","jsonArray","outputPath","writeFileSync","pathJoin","join","TestRunAutoResultStatus","DEFAULT_PUBLIC_API_PROPERTIES","publicApiBaseUrl","validatePublicApiConfig","overrideConfig","overrides","assign","isComplete","isAutoApiConfigComplete","isPublicApiConfigComplete","loadConfigFromFile","configFile","configFilePath","process","cwd","existsSync","fileContents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","env","r","parseInt","runnerStart","initializedReporter","toString","isSynchronized","getInbox","generatedAddress","submitResult","loadOptions","path","properties","finalConfig"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.mjs b/dist/index.mjs index 2cc8231..c2fe2ad 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -179,7 +179,7 @@ class AutoApi { sdkVersion: `js:${API_VERSION}`, // Copy over the product id productId: this.options.productId, - applauseTestCycleId: this.options.applauseTestCycleId, + itwTestCycleId: this.options.applauseTestCycleId, // Copy over test rail parameters testRailReportingEnabled: this.options.testRailOptions !== undefined, addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan, diff --git a/dist/index.mjs.map b/dist/index.mjs.map index 89ff64c..9914c70 100644 --- a/dist/index.mjs.map +++ b/dist/index.mjs.map @@ -1 +1 @@ -{"version":3,"file":"index.mjs","sources":["../src/auto-api/version.ts","../src/auto-api/auto-api-config.ts","../src/shared/logging.ts","../src/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/email-helper.ts","../src/auto-api/heartbeat.ts","../src/shared/test-case.ts","../src/auto-api/reporter.ts","../src/public-api/dto.ts","../src/public-api/public-api-config.ts","../src/public-api/public-api.ts","../src/config/config.ts"],"sourcesContent":["export const API_VERSION = '1.1.0';\n","import { TestRailOptions } from './dto.ts';\nimport Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface AutoApiConfig {\n readonly autoApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly testRailOptions?: TestRailOptions;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n\nexport const DEFAULT_AUTO_API_PROPERTIES: Partial = {\n autoApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isAutoApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialAutoApiConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validateAutoApiConfig(config: AutoApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import * as winston from 'winston';\nimport { TransformableInfo } from 'logform';\nimport TransportStream from 'winston-transport';\nconst MESSAGE = Symbol.for('message');\n\nexport const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf(\n ({ level, message, label, timestamp }) => {\n return `${timestamp} [${label}] ${level}: ${message}`;\n }\n);\n\nexport function constructDefaultLogger(): winston.Logger {\n return winston.createLogger({\n format: winston.format.combine(\n winston.format.label({ label: 'Applause Tests' }),\n winston.format.timestamp(),\n winston.format.splat(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n transports: [\n new winston.transports.File({ filename: 'error.log', level: 'error' }),\n new winston.transports.File({ filename: 'combined.log' }),\n new ApplauseTransport(),\n new winston.transports.Console({\n level: 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n }),\n ],\n });\n}\n\n/**\n * A simple Class for storing and retrieving log messages.\n */\nexport class LoggingContainer {\n private logs: string[] = [];\n\n /**\n * Retrieves all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public getLogs(): string[] {\n return this.logs;\n }\n\n /**\n * Retrieves and clears all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public drainLogs(): string[] {\n const logs = this.logs;\n this.clearLogs();\n return logs;\n }\n\n /**\n * Clears all logs stored in the container.\n */\n public clearLogs(): void {\n this.logs = [];\n }\n\n /**\n * Adds a log message to the container.\n *\n * @param log - The log message to add.\n */\n public addLog(log: string): void {\n this.logs.push(log);\n }\n}\n\n// Create a new Shared LoggingContainer to store logs\nexport const APPLAUSE_LOG_RECORDS: LoggingContainer = new LoggingContainer();\n\n/**\n * A Custom Winston Transport that sends logs to the Applause LoggingContainer\n */\nexport class ApplauseTransport extends TransportStream {\n constructor(opts?: TransportStream.TransportStreamOptions) {\n super(opts);\n }\n\n log(info: TransformableInfo, callback: () => void): void {\n setImmediate(() => {\n this.emit('logged', info);\n });\n\n this.format?.transform(info);\n APPLAUSE_LOG_RECORDS.addLog(\n (info[MESSAGE] as string | undefined) ?? (info.message as string)\n );\n\n // Continue to the next transport\n callback();\n }\n}\n","/**\n * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform.\n * The `AutoApi` class provides methods for starting and ending test runs, creating test cases, submitting test case results, and performing other operations related to test management.\n * It also includes properties and methods to track the number of HTTP calls in progress.\n */\n\nimport axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport {\n AssetType,\n CreateTestCaseResultDto,\n CreateTestCaseResultResponseDto,\n EmailAddressResponse,\n EmailFetchRequest,\n SubmitTestCaseResultDto,\n TestResultProviderInfo,\n TestRunCreateDto,\n TestRunCreateResponseDto,\n} from './dto.ts';\nimport { API_VERSION } from './version.ts';\nimport { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\nimport * as winston from 'winston';\n\nexport class AutoApi {\n private readonly client: AxiosInstance;\n\n private logger: winston.Logger;\n private callsInFlight: number;\n /**\n * Tracks the number of HTTP calls in progress.\n * This property is used by reporters that want to know when the async work is finished.\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n /**\n * Creates an instance of the `AutoApi` class.\n * @param options - The configuration options for the Applause API.\n */\n constructor(\n readonly options: AutoApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validateAutoApiConfig(options);\n this.client = axios.create({\n baseURL: options.autoApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * Starts a new test run.\n * @param info - The information for creating the test run.\n * @returns A promise that resolves to the response containing the created test run.\n */\n async startTestRun(\n info: TestRunCreateDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n '/api/v1.0/test-run/create',\n {\n // Provided params\n ...info,\n\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n\n // Copy over the product id\n productId: this.options.productId,\n\n applauseTestCycleId: this.options.applauseTestCycleId,\n\n // Copy over test rail parameters\n testRailReportingEnabled: this.options.testRailOptions !== undefined,\n addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan,\n testRailProjectId: this.options.testRailOptions?.projectId,\n testRailSuiteId: this.options.testRailOptions?.suiteId,\n testRailPlanName: this.options.testRailOptions?.planName,\n testRailRunName: this.options.testRailOptions?.runName,\n overrideTestRailRunNameUniqueness:\n this.options.testRailOptions?.overrideTestRailRunUniqueness,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Ends a test run.\n * @param testRunId - The ID of the test run to end.\n * @returns A promise that resolves to the response indicating the completion of the test run.\n */\n async endTestRun(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(\n `/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Starts a new test case.\n * @param params - The parameters for creating the test case.\n * @returns A promise that resolves to the response containing the created test case.\n */\n async startTestCase(\n params: CreateTestCaseResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post(\n '/api/v1.0/test-result/create-result',\n params\n );\n return res;\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Submits a test case result.\n * @param params - The parameters for submitting the test case result.\n * @returns A promise that resolves when the test case result is submitted.\n */\n async submitTestCaseResult(params: SubmitTestCaseResultDto): Promise {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the provider session links for the specified test results.\n * @param resultIds - The IDs of the test results.\n * @returns A promise that resolves to the response containing the provider session links.\n */\n async getProviderSessionLinks(\n resultIds: number[]\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds: number[] = resultIds.filter(id => id);\n return await this.client.post(\n '/api/v1.0/test-result/provider-info',\n validIds\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Sends a heartbeat for the specified test run.\n * @param testRunId - The ID of the test run.\n * @returns A promise that resolves to the response indicating the heartbeat was sent.\n */\n async sendSdkHeartbeat(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v2.0/sdk-heartbeat', {\n testRunId: testRunId,\n });\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the email address for the specified email prefix.\n * @param emailPrefix - The prefix of the email address.\n * @returns A promise that resolves to the response containing the email address.\n */\n async getEmailAddress(\n emailPrefix: string\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(\n `/api/v1.0/email/get-address?prefix=${emailPrefix}`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the content of the specified email.\n * @param request - The request parameters for retrieving the email content.\n * @returns A promise that resolves to the response containing the email content.\n */\n async getEmailContent(\n request: EmailFetchRequest\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post(\n '/api/v1.0/email/download-email',\n request\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Uploads an asset for the specified test result.\n * @param resultId - The ID of the test result.\n * @param file - The file to upload as an asset.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The GUID of the provider session.\n * @param assetType - The type of the asset.\n * @returns A promise that resolves to the response indicating the asset was uploaded.\n */\n async uploadAsset(\n resultId: number,\n file: Buffer,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType\n ): Promise> {\n this.callsInFlight += 1;\n\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.postForm(\n `/api/v1.0/test-result/${resultId}/upload`,\n {\n file,\n assetName,\n providerSessionGuid,\n assetType,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Configuration of the auto-api client\n */\nexport type ClientConfig = {\n readonly baseUrl: string;\n readonly apiKey: string;\n};\n\n/**\n * DTO used to create a new Applause test run\n */\nexport interface TestRunCreateDto {\n // Required: a list of test cases to pre-create\n tests: string[];\n}\n\n/**\n * DTO modeling the response to a test run creation request\n */\nexport interface TestRunCreateResponseDto {\n // The ID of the Applause Test Run\n runId: number;\n}\n\nexport interface AdditionalTestCaseParams {\n // A collection of provider session guids\n providerSessionIds?: string[];\n\n // Optional: TestRail Test Case Id\n testCaseId?: string;\n\n // Optional: Applause Test Case Id\n itwTestCaseId?: string;\n}\n\n/**\n * DTO used to mark the start of a test result\n */\nexport interface CreateTestCaseResultDto extends AdditionalTestCaseParams {\n // ID of the test run to submit this result to\n testRunId: number;\n\n // Name of the Test Case\n testCaseName: string;\n}\n\n/**\n * DTO response to a test result creation request\n */\nexport interface CreateTestCaseResultResponseDto {\n testResultId: number;\n}\n\nexport interface AdditionalTestCaseResultParams {\n // A list of selenium provider session ids to connect to the result\n providerSessionGuids?: string[];\n\n // An optional testrail test case id\n testRailCaseId?: number;\n\n // An optional applause test case id\n itwCaseId?: number;\n\n // The reason a test case failed\n failureReason?: string;\n}\n\n/**\n * DTO used to submit a status to an in progress test result.\n */\nexport interface SubmitTestCaseResultDto\n extends AdditionalTestCaseResultParams {\n // The id of the test result\n testResultId: number;\n\n // The ending status of the test.\n status: TestResultStatus;\n}\n\n/**\n * Enum representing a test result's status\n */\nexport enum TestResultStatus {\n NOT_RUN = 'NOT_RUN',\n IN_PROGRESS = 'IN_PROGRESS',\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\n/**\n * DTO representing test result info that is provided at the end of a test run\n */\nexport interface TestResultProviderInfo {\n testResultId: number;\n providerUrl: string;\n providerSessionId: string;\n}\n\n/**\n * DTO representing TestRail settings. The presence of this info signals that test rail reporting is enabled\n */\nexport interface TestRailOptions {\n projectId: number;\n suiteId: number;\n planName: string;\n runName: string;\n addAllTestsToPlan?: boolean;\n overrideTestRailRunUniqueness?: boolean;\n}\n\n/**\n * DTO containing a generated email address for testing\n */\nexport interface EmailAddressResponse {\n emailAddress: string;\n}\n\n/**\n * DTO used for fetching an email from a given email address\n */\nexport interface EmailFetchRequest {\n emailAddress: string;\n}\n\nexport enum AssetType {\n SCREENSHOT = 'SCREENSHOT',\n FAILURE_SCREENSHOT = 'FAILURE_SCREENSHOT',\n VIDEO = 'VIDEO',\n NETWORK_HAR = 'NETWORK_HAR',\n VITALS_LOG = 'VITALS_LOG',\n CONSOLE_LOG = 'CONSOLE_LOG',\n NETWORK_LOG = 'NETWORK_LOG',\n DEVICE_LOG = 'DEVICE_LOG',\n SELENIUM_LOG = 'SELENIUM_LOG',\n SELENIUM_LOG_JSON = 'SELENIUM_LOG_JSON',\n BROWSER_LOG = 'BROWSER_LOG',\n FRAMEWORK_LOG = 'FRAMEWORK_LOG',\n EMAIL = 'EMAIL',\n PAGE_SOURCE = 'PAGE_SOURCE',\n CODE_BUNDLE = 'CODE_BUNDLE',\n RESULTS_ZIP = 'RESULTS_ZIP',\n SESSION_DETAILS = 'SESSION_DETAILS',\n DEVICE_DETAILS = 'DEVICE_DETAILS',\n UNKNOWN = 'UNKNOWN',\n}\n","import { AutoApi } from '../auto-api.ts';\nimport { ParsedMail, simpleParser } from 'mailparser';\n\n/**\n * Represents an email inbox.\n */\nexport class Inbox {\n /**\n * Creates an instance of Inbox.\n * @param emailAddress - The email address associated with the inbox.\n * @param autoApi - An instance of the AutoApi class.\n */\n constructor(\n public readonly emailAddress: string,\n private autoApi: AutoApi\n ) {}\n\n /**\n * Retrieves the content of an email from the inbox.\n * @returns A Promise that resolves to the parsed email content.\n */\n async getEmail(): Promise {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n","import { AutoApi } from './auto-api.ts';\nimport { Inbox } from './email/inbox.ts';\n\n/**\n * Helper class for managing email functionality.\n */\nexport class EmailHelper {\n constructor(private autoApi: AutoApi) {}\n\n /**\n * Retrieves the inbox for the specified email prefix.\n *\n * @param emailPrefix - The prefix used to generate the email address.\n * @returns A Promise that resolves to an Inbox object.\n */\n async getInbox(emailPrefix: string): Promise {\n const generatedAddress: string = (\n await this.autoApi.getEmailAddress(emailPrefix)\n ).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\n\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n","import winston = require('winston');\nimport { AutoApi } from './auto-api.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents a service for sending heartbeats during a test run.\n */\nexport class TestRunHeartbeatService {\n private enabled = false;\n private nextHeartbeat?: Promise;\n private readonly logger: winston.Logger;\n\n /**\n * Creates an instance of TestRunHeartbeatService.\n * @param testRunId - The ID of the test run.\n * @param autoApi - The AutoApi instance used for sending heartbeats.\n */\n constructor(\n readonly testRunId: number,\n readonly autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts sending heartbeats.\n * @returns A promise that resolves when the heartbeats are started.\n */\n async start(): Promise {\n // End the current heartbeat if it has started\n await this.end();\n\n // Set up a new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Checks if the heartbeats are enabled.\n * @returns True if the heartbeats are enabled, false otherwise.\n */\n public isEnabled(): boolean {\n return this.enabled;\n }\n\n private scheduleNextHeartbeat(): void {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(\n () => this.sendHeartbeat()\n );\n }\n\n private async sendHeartbeat(): Promise {\n this.logger.debug('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n this.logger.debug('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Ends the heartbeats.\n * @returns A promise that resolves when the heartbeats are ended.\n */\n async end(): Promise {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n this.logger.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n this.logger.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n","import * as winston from 'winston';\n\nexport const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-';\n\nexport function parseTestCaseName(\n testCaseName: string,\n logger?: winston.Logger\n): ParsedTestCaseName {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds =\n matches\n ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX))\n .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? [];\n const applauseCaseIds =\n matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? [];\n\n if (testRailCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple TestRail case ids detected in testCase name'\n );\n }\n if (applauseCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple Applause case ids detected in testCase name'\n );\n }\n return {\n applauseTestCaseId: applauseCaseIds[0],\n testRailTestCaseId: testRailCaseIds[0],\n testCaseName: testCaseName\n .replace(/(TestRail-\\d+|Applause-\\d+)/g, '')\n .replace(/\\s+/g, ' ')\n .trim(),\n };\n}\n\nexport interface ParsedTestCaseName {\n testCaseName: string;\n testRailTestCaseId?: string;\n applauseTestCaseId?: string;\n}\n","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport {\n AdditionalTestCaseParams,\n AdditionalTestCaseResultParams,\n AssetType,\n TestResultStatus,\n} from './dto.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { AutoApiConfig } from './auto-api-config.ts';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents an Applause reporter.\n */\nexport class ApplauseReporter {\n private autoApi: AutoApi;\n private initializer: RunInitializer;\n private logger: winston.Logger;\n private reporter?: Promise;\n private runStarted: boolean = false;\n private runFinished: boolean = false;\n\n /**\n * Creates an instance of ApplauseReporter.\n * @param config - The Applause configuration.\n */\n constructor(config: AutoApiConfig, logger?: winston.Logger) {\n this.logger = logger ?? constructDefaultLogger();\n this.autoApi = new AutoApi(config, this.logger);\n this.initializer = new RunInitializer(this.autoApi, this.logger);\n const runId = process.env['APPLAUSE_RUN_ID'];\n if (runId !== undefined) {\n const r = new RunReporter(\n this.autoApi,\n parseInt(runId),\n undefined,\n this.logger\n );\n this.reporter = new Promise(resolve => resolve(r));\n this.runStarted = true;\n }\n }\n\n /**\n * Starts the Applause runner.\n * @param tests - Optional array of test names to run.\n * @returns A promise that resolves to the test run ID.\n * @throws Error if a run is already started or finished.\n */\n public async runnerStart(tests?: string[]): Promise {\n if (this.reporter !== undefined) {\n this.logger.error(\n 'Cannot start a run - run already started or run already finished'\n );\n throw new Error(\n 'Cannot start a run - run already started or run already finished'\n );\n }\n this.reporter = this.initializer.initializeRun(tests);\n const initializedReporter = await this.reporter;\n this.runStarted = true;\n process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString();\n return initializedReporter.testRunId;\n }\n\n /**\n * Starts a test case.\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Optional additional parameters for the test case.\n * @returns A promise that resolves to the test case ID.\n * @throws Error if a run was never initialized.\n */\n public async startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot start a test case for a run that was never initialized'\n );\n throw new Error(\n 'Cannot start a test case for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.startTestCase(id, testCaseName, params);\n }\n\n /**\n * Submits a test case result.\n * @param id - The ID of the test case.\n * @param status - The status of the test case result.\n * @param params - Optional additional parameters for the test case result.\n * @returns A promise that resolves to the test case result ID.\n * @throws Error if a run was never initialized.\n */\n public async submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n throw new Error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.submitTestCaseResult(id, status, params);\n }\n\n /**\n * Ends the Applause runner.\n * @returns A promise that resolves when the runner is ended.\n * @throws Error if a run was never initialized.\n */\n public async runnerEnd(): Promise {\n if (this.reporter === undefined) {\n this.logger.error('Cannot end a run that was never initialized');\n throw new Error('Cannot end a run that was never initialized');\n }\n await this.reporter\n .then(reporter => reporter.runnerEnd())\n .then(() => (this.runFinished = true));\n }\n\n /**\n * Attaches an asset to a test case.\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset data as a Buffer.\n * @returns A promise that resolves when the asset is attached.\n * @throws Error if a run was never initialized.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n throw new Error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n }\n return await this.reporter.then(reporter =>\n reporter.attachTestCaseAsset(\n id,\n assetName,\n providerSessionGuid,\n assetType,\n asset\n )\n );\n }\n\n /**\n * Checks if the Applause runner is synchronized.\n * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished.\n */\n public isSynchronized(): boolean {\n return (\n (!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0\n );\n }\n}\n\n/**\n * Represents a Run Initializer.\n */\nexport class RunInitializer {\n private logger: winston.Logger;\n constructor(\n private autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Initializes a test run.\n * @param tests - An optional array of test names to include in the run.\n * @returns A promise that resolves to a RunReporter instance.\n * @throws An error if unable to create the test run.\n */\n async initializeRun(tests?: string[]): Promise {\n const cleanedTests = tests\n ?.map(testName => parseTestCaseName(testName, this.logger))\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests ?? [],\n });\n if (\n testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300\n ) {\n this.logger.error(\n `Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`\n );\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n this.logger.info(`Test Run ${runId} initialized`);\n const heartbeatService = new TestRunHeartbeatService(\n runId,\n this.autoApi,\n this.logger\n );\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService, this.logger);\n }\n}\n\n/**\n * Handles reporting test results to the Applause API.\n */\nexport class RunReporter {\n private uidToResultIdMap: Record> = {};\n private resultSubmissionMap: Record> = {};\n private logger: winston.Logger;\n\n /**\n * Creates a new instance of the Reporter class.\n * @param autoApi - The AutoApi instance.\n * @param testRunId - The ID of the test run.\n * @param heartbeatService - (Optional) The TestRunHeartbeatService instance.\n */\n constructor(\n private autoApi: AutoApi,\n public readonly testRunId: number,\n private heartbeatService?: TestRunHeartbeatService,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts a test case and returns a promise that resolves to the test result ID.\n *\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Additional parameters for the test case.\n * @returns A promise that resolves to the test result ID.\n */\n public startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (!testCaseName) {\n this.logger.error('testCaseName is required');\n throw new Error('testCaseName is required');\n }\n const parsedTestCase = parseTestCaseName(testCaseName, this.logger);\n const submission = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\n\n testRunId: this.testRunId,\n // If the additional params provides either test case id, it will override the parsed value we set above\n ...Object.fromEntries(\n Object.entries(params || {}).filter(([_, v]) => v !== undefined)\n ),\n })\n .then(res => {\n return res.data.testResultId;\n });\n this.uidToResultIdMap[id] = submission;\n return submission;\n }\n\n /**\n * Submits the result of a test case.\n *\n * @param id - The ID of the test case.\n * @param status - The status of the test result.\n * @param params - Additional parameters for the test result.\n * @returns A promise that resolves to the result ID.\n */\n public submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n const submission = this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi\n .submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n })\n .then(() => resultId)\n );\n this.resultSubmissionMap[id] = submission;\n return submission;\n }\n\n /**\n * Attaches a test case asset to a result.\n *\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset to attach.\n * @returns A promise that resolves when the asset is attached.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n await this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi.uploadAsset(\n resultId,\n asset,\n assetName,\n providerSessionGuid,\n assetType\n )\n );\n }\n\n /**\n * Ends the test runner and performs necessary cleanup tasks.\n * @returns A promise that resolves when the runner has ended.\n */\n public async runnerEnd(): Promise {\n // Wait for all results to be created\n const resultIds =\n (await Promise.all(Object.values(this.uidToResultIdMap))) ?? [];\n\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n\n // Wait the heartbeat to be ended\n void (await this.heartbeatService?.end());\n void (await this.autoApi.endTestRun(this.testRunId));\n\n // Fetch the provider session asset links and save them off to a file\n const resp = await this.autoApi.getProviderSessionLinks(resultIds);\n const jsonArray = resp.data ?? [];\n if (jsonArray.length > 0) {\n this.logger.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(\n pathJoin(outputPath, 'providerUrls.txt'),\n JSON.stringify(jsonArray, null, 1)\n );\n }\n }\n}\n","export interface TestRunAutoResultDto {\n testCycleId: number;\n status: TestRunAutoResultStatus;\n failureReason?: string;\n sessionDetailsJson?: SessionDetails;\n startTime?: Date;\n endTime?: Date;\n}\n\nexport enum TestRunAutoResultStatus {\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\nexport interface SessionDetails {\n value: {\n deviceName?: string;\n orientation?: string;\n platformName?: string;\n platformVersion?: string;\n browserName?: string;\n browserVersion?: string;\n };\n}\n","import Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface PublicApiConfig {\n readonly publicApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://api.applause.com/';\n\nexport const DEFAULT_PUBLIC_API_PROPERTIES: Partial = {\n publicApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isPublicApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialPublicApiConfig(\n config: Partial\n) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validatePublicApiConfig(config: PublicApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport { TestRunAutoResultDto } from './dto.ts';\nimport {\n PublicApiConfig,\n validatePublicApiConfig,\n} from './public-api-config.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\nexport class PublicApi {\n private readonly client: AxiosInstance;\n\n private callsInFlight: number;\n private logger: winston.Logger;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n constructor(\n readonly options: PublicApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validatePublicApiConfig(options);\n this.client = axios.create({\n baseURL: options.publicApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n async submitResult(\n testCaseId: number,\n info: TestRunAutoResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n `v2/test-case-results/${testCaseId}/submit`,\n info\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Represents the configuration options for the Applause Reporter.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport path from 'path';\n\nimport {\n AutoApiConfig,\n DEFAULT_AUTO_API_PROPERTIES,\n isAutoApiConfigComplete,\n validateAutoApiConfig,\n} from '../auto-api/auto-api-config.ts';\nimport {\n DEFAULT_PUBLIC_API_PROPERTIES,\n isPublicApiConfigComplete,\n PublicApiConfig,\n validatePublicApiConfig,\n} from '../public-api/public-api-config.ts';\n\nexport type ApplauseConfig = AutoApiConfig & PublicApiConfig;\n\n/**\n * Represents the properties for loading the configuration.\n */\nexport interface ConfigLoadProperties {\n configFile?: string;\n properties?: Partial;\n}\n\n/**\n * Loads the configuration for the Applause Reporter.\n * @param loadOptions - The options for loading the configuration.\n * @returns The loaded Applause configuration.\n * @throws Error if the configuration is not complete or invalid.\n */\nexport function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig {\n // Setup the initial config with any default properties\n let config: Partial = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(\n config,\n loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))\n );\n } else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n\n // We know that the config is complete, so we can cast\n const finalConfig = config as ApplauseConfig;\n\n validateConfig(finalConfig);\n\n return finalConfig;\n}\n\n/**\n * Overrides the configuration with the provided overrides.\n * @param config - The base configuration.\n * @param overrides - The overrides to apply.\n * @returns The overridden configuration.\n */\nexport function overrideConfig(\n config: Partial,\n overrides?: Partial\n): Partial {\n return Object.assign(\n {},\n config,\n Object.fromEntries(\n Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined)\n )\n );\n}\n\n/**\n * Checks if the configuration is complete.\n * @param config - The configuration to check.\n * @returns True if the configuration is complete, false otherwise.\n */\nexport function isComplete(config: Partial): boolean {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\n\n/**\n * Loads the configuration from the specified file.\n * @param configFile - The path to the configuration file.\n * @returns The loaded configuration from the file.\n */\nexport function loadConfigFromFile(\n configFile?: string\n): Partial {\n const configFilePath = configFile ?? `${process.cwd()}/applause.json`;\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileContents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileContents) as Partial;\n}\n\n/**\n * Validates the configuration.\n * @param config - The configuration to validate.\n * @throws Error if the configuration is invalid.\n */\nexport function validateConfig(config: ApplauseConfig) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\n\n/**\n * Validates a partial configuration.\n * @param config - The partial configuration to validate.\n * @throws Error if the partial configuration is invalid.\n */\nexport function validatePartialConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n"],"names":["validator","DEFAULT_URL","pathJoin"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.mjs","sources":["../src/auto-api/version.ts","../src/auto-api/auto-api-config.ts","../src/shared/logging.ts","../src/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/email-helper.ts","../src/auto-api/heartbeat.ts","../src/shared/test-case.ts","../src/auto-api/reporter.ts","../src/public-api/dto.ts","../src/public-api/public-api-config.ts","../src/public-api/public-api.ts","../src/config/config.ts"],"sourcesContent":["export const API_VERSION = '1.1.0';\n","import { TestRailOptions } from './dto.ts';\nimport Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface AutoApiConfig {\n readonly autoApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly testRailOptions?: TestRailOptions;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n\nexport const DEFAULT_AUTO_API_PROPERTIES: Partial = {\n autoApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isAutoApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialAutoApiConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validateAutoApiConfig(config: AutoApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import * as winston from 'winston';\nimport { TransformableInfo } from 'logform';\nimport TransportStream from 'winston-transport';\nconst MESSAGE = Symbol.for('message');\n\nexport const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf(\n ({ level, message, label, timestamp }) => {\n return `${timestamp} [${label}] ${level}: ${message}`;\n }\n);\n\nexport function constructDefaultLogger(): winston.Logger {\n return winston.createLogger({\n format: winston.format.combine(\n winston.format.label({ label: 'Applause Tests' }),\n winston.format.timestamp(),\n winston.format.splat(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n transports: [\n new winston.transports.File({ filename: 'error.log', level: 'error' }),\n new winston.transports.File({ filename: 'combined.log' }),\n new ApplauseTransport(),\n new winston.transports.Console({\n level: 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n WINSTON_DEFAULT_LOG_FORMAT\n ),\n }),\n ],\n });\n}\n\n/**\n * A simple Class for storing and retrieving log messages.\n */\nexport class LoggingContainer {\n private logs: string[] = [];\n\n /**\n * Retrieves all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public getLogs(): string[] {\n return this.logs;\n }\n\n /**\n * Retrieves and clears all logs stored in the container.\n *\n * @returns An array of log messages.\n */\n public drainLogs(): string[] {\n const logs = this.logs;\n this.clearLogs();\n return logs;\n }\n\n /**\n * Clears all logs stored in the container.\n */\n public clearLogs(): void {\n this.logs = [];\n }\n\n /**\n * Adds a log message to the container.\n *\n * @param log - The log message to add.\n */\n public addLog(log: string): void {\n this.logs.push(log);\n }\n}\n\n// Create a new Shared LoggingContainer to store logs\nexport const APPLAUSE_LOG_RECORDS: LoggingContainer = new LoggingContainer();\n\n/**\n * A Custom Winston Transport that sends logs to the Applause LoggingContainer\n */\nexport class ApplauseTransport extends TransportStream {\n constructor(opts?: TransportStream.TransportStreamOptions) {\n super(opts);\n }\n\n log(info: TransformableInfo, callback: () => void): void {\n setImmediate(() => {\n this.emit('logged', info);\n });\n\n this.format?.transform(info);\n APPLAUSE_LOG_RECORDS.addLog(\n (info[MESSAGE] as string | undefined) ?? (info.message as string)\n );\n\n // Continue to the next transport\n callback();\n }\n}\n","/**\n * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform.\n * The `AutoApi` class provides methods for starting and ending test runs, creating test cases, submitting test case results, and performing other operations related to test management.\n * It also includes properties and methods to track the number of HTTP calls in progress.\n */\n\nimport axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport {\n AssetType,\n CreateTestCaseResultDto,\n CreateTestCaseResultResponseDto,\n EmailAddressResponse,\n EmailFetchRequest,\n SubmitTestCaseResultDto,\n TestResultProviderInfo,\n TestRunCreateDto,\n TestRunCreateResponseDto,\n} from './dto.ts';\nimport { API_VERSION } from './version.ts';\nimport { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\nimport * as winston from 'winston';\n\nexport class AutoApi {\n private readonly client: AxiosInstance;\n\n private logger: winston.Logger;\n private callsInFlight: number;\n /**\n * Tracks the number of HTTP calls in progress.\n * This property is used by reporters that want to know when the async work is finished.\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n /**\n * Creates an instance of the `AutoApi` class.\n * @param options - The configuration options for the Applause API.\n */\n constructor(\n readonly options: AutoApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validateAutoApiConfig(options);\n this.client = axios.create({\n baseURL: options.autoApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * Starts a new test run.\n * @param info - The information for creating the test run.\n * @returns A promise that resolves to the response containing the created test run.\n */\n async startTestRun(\n info: TestRunCreateDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n '/api/v1.0/test-run/create',\n {\n // Provided params\n ...info,\n\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n\n // Copy over the product id\n productId: this.options.productId,\n\n itwTestCycleId: this.options.applauseTestCycleId,\n\n // Copy over test rail parameters\n testRailReportingEnabled: this.options.testRailOptions !== undefined,\n addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan,\n testRailProjectId: this.options.testRailOptions?.projectId,\n testRailSuiteId: this.options.testRailOptions?.suiteId,\n testRailPlanName: this.options.testRailOptions?.planName,\n testRailRunName: this.options.testRailOptions?.runName,\n overrideTestRailRunNameUniqueness:\n this.options.testRailOptions?.overrideTestRailRunUniqueness,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Ends a test run.\n * @param testRunId - The ID of the test run to end.\n * @returns A promise that resolves to the response indicating the completion of the test run.\n */\n async endTestRun(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(\n `/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Starts a new test case.\n * @param params - The parameters for creating the test case.\n * @returns A promise that resolves to the response containing the created test case.\n */\n async startTestCase(\n params: CreateTestCaseResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post(\n '/api/v1.0/test-result/create-result',\n params\n );\n return res;\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Submits a test case result.\n * @param params - The parameters for submitting the test case result.\n * @returns A promise that resolves when the test case result is submitted.\n */\n async submitTestCaseResult(params: SubmitTestCaseResultDto): Promise {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the provider session links for the specified test results.\n * @param resultIds - The IDs of the test results.\n * @returns A promise that resolves to the response containing the provider session links.\n */\n async getProviderSessionLinks(\n resultIds: number[]\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds: number[] = resultIds.filter(id => id);\n return await this.client.post(\n '/api/v1.0/test-result/provider-info',\n validIds\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Sends a heartbeat for the specified test run.\n * @param testRunId - The ID of the test run.\n * @returns A promise that resolves to the response indicating the heartbeat was sent.\n */\n async sendSdkHeartbeat(testRunId: number): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v2.0/sdk-heartbeat', {\n testRunId: testRunId,\n });\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the email address for the specified email prefix.\n * @param emailPrefix - The prefix of the email address.\n * @returns A promise that resolves to the response containing the email address.\n */\n async getEmailAddress(\n emailPrefix: string\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(\n `/api/v1.0/email/get-address?prefix=${emailPrefix}`\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Retrieves the content of the specified email.\n * @param request - The request parameters for retrieving the email content.\n * @returns A promise that resolves to the response containing the email content.\n */\n async getEmailContent(\n request: EmailFetchRequest\n ): Promise> {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post(\n '/api/v1.0/email/download-email',\n request\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n\n /**\n * Uploads an asset for the specified test result.\n * @param resultId - The ID of the test result.\n * @param file - The file to upload as an asset.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The GUID of the provider session.\n * @param assetType - The type of the asset.\n * @returns A promise that resolves to the response indicating the asset was uploaded.\n */\n async uploadAsset(\n resultId: number,\n file: Buffer,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType\n ): Promise> {\n this.callsInFlight += 1;\n\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.postForm(\n `/api/v1.0/test-result/${resultId}/upload`,\n {\n file,\n assetName,\n providerSessionGuid,\n assetType,\n }\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Configuration of the auto-api client\n */\nexport type ClientConfig = {\n readonly baseUrl: string;\n readonly apiKey: string;\n};\n\n/**\n * DTO used to create a new Applause test run\n */\nexport interface TestRunCreateDto {\n // Required: a list of test cases to pre-create\n tests: string[];\n}\n\n/**\n * DTO modeling the response to a test run creation request\n */\nexport interface TestRunCreateResponseDto {\n // The ID of the Applause Test Run\n runId: number;\n}\n\nexport interface AdditionalTestCaseParams {\n // A collection of provider session guids\n providerSessionIds?: string[];\n\n // Optional: TestRail Test Case Id\n testCaseId?: string;\n\n // Optional: Applause Test Case Id\n itwTestCaseId?: string;\n}\n\n/**\n * DTO used to mark the start of a test result\n */\nexport interface CreateTestCaseResultDto extends AdditionalTestCaseParams {\n // ID of the test run to submit this result to\n testRunId: number;\n\n // Name of the Test Case\n testCaseName: string;\n}\n\n/**\n * DTO response to a test result creation request\n */\nexport interface CreateTestCaseResultResponseDto {\n testResultId: number;\n}\n\nexport interface AdditionalTestCaseResultParams {\n // A list of selenium provider session ids to connect to the result\n providerSessionGuids?: string[];\n\n // An optional testrail test case id\n testRailCaseId?: number;\n\n // An optional applause test case id\n itwCaseId?: number;\n\n // The reason a test case failed\n failureReason?: string;\n}\n\n/**\n * DTO used to submit a status to an in progress test result.\n */\nexport interface SubmitTestCaseResultDto\n extends AdditionalTestCaseResultParams {\n // The id of the test result\n testResultId: number;\n\n // The ending status of the test.\n status: TestResultStatus;\n}\n\n/**\n * Enum representing a test result's status\n */\nexport enum TestResultStatus {\n NOT_RUN = 'NOT_RUN',\n IN_PROGRESS = 'IN_PROGRESS',\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\n/**\n * DTO representing test result info that is provided at the end of a test run\n */\nexport interface TestResultProviderInfo {\n testResultId: number;\n providerUrl: string;\n providerSessionId: string;\n}\n\n/**\n * DTO representing TestRail settings. The presence of this info signals that test rail reporting is enabled\n */\nexport interface TestRailOptions {\n projectId: number;\n suiteId: number;\n planName: string;\n runName: string;\n addAllTestsToPlan?: boolean;\n overrideTestRailRunUniqueness?: boolean;\n}\n\n/**\n * DTO containing a generated email address for testing\n */\nexport interface EmailAddressResponse {\n emailAddress: string;\n}\n\n/**\n * DTO used for fetching an email from a given email address\n */\nexport interface EmailFetchRequest {\n emailAddress: string;\n}\n\nexport enum AssetType {\n SCREENSHOT = 'SCREENSHOT',\n FAILURE_SCREENSHOT = 'FAILURE_SCREENSHOT',\n VIDEO = 'VIDEO',\n NETWORK_HAR = 'NETWORK_HAR',\n VITALS_LOG = 'VITALS_LOG',\n CONSOLE_LOG = 'CONSOLE_LOG',\n NETWORK_LOG = 'NETWORK_LOG',\n DEVICE_LOG = 'DEVICE_LOG',\n SELENIUM_LOG = 'SELENIUM_LOG',\n SELENIUM_LOG_JSON = 'SELENIUM_LOG_JSON',\n BROWSER_LOG = 'BROWSER_LOG',\n FRAMEWORK_LOG = 'FRAMEWORK_LOG',\n EMAIL = 'EMAIL',\n PAGE_SOURCE = 'PAGE_SOURCE',\n CODE_BUNDLE = 'CODE_BUNDLE',\n RESULTS_ZIP = 'RESULTS_ZIP',\n SESSION_DETAILS = 'SESSION_DETAILS',\n DEVICE_DETAILS = 'DEVICE_DETAILS',\n UNKNOWN = 'UNKNOWN',\n}\n","import { AutoApi } from '../auto-api.ts';\nimport { ParsedMail, simpleParser } from 'mailparser';\n\n/**\n * Represents an email inbox.\n */\nexport class Inbox {\n /**\n * Creates an instance of Inbox.\n * @param emailAddress - The email address associated with the inbox.\n * @param autoApi - An instance of the AutoApi class.\n */\n constructor(\n public readonly emailAddress: string,\n private autoApi: AutoApi\n ) {}\n\n /**\n * Retrieves the content of an email from the inbox.\n * @returns A Promise that resolves to the parsed email content.\n */\n async getEmail(): Promise {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n","import { AutoApi } from './auto-api.ts';\nimport { Inbox } from './email/inbox.ts';\n\n/**\n * Helper class for managing email functionality.\n */\nexport class EmailHelper {\n constructor(private autoApi: AutoApi) {}\n\n /**\n * Retrieves the inbox for the specified email prefix.\n *\n * @param emailPrefix - The prefix used to generate the email address.\n * @returns A Promise that resolves to an Inbox object.\n */\n async getInbox(emailPrefix: string): Promise {\n const generatedAddress: string = (\n await this.autoApi.getEmailAddress(emailPrefix)\n ).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\n\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n","import winston = require('winston');\nimport { AutoApi } from './auto-api.ts';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents a service for sending heartbeats during a test run.\n */\nexport class TestRunHeartbeatService {\n private enabled = false;\n private nextHeartbeat?: Promise;\n private readonly logger: winston.Logger;\n\n /**\n * Creates an instance of TestRunHeartbeatService.\n * @param testRunId - The ID of the test run.\n * @param autoApi - The AutoApi instance used for sending heartbeats.\n */\n constructor(\n readonly testRunId: number,\n readonly autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts sending heartbeats.\n * @returns A promise that resolves when the heartbeats are started.\n */\n async start(): Promise {\n // End the current heartbeat if it has started\n await this.end();\n\n // Set up a new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Checks if the heartbeats are enabled.\n * @returns True if the heartbeats are enabled, false otherwise.\n */\n public isEnabled(): boolean {\n return this.enabled;\n }\n\n private scheduleNextHeartbeat(): void {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(\n () => this.sendHeartbeat()\n );\n }\n\n private async sendHeartbeat(): Promise {\n this.logger.debug('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n this.logger.debug('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Ends the heartbeats.\n * @returns A promise that resolves when the heartbeats are ended.\n */\n async end(): Promise {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n this.logger.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n this.logger.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n","import * as winston from 'winston';\n\nexport const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-';\n\nexport function parseTestCaseName(\n testCaseName: string,\n logger?: winston.Logger\n): ParsedTestCaseName {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds =\n matches\n ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX))\n .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? [];\n const applauseCaseIds =\n matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? [];\n\n if (testRailCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple TestRail case ids detected in testCase name'\n );\n }\n if (applauseCaseIds.length > 1) {\n (logger ?? console).warn(\n 'Multiple Applause case ids detected in testCase name'\n );\n }\n return {\n applauseTestCaseId: applauseCaseIds[0],\n testRailTestCaseId: testRailCaseIds[0],\n testCaseName: testCaseName\n .replace(/(TestRail-\\d+|Applause-\\d+)/g, '')\n .replace(/\\s+/g, ' ')\n .trim(),\n };\n}\n\nexport interface ParsedTestCaseName {\n testCaseName: string;\n testRailTestCaseId?: string;\n applauseTestCaseId?: string;\n}\n","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport {\n AdditionalTestCaseParams,\n AdditionalTestCaseResultParams,\n AssetType,\n TestResultStatus,\n} from './dto.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { AutoApiConfig } from './auto-api-config.ts';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\n/**\n * Represents an Applause reporter.\n */\nexport class ApplauseReporter {\n private autoApi: AutoApi;\n private initializer: RunInitializer;\n private logger: winston.Logger;\n private reporter?: Promise;\n private runStarted: boolean = false;\n private runFinished: boolean = false;\n\n /**\n * Creates an instance of ApplauseReporter.\n * @param config - The Applause configuration.\n */\n constructor(config: AutoApiConfig, logger?: winston.Logger) {\n this.logger = logger ?? constructDefaultLogger();\n this.autoApi = new AutoApi(config, this.logger);\n this.initializer = new RunInitializer(this.autoApi, this.logger);\n const runId = process.env['APPLAUSE_RUN_ID'];\n if (runId !== undefined) {\n const r = new RunReporter(\n this.autoApi,\n parseInt(runId),\n undefined,\n this.logger\n );\n this.reporter = new Promise(resolve => resolve(r));\n this.runStarted = true;\n }\n }\n\n /**\n * Starts the Applause runner.\n * @param tests - Optional array of test names to run.\n * @returns A promise that resolves to the test run ID.\n * @throws Error if a run is already started or finished.\n */\n public async runnerStart(tests?: string[]): Promise {\n if (this.reporter !== undefined) {\n this.logger.error(\n 'Cannot start a run - run already started or run already finished'\n );\n throw new Error(\n 'Cannot start a run - run already started or run already finished'\n );\n }\n this.reporter = this.initializer.initializeRun(tests);\n const initializedReporter = await this.reporter;\n this.runStarted = true;\n process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString();\n return initializedReporter.testRunId;\n }\n\n /**\n * Starts a test case.\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Optional additional parameters for the test case.\n * @returns A promise that resolves to the test case ID.\n * @throws Error if a run was never initialized.\n */\n public async startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot start a test case for a run that was never initialized'\n );\n throw new Error(\n 'Cannot start a test case for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.startTestCase(id, testCaseName, params);\n }\n\n /**\n * Submits a test case result.\n * @param id - The ID of the test case.\n * @param status - The status of the test case result.\n * @param params - Optional additional parameters for the test case result.\n * @returns A promise that resolves to the test case result ID.\n * @throws Error if a run was never initialized.\n */\n public async submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n throw new Error(\n 'Cannot submit test case result for a run that was never initialized'\n );\n }\n const reporter = await this.reporter;\n return reporter.submitTestCaseResult(id, status, params);\n }\n\n /**\n * Ends the Applause runner.\n * @returns A promise that resolves when the runner is ended.\n * @throws Error if a run was never initialized.\n */\n public async runnerEnd(): Promise {\n if (this.reporter === undefined) {\n this.logger.error('Cannot end a run that was never initialized');\n throw new Error('Cannot end a run that was never initialized');\n }\n await this.reporter\n .then(reporter => reporter.runnerEnd())\n .then(() => (this.runFinished = true));\n }\n\n /**\n * Attaches an asset to a test case.\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset data as a Buffer.\n * @returns A promise that resolves when the asset is attached.\n * @throws Error if a run was never initialized.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n if (this.reporter === undefined) {\n this.logger.error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n throw new Error(\n 'Cannot attach an asset for a run that was never initialized'\n );\n }\n return await this.reporter.then(reporter =>\n reporter.attachTestCaseAsset(\n id,\n assetName,\n providerSessionGuid,\n assetType,\n asset\n )\n );\n }\n\n /**\n * Checks if the Applause runner is synchronized.\n * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished.\n */\n public isSynchronized(): boolean {\n return (\n (!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0\n );\n }\n}\n\n/**\n * Represents a Run Initializer.\n */\nexport class RunInitializer {\n private logger: winston.Logger;\n constructor(\n private autoApi: AutoApi,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Initializes a test run.\n * @param tests - An optional array of test names to include in the run.\n * @returns A promise that resolves to a RunReporter instance.\n * @throws An error if unable to create the test run.\n */\n async initializeRun(tests?: string[]): Promise {\n const cleanedTests = tests\n ?.map(testName => parseTestCaseName(testName, this.logger))\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests ?? [],\n });\n if (\n testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300\n ) {\n this.logger.error(\n `Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`\n );\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n this.logger.info(`Test Run ${runId} initialized`);\n const heartbeatService = new TestRunHeartbeatService(\n runId,\n this.autoApi,\n this.logger\n );\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService, this.logger);\n }\n}\n\n/**\n * Handles reporting test results to the Applause API.\n */\nexport class RunReporter {\n private uidToResultIdMap: Record> = {};\n private resultSubmissionMap: Record> = {};\n private logger: winston.Logger;\n\n /**\n * Creates a new instance of the Reporter class.\n * @param autoApi - The AutoApi instance.\n * @param testRunId - The ID of the test run.\n * @param heartbeatService - (Optional) The TestRunHeartbeatService instance.\n */\n constructor(\n private autoApi: AutoApi,\n public readonly testRunId: number,\n private heartbeatService?: TestRunHeartbeatService,\n logger?: winston.Logger\n ) {\n this.logger = logger ?? constructDefaultLogger();\n }\n\n /**\n * Starts a test case and returns a promise that resolves to the test result ID.\n *\n * @param id - The ID of the test case.\n * @param testCaseName - The name of the test case.\n * @param params - Additional parameters for the test case.\n * @returns A promise that resolves to the test result ID.\n */\n public startTestCase(\n id: string,\n testCaseName: string,\n params?: AdditionalTestCaseParams\n ): Promise {\n if (!testCaseName) {\n this.logger.error('testCaseName is required');\n throw new Error('testCaseName is required');\n }\n const parsedTestCase = parseTestCaseName(testCaseName, this.logger);\n const submission = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\n\n testRunId: this.testRunId,\n // If the additional params provides either test case id, it will override the parsed value we set above\n ...Object.fromEntries(\n Object.entries(params || {}).filter(([_, v]) => v !== undefined)\n ),\n })\n .then(res => {\n return res.data.testResultId;\n });\n this.uidToResultIdMap[id] = submission;\n return submission;\n }\n\n /**\n * Submits the result of a test case.\n *\n * @param id - The ID of the test case.\n * @param status - The status of the test result.\n * @param params - Additional parameters for the test result.\n * @returns A promise that resolves to the result ID.\n */\n public submitTestCaseResult(\n id: string,\n status: TestResultStatus,\n params?: AdditionalTestCaseResultParams\n ): Promise {\n const submission = this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi\n .submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n })\n .then(() => resultId)\n );\n this.resultSubmissionMap[id] = submission;\n return submission;\n }\n\n /**\n * Attaches a test case asset to a result.\n *\n * @param id - The ID of the test case.\n * @param assetName - The name of the asset.\n * @param providerSessionGuid - The provider session GUID.\n * @param assetType - The type of the asset.\n * @param asset - The asset to attach.\n * @returns A promise that resolves when the asset is attached.\n */\n public async attachTestCaseAsset(\n id: string,\n assetName: string,\n providerSessionGuid: string,\n assetType: AssetType,\n asset: Buffer\n ): Promise {\n await this.uidToResultIdMap[id]?.then(resultId =>\n this.autoApi.uploadAsset(\n resultId,\n asset,\n assetName,\n providerSessionGuid,\n assetType\n )\n );\n }\n\n /**\n * Ends the test runner and performs necessary cleanup tasks.\n * @returns A promise that resolves when the runner has ended.\n */\n public async runnerEnd(): Promise {\n // Wait for all results to be created\n const resultIds =\n (await Promise.all(Object.values(this.uidToResultIdMap))) ?? [];\n\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n\n // Wait the heartbeat to be ended\n void (await this.heartbeatService?.end());\n void (await this.autoApi.endTestRun(this.testRunId));\n\n // Fetch the provider session asset links and save them off to a file\n const resp = await this.autoApi.getProviderSessionLinks(resultIds);\n const jsonArray = resp.data ?? [];\n if (jsonArray.length > 0) {\n this.logger.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(\n pathJoin(outputPath, 'providerUrls.txt'),\n JSON.stringify(jsonArray, null, 1)\n );\n }\n }\n}\n","export interface TestRunAutoResultDto {\n testCycleId: number;\n status: TestRunAutoResultStatus;\n failureReason?: string;\n sessionDetailsJson?: SessionDetails;\n startTime?: Date;\n endTime?: Date;\n}\n\nexport enum TestRunAutoResultStatus {\n PASSED = 'PASSED',\n FAILED = 'FAILED',\n SKIPPED = 'SKIPPED',\n CANCELED = 'CANCELED',\n ERROR = 'ERROR',\n}\n\nexport interface SessionDetails {\n value: {\n deviceName?: string;\n orientation?: string;\n platformName?: string;\n platformVersion?: string;\n browserName?: string;\n browserVersion?: string;\n };\n}\n","import Validator from 'validator';\nconst validator = Validator.default;\n\nexport interface PublicApiConfig {\n readonly publicApiBaseUrl: string;\n readonly apiKey: string;\n readonly productId: number;\n readonly applauseTestCycleId?: number;\n}\n\nexport const DEFAULT_URL = 'https://api.applause.com/';\n\nexport const DEFAULT_PUBLIC_API_PROPERTIES: Partial = {\n publicApiBaseUrl: DEFAULT_URL,\n};\n\nexport function isPublicApiConfigComplete(\n config: Partial\n): boolean {\n return (\n config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined\n );\n}\n\nexport function validatePartialPublicApiConfig(\n config: Partial\n) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n\nexport function validatePublicApiConfig(config: PublicApiConfig) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n if (\n !validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false, // allow localhost\n allow_query_components: false,\n disallow_auth: true,\n allow_fragments: false,\n allow_protocol_relative_urls: false,\n allow_trailing_dot: false,\n require_host: true,\n require_protocol: true,\n })\n ) {\n throw new Error(\n `publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`\n );\n }\n\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n","import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';\nimport { TestRunAutoResultDto } from './dto.ts';\nimport {\n PublicApiConfig,\n validatePublicApiConfig,\n} from './public-api-config.ts';\nimport * as winston from 'winston';\nimport { constructDefaultLogger } from '../shared/logging.ts';\n\nexport class PublicApi {\n private readonly client: AxiosInstance;\n\n private callsInFlight: number;\n private logger: winston.Logger;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n public get getCallsInFlight(): number {\n return this.callsInFlight;\n }\n\n constructor(\n readonly options: PublicApiConfig,\n logger?: winston.Logger\n ) {\n this.callsInFlight = 0;\n this.logger = logger ?? constructDefaultLogger();\n validatePublicApiConfig(options);\n this.client = axios.create({\n baseURL: options.publicApiBaseUrl,\n timeout: 10000,\n headers: {\n 'X-Api-Key': options.apiKey,\n 'Context-Type': 'application/json',\n },\n responseType: 'json',\n });\n this.client.interceptors.response.use(\n function (response: AxiosResponse) {\n return response;\n },\n (error: AxiosError) => {\n // log and rethrow\n const errText =\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.response?.data !== undefined\n ? JSON.stringify(error.response.data)\n : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`;\n this.logger.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n }\n );\n }\n\n async submitResult(\n testCaseId: number,\n info: TestRunAutoResultDto\n ): Promise> {\n this.callsInFlight += 1;\n try {\n return await this.client.post(\n `v2/test-case-results/${testCaseId}/submit`,\n info\n );\n } finally {\n this.callsInFlight -= 1;\n }\n }\n}\n","/**\n * Represents the configuration options for the Applause Reporter.\n */\nimport { existsSync, readFileSync } from 'fs';\nimport path from 'path';\n\nimport {\n AutoApiConfig,\n DEFAULT_AUTO_API_PROPERTIES,\n isAutoApiConfigComplete,\n validateAutoApiConfig,\n} from '../auto-api/auto-api-config.ts';\nimport {\n DEFAULT_PUBLIC_API_PROPERTIES,\n isPublicApiConfigComplete,\n PublicApiConfig,\n validatePublicApiConfig,\n} from '../public-api/public-api-config.ts';\n\nexport type ApplauseConfig = AutoApiConfig & PublicApiConfig;\n\n/**\n * Represents the properties for loading the configuration.\n */\nexport interface ConfigLoadProperties {\n configFile?: string;\n properties?: Partial;\n}\n\n/**\n * Loads the configuration for the Applause Reporter.\n * @param loadOptions - The options for loading the configuration.\n * @returns The loaded Applause configuration.\n * @throws Error if the configuration is not complete or invalid.\n */\nexport function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig {\n // Setup the initial config with any default properties\n let config: Partial = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(\n config,\n loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))\n );\n } else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n\n // We know that the config is complete, so we can cast\n const finalConfig = config as ApplauseConfig;\n\n validateConfig(finalConfig);\n\n return finalConfig;\n}\n\n/**\n * Overrides the configuration with the provided overrides.\n * @param config - The base configuration.\n * @param overrides - The overrides to apply.\n * @returns The overridden configuration.\n */\nexport function overrideConfig(\n config: Partial,\n overrides?: Partial\n): Partial {\n return Object.assign(\n {},\n config,\n Object.fromEntries(\n Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined)\n )\n );\n}\n\n/**\n * Checks if the configuration is complete.\n * @param config - The configuration to check.\n * @returns True if the configuration is complete, false otherwise.\n */\nexport function isComplete(config: Partial): boolean {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\n\n/**\n * Loads the configuration from the specified file.\n * @param configFile - The path to the configuration file.\n * @returns The loaded configuration from the file.\n */\nexport function loadConfigFromFile(\n configFile?: string\n): Partial {\n const configFilePath = configFile ?? `${process.cwd()}/applause.json`;\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileContents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileContents) as Partial;\n}\n\n/**\n * Validates the configuration.\n * @param config - The configuration to validate.\n * @throws Error if the configuration is invalid.\n */\nexport function validateConfig(config: ApplauseConfig) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\n\n/**\n * Validates a partial configuration.\n * @param config - The partial configuration to validate.\n * @throws Error if the partial configuration is invalid.\n */\nexport function validatePartialConfig(config: Partial) {\n if (\n config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)\n ) {\n throw new Error(\n `productId must be a positive integer, was: '${config.productId}'`\n );\n }\n}\n"],"names":["validator","DEFAULT_URL","pathJoin"],"mappings":"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"} \ No newline at end of file diff --git a/src/auto-api/auto-api.ts b/src/auto-api/auto-api.ts index 7a53eaf..4be6be3 100644 --- a/src/auto-api/auto-api.ts +++ b/src/auto-api/auto-api.ts @@ -94,7 +94,7 @@ export class AutoApi { // Copy over the product id productId: this.options.productId, - applauseTestCycleId: this.options.applauseTestCycleId, + itwTestCycleId: this.options.applauseTestCycleId, // Copy over test rail parameters testRailReportingEnabled: this.options.testRailOptions !== undefined,