From 81935d2aa73124d1ac00ef1c882771e64fb68589 Mon Sep 17 00:00:00 2001 From: rconner46 Date: Thu, 25 Jul 2024 12:34:37 -0400 Subject: [PATCH 1/6] Public API Integration --- dist/index.cjs | 217 ++++++++++++++++++------- dist/index.cjs.map | 2 +- dist/index.d.ts | 78 +++++++-- dist/index.min.js | 2 +- dist/index.min.js.map | 2 +- dist/index.mjs | 214 +++++++++++++++++------- dist/index.mjs.map | 2 +- src/auto-api/auto-api-config.ts | 67 ++++++++ src/{ => auto-api}/auto-api.ts | 8 +- src/{ => auto-api}/dto.ts | 0 src/{ => auto-api}/email-helper.ts | 0 src/{ => auto-api}/email/attachment.ts | 0 src/{ => auto-api}/email/inbox.ts | 0 src/{ => auto-api}/heartbeat.ts | 0 src/auto-api/index.ts | 6 + src/{ => auto-api}/reporter.ts | 10 +- src/{ => auto-api}/version.ts | 0 src/{ => config}/config.ts | 64 +++----- src/index.ts | 10 +- src/public-api/dto.ts | 16 ++ src/public-api/index.ts | 2 + src/public-api/public-api-config.ts | 67 ++++++++ src/public-api/public-api.ts | 64 ++++++++ test/auto-api.test.ts | 6 +- test/config.test.ts | 17 +- test/email.test.ts | 10 +- test/heartbeat.test.ts | 10 +- test/public-api.test.ts | 23 +++ test/reporter.test.ts | 28 ++-- test/resources/applause-with-url.json | 2 +- test/resources/bad-url-applause.json | 2 +- 31 files changed, 698 insertions(+), 231 deletions(-) create mode 100644 src/auto-api/auto-api-config.ts rename src/{ => auto-api}/auto-api.ts (96%) rename src/{ => auto-api}/dto.ts (100%) rename src/{ => auto-api}/email-helper.ts (100%) rename src/{ => auto-api}/email/attachment.ts (100%) rename src/{ => auto-api}/email/inbox.ts (100%) rename src/{ => auto-api}/heartbeat.ts (100%) create mode 100644 src/auto-api/index.ts rename src/{ => auto-api}/reporter.ts (95%) rename src/{ => auto-api}/version.ts (100%) rename src/{ => config}/config.ts (63%) create mode 100644 src/public-api/dto.ts create mode 100644 src/public-api/index.ts create mode 100644 src/public-api/public-api-config.ts create mode 100644 src/public-api/public-api.ts create mode 100644 test/public-api.test.ts diff --git a/dist/index.cjs b/dist/index.cjs index edba57b..eea377a 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -1,62 +1,28 @@ 'use strict'; var axios = require('axios'); -var fs = require('fs'); -var path = require('path'); var Validator = require('validator'); var mailparser = require('mailparser'); +var fs = require('fs'); +var path = require('path'); const API_VERSION = '1.0.0'; -const validator = Validator.default; -const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/'; -// Loads the configuration -function loadConfig(loadOptions) { - // Setup the initial config with any default properties - let config = { - baseUrl: DEFAULT_URL, - }; - // Load properties from the provided config file - if (loadOptions !== undefined && loadOptions.configFile !== undefined) { - config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))); - } - else { - // Override from the default config file - config = overrideConfig(config, loadConfigFromFile()); - } - // Then load in the file override properties - if (loadOptions !== undefined && loadOptions.properties !== undefined) { - config = overrideConfig(config, loadOptions.properties); - } - if (!isComplete(config)) { - throw new Error('Config is not complete'); - } - // We know that the config is complete, so we can cast - const finalConfig = config; - validateConfig(finalConfig); - return finalConfig; -} -function overrideConfig(config, overrides) { - return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined))); -} -function isComplete(config) { - return (config.baseUrl !== undefined && +const validator$1 = Validator.default; +const DEFAULT_URL$1 = 'https://prod-auto-api.cloud.applause.com/'; +const DEFAULT_AUTO_API_PROPERTIES = { + autoApiBaseUrl: DEFAULT_URL$1, +}; +function isAutoApiConfigComplete(config) { + return (config.autoApiBaseUrl !== undefined && config.apiKey !== undefined && config.productId !== undefined); } -function loadConfigFromFile(configFile) { - const configFilePath = configFile || process.cwd() + '/applause.json'; - if (!fs.existsSync(configFilePath)) { - return {}; - } - const fileCotents = fs.readFileSync(configFilePath, 'utf8'); - return JSON.parse(fileCotents); -} -function validateConfig(config) { +function validateAutoApiConfig(config) { if (!Number.isInteger(config.productId) || config.productId <= 0) { throw new Error(`productId must be a positive integer, was: '${config.productId}'`); } - if (!validator.isURL(config.baseUrl, { + if (!validator$1.isURL(config.autoApiBaseUrl, { protocols: ['http', 'https'], require_tld: false, allow_query_components: false, @@ -67,18 +33,12 @@ function validateConfig(config) { require_host: true, require_protocol: true, })) { - throw new Error(`baseUrl is not valid HTTP/HTTPS URL, was: ${config.baseUrl}`); + throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`); } - if (validator.isEmpty(config.apiKey)) { + if (validator$1.isEmpty(config.apiKey)) { throw new Error('apiKey is an empty string!'); } } -function validatePartialConfig(config) { - if (config.productId !== undefined && - (!Number.isInteger(config.productId) || config.productId <= 0)) { - throw new Error(`productId must be a positive integer, was: '${config.productId}'`); - } -} class AutoApi { options; @@ -93,9 +53,9 @@ class AutoApi { constructor(options) { this.options = options; this.callsInFlight = 0; - validateConfig(options); + validateAutoApiConfig(options); this.client = axios.create({ - baseURL: options.baseUrl, + baseURL: options.autoApiBaseUrl, timeout: 10000, headers: { 'X-Api-Key': options.apiKey, @@ -446,18 +406,163 @@ function parseTestCaseName(testCaseName) { }; } +exports.TestRunAutoResultStatus = void 0; +(function (TestRunAutoResultStatus) { + TestRunAutoResultStatus["PASSED"] = "PASSED"; + TestRunAutoResultStatus["FAILED"] = "FAILED"; + TestRunAutoResultStatus["SKIPPED"] = "SKIPPED"; + TestRunAutoResultStatus["CANCELED"] = "CANCELED"; + TestRunAutoResultStatus["ERROR"] = "ERROR"; +})(exports.TestRunAutoResultStatus || (exports.TestRunAutoResultStatus = {})); + +const validator = Validator.default; +const DEFAULT_URL = 'https://api.applause.com/'; +const DEFAULT_PUBLIC_API_PROPERTIES = { + publicApiBaseUrl: DEFAULT_URL, +}; +function isPublicApiConfigComplete(config) { + return (config.publicApiBaseUrl !== undefined && + config.apiKey !== undefined && + config.productId !== undefined); +} +function validatePublicApiConfig(config) { + if (!Number.isInteger(config.productId) || config.productId <= 0) { + throw new Error(`productId must be a positive integer, was: '${config.productId}'`); + } + if (!validator.isURL(config.publicApiBaseUrl, { + protocols: ['http', 'https'], + require_tld: false, + allow_query_components: false, + disallow_auth: true, + allow_fragments: false, + allow_protocol_relative_urls: false, + allow_trailing_dot: false, + require_host: true, + require_protocol: true, + })) { + throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`); + } + if (validator.isEmpty(config.apiKey)) { + throw new Error('apiKey is an empty string!'); + } +} + +class PublicApi { + options; + client; + callsInFlight; + /** + * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + */ + get getCallsInFlight() { + return this.callsInFlight; + } + constructor(options) { + this.options = options; + this.callsInFlight = 0; + validatePublicApiConfig(options); + this.client = axios.create({ + baseURL: options.publicApiBaseUrl, + timeout: 10000, + headers: { + 'X-Api-Key': options.apiKey, + 'Context-Type': 'application/json', + }, + responseType: 'json', + }); + this.client.interceptors.response.use(function (response) { + return response; + }, function (error) { + // log and rethrow + const errText = + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + error.data !== undefined + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + error.data + : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + `error-code [${error.response.status}] with error [${error.response.statusText}]`; + console.error(`Public-Api returned ${errText}`); + return Promise.reject(error); + }); + } + async submitResult(testCaseId, info) { + this.callsInFlight += 1; + try { + return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info); + } + finally { + this.callsInFlight -= 1; + } + } +} + +// Loads the configuration +function loadConfig(loadOptions) { + // Setup the initial config with any default properties + let config = { + ...DEFAULT_PUBLIC_API_PROPERTIES, + ...DEFAULT_AUTO_API_PROPERTIES, + }; + // Load properties from the provided config file + if (loadOptions !== undefined && loadOptions.configFile !== undefined) { + config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))); + } + else { + // Override from the default config file + config = overrideConfig(config, loadConfigFromFile()); + } + // Then load in the file override properties + if (loadOptions !== undefined && loadOptions.properties !== undefined) { + config = overrideConfig(config, loadOptions.properties); + } + if (!isComplete(config)) { + throw new Error('Config is not complete'); + } + // We know that the config is complete, so we can cast + const finalConfig = config; + validateConfig(finalConfig); + return finalConfig; +} +function overrideConfig(config, overrides) { + return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined))); +} +function isComplete(config) { + return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config); +} +function loadConfigFromFile(configFile) { + const configFilePath = configFile || process.cwd() + '/applause.json'; + if (!fs.existsSync(configFilePath)) { + return {}; + } + const fileCotents = fs.readFileSync(configFilePath, 'utf8'); + return JSON.parse(fileCotents); +} +function validateConfig(config) { + validateAutoApiConfig(config); + validatePublicApiConfig(config); +} +function validatePartialConfig(config) { + if (config.productId !== undefined && + (!Number.isInteger(config.productId) || config.productId <= 0)) { + throw new Error(`productId must be a positive integer, was: '${config.productId}'`); + } +} + +exports.APPLAUSE_CASE_ID_PREFIX = APPLAUSE_CASE_ID_PREFIX; exports.ApplauseReporter = ApplauseReporter; exports.AutoApi = AutoApi; -exports.DEFAULT_URL = DEFAULT_URL; exports.EmailHelper = EmailHelper; exports.Inbox = Inbox; +exports.PublicApi = PublicApi; exports.RunInitializer = RunInitializer; exports.RunReporter = RunReporter; +exports.TEST_RAIL_CASE_ID_PREFIX = TEST_RAIL_CASE_ID_PREFIX; exports.TestRunHeartbeatService = TestRunHeartbeatService; exports.isComplete = isComplete; exports.loadConfig = loadConfig; exports.loadConfigFromFile = loadConfigFromFile; exports.overrideConfig = overrideConfig; +exports.parseTestCaseName = parseTestCaseName; exports.validateConfig = validateConfig; exports.validatePartialConfig = validatePartialConfig; //# sourceMappingURL=index.cjs.map diff --git a/dist/index.cjs.map b/dist/index.cjs.map index 16ad4fb..c71101e 100644 --- a/dist/index.cjs.map +++ b/dist/index.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.cjs","sources":["../src/version.ts","../src/config.ts","../src/auto-api.ts","../src/dto.ts","../src/email/inbox.ts","../src/email-helper.ts","../src/heartbeat.ts","../src/reporter.ts"],"sourcesContent":["export const API_VERSION = '1.0.0';\n//# sourceMappingURL=version.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n baseUrl: DEFAULT_URL,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return (config.baseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.baseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`baseUrl is not valid HTTP/HTTPS URL, was: ${config.baseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateConfig } from './config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\n validateConfig(options);\n this.client = axios.create({\n baseURL: options.baseUrl,\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nconst TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nconst APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nfunction parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map"],"names":["existsSync","readFileSync","TestResultStatus","simpleParser","writeFileSync","pathJoin"],"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/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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nexport const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","TestResultStatus","simpleParser","writeFileSync","pathJoin","TestRunAutoResultStatus","existsSync","readFileSync"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index aed5c38..7b3a652 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -96,34 +96,23 @@ interface EmailFetchRequest { emailAddress: string; } -interface ApplauseConfig { - readonly baseUrl: string; +interface AutoApiConfig { + readonly autoApiBaseUrl: string; readonly apiKey: string; readonly productId: number; readonly testRailOptions?: TestRailOptions; readonly applauseTestCycleId?: number; } -declare const DEFAULT_URL = "https://prod-auto-api.cloud.applause.com/"; -interface ConfigLoadProperties { - configFile?: string; - properties?: Partial; -} -declare function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig; -declare function overrideConfig(config: Partial, overrides?: Partial): Partial; -declare function isComplete(config: Partial): boolean; -declare function loadConfigFromFile(configFile?: string): Partial; -declare function validateConfig(config: ApplauseConfig): void; -declare function validatePartialConfig(config: Partial): void; declare class AutoApi { - readonly options: ApplauseConfig; + readonly options: AutoApiConfig; private readonly client; private callsInFlight; /** * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished */ get getCallsInFlight(): number; - constructor(options: ApplauseConfig); + constructor(options: AutoApiConfig); startTestRun(info: TestRunCreateDto): Promise>; endTestRun(testRunId: number): Promise>; startTestCase(params: CreateTestCaseResultDto): Promise>; @@ -171,7 +160,7 @@ declare class ApplauseReporter { private reporter?; private runStarted; private runFinished; - constructor(config: ApplauseConfig); + constructor(config: AutoApiConfig); runnerStart(tests?: string[]): void; startTestCase(id: string, testCaseName: string, params?: AdditionalTestCaseParams): void; submitTestCaseResult(id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams): void; @@ -194,5 +183,60 @@ declare class RunReporter { submitTestCaseResult(id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams): void; runnerEnd(): Promise; } +declare const TEST_RAIL_CASE_ID_PREFIX: string; +declare const APPLAUSE_CASE_ID_PREFIX: string; +declare function parseTestCaseName(testCaseName: string): ParsedTestCaseName; +interface ParsedTestCaseName { + testCaseName: string; + testRailTestCaseId?: string; + applauseTestCaseId?: string; +} + +interface TestRunAutoResultDto { + testCycleId: number; + status: TestRunAutoResultStatus; + failureReason?: string; + sessionDetailsJson?: object; + startTime?: Date; + endTime?: Date; +} +declare enum TestRunAutoResultStatus { + PASSED = "PASSED", + FAILED = "FAILED", + SKIPPED = "SKIPPED", + CANCELED = "CANCELED", + ERROR = "ERROR" +} + +interface PublicApiConfig { + readonly publicApiBaseUrl: string; + readonly apiKey: string; + readonly productId: number; + readonly applauseTestCycleId?: number; +} + +declare class PublicApi { + readonly options: PublicApiConfig; + private readonly client; + private callsInFlight; + /** + * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + */ + get getCallsInFlight(): number; + constructor(options: PublicApiConfig); + submitResult(testCaseId: number, info: TestRunAutoResultDto): Promise>; +} + +type ApplauseConfig = AutoApiConfig & PublicApiConfig; +interface ConfigLoadProperties { + configFile?: string; + properties?: Partial; +} +declare function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig; +declare function overrideConfig(config: Partial, overrides?: Partial): Partial; +declare function isComplete(config: Partial): boolean; +declare function loadConfigFromFile(configFile?: string): Partial; +declare function validateConfig(config: ApplauseConfig): void; +declare function validatePartialConfig(config: Partial): void; -export { type AdditionalTestCaseParams, type AdditionalTestCaseResultParams, type ApplauseConfig, ApplauseReporter, type Attachment, AutoApi, type ClientConfig, type ConfigLoadProperties, type CreateTestCaseResultDto, type CreateTestCaseResultResponseDto, DEFAULT_URL, type EmailAddressResponse, type EmailFetchRequest, EmailHelper, Inbox, RunInitializer, RunReporter, type SubmitTestCaseResultDto, type TestRailOptions, type TestResultProviderInfo, TestResultStatus, type TestRunCreateDto, type TestRunCreateResponseDto, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, validateConfig, validatePartialConfig }; +export { APPLAUSE_CASE_ID_PREFIX, type AdditionalTestCaseParams, type AdditionalTestCaseResultParams, type ApplauseConfig, ApplauseReporter, type Attachment, AutoApi, type ClientConfig, type ConfigLoadProperties, type CreateTestCaseResultDto, type CreateTestCaseResultResponseDto, type EmailAddressResponse, type EmailFetchRequest, EmailHelper, Inbox, PublicApi, RunInitializer, RunReporter, type SubmitTestCaseResultDto, TEST_RAIL_CASE_ID_PREFIX, type TestRailOptions, type TestResultProviderInfo, TestResultStatus, type TestRunAutoResultDto, TestRunAutoResultStatus, type TestRunCreateDto, type TestRunCreateResponseDto, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; diff --git a/dist/index.min.js b/dist/index.min.js index be516db..eaeff67 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("fs"),require("path"),require("validator"),require("mailparser")):"function"==typeof define&&define.amd?define(["exports","axios","fs","path","validator","mailparser"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.fs,t.path,t.Validator,t.mailparser)}(this,(function(t,e,s,i,a,r){"use strict";const n=a.default,o="https://prod-auto-api.cloud.applause.com/";function l(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e||{}).filter((([t,e])=>void 0!==e))))}function u(t){return void 0!==t.baseUrl&&void 0!==t.apiKey&&void 0!==t.productId}function d(t){const e=t||process.cwd()+"/applause.json";if(!s.existsSync(e))return{};const i=s.readFileSync(e,"utf8");return JSON.parse(i)}function p(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!n.isURL(t.baseUrl,{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(`baseUrl is not valid HTTP/HTTPS URL, was: ${t.baseUrl}`);if(n.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}class c{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,p(t),this.client=e.create({baseURL:t.baseUrl,timeout:1e4,headers:{"X-Api-Key":t.apiKey,"Context-Type":"application/json"},responseType:"json"}),this.client.interceptors.response.use((function(t){return t}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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.0.0",productId:this.options.productId,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}}}var h;t.TestResultStatus=void 0,(h=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",h.IN_PROGRESS="IN_PROGRESS",h.PASSED="PASSED",h.FAILED="FAILED",h.SKIPPED="SKIPPED",h.CANCELED="CANCELED",h.ERROR="ERROR";class R{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await r.simpleParser(t.data)}}class f{testRunId;autoApi;enabled=!1;nextHeartbeat;constructor(t,e){this.testRunId=t,this.autoApi=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(){console.log("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),console.log("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,console.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,console.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}class I{autoApi;constructor(t){this.autoApi=t}async initializeRun(t){const e=t?.map(w).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e||[]});if(s.status<200||s.status>300)throw new Error("Unable to create test run");const i=s.data.runId;console.log("Test Run %d initialized",i);const a=new f(i,this.autoApi);return await a.start(),new g(this.autoApi,i,a)}}class g{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};constructor(t,e,s){this.autoApi=t,this.testRunId=e,this.heartbeatService=s}startTestCase(t,e,s){const i=w(e);this.uidToResultIdMap[t]=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))}submitTestCaseResult(t,e,s){this.resultSubmissionMap[t]=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s})))}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){console.info(JSON.stringify(e));const t=".";s.writeFileSync(i.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}const m="TestRail-",b="Applause-";function w(t){const e=t.split(" ");let s,i;return e.forEach((t=>{t?.startsWith(m)?(void 0!==s&&console.warn("Multiple TestRail case ids detected in testCase name"),s=t.substring(m.length)):t?.startsWith(b)&&(void 0!==i&&console.warn("Multiple Applause case ids detected in testCase name"),i=t.substring(b.length))})),{applauseTestCaseId:i,testRailTestCaseId:s,testCaseName:e.filter((t=>t!==`${m}${s||""}`)).filter((t=>t!==`${b}${i||""}`)).join(" ").trim()}}t.ApplauseReporter=class{autoApi;initializer;reporter;runStarted=!1;runFinished=!1;constructor(t){this.autoApi=new c(t),this.initializer=new I(this.autoApi)}runnerStart(t){this.reporter=this.initializer.initializeRun(t),this.reporter.then((()=>{this.runStarted=!0}))}startTestCase(t,e,s){if(void 0===this.reporter)throw new Error("Cannot start a test case for a run that was never initialized");this.reporter.then((i=>i.startTestCase(t,e,s)))}submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw new Error("Cannot submit test case result for a run that was never initialized");this.reporter.then((i=>i.submitTestCaseResult(t,e,s)))}async runnerEnd(){if(void 0===this.reporter)throw new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.AutoApi=c,t.DEFAULT_URL=o,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new R(e,this.autoApi)}},t.Inbox=R,t.RunInitializer=I,t.RunReporter=g,t.TestRunHeartbeatService=f,t.isComplete=u,t.loadConfig=function(t){let e={baseUrl:o};if(e=void 0!==t&&void 0!==t.configFile?l(e,d(i.join(process.cwd(),t.configFile))):l(e,d()),void 0!==t&&void 0!==t.properties&&(e=l(e,t.properties)),!u(e))throw new Error("Config is not complete");const s=e;return p(s),s},t.loadConfigFromFile=d,t.overrideConfig=l,t.validateConfig=p,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("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,a,r){"use strict";const n=s.default,o={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function l(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!n.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(n.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}class u{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,l(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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.0.0",productId:this.options.productId,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}}}var p;t.TestResultStatus=void 0,(p=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",p.IN_PROGRESS="IN_PROGRESS",p.PASSED="PASSED",p.FAILED="FAILED",p.SKIPPED="SKIPPED",p.CANCELED="CANCELED",p.ERROR="ERROR";class d{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await i.simpleParser(t.data)}}class c{testRunId;autoApi;enabled=!1;nextHeartbeat;constructor(t,e){this.testRunId=t,this.autoApi=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(){console.log("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),console.log("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,console.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,console.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}class h{autoApi;constructor(t){this.autoApi=t}async initializeRun(t){const e=t?.map(g).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e||[]});if(s.status<200||s.status>300)throw new Error("Unable to create test run");const i=s.data.runId;console.log("Test Run %d initialized",i);const a=new c(i,this.autoApi);return await a.start(),new I(this.autoApi,i,a)}}class I{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};constructor(t,e,s){this.autoApi=t,this.testRunId=e,this.heartbeatService=s}startTestCase(t,e,s){const i=g(e);this.uidToResultIdMap[t]=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))}submitTestCaseResult(t,e,s){this.resultSubmissionMap[t]=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s})))}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){console.info(JSON.stringify(e));const t=".";a.writeFileSync(r.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}const R="TestRail-",f="Applause-";function g(t){const e=t.split(" ");let s,i;return e.forEach((t=>{t?.startsWith(R)?(void 0!==s&&console.warn("Multiple TestRail case ids detected in testCase name"),s=t.substring(R.length)):t?.startsWith(f)&&(void 0!==i&&console.warn("Multiple Applause case ids detected in testCase name"),i=t.substring(f.length))})),{applauseTestCaseId:i,testRailTestCaseId:s,testCaseName:e.filter((t=>t!==`${R}${s||""}`)).filter((t=>t!==`${f}${i||""}`)).join(" ").trim()}}var w;t.TestRunAutoResultStatus=void 0,(w=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",w.FAILED="FAILED",w.SKIPPED="SKIPPED",w.CANCELED="CANCELED",w.ERROR="ERROR";const A=s.default,m={publicApiBaseUrl:"https://api.applause.com/"};function b(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!A.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(A.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function y(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e||{}).filter((([t,e])=>void 0!==e))))}function E(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 v(t){const e=t||process.cwd()+"/applause.json";if(!a.existsSync(e))return{};const s=a.readFileSync(e,"utf8");return JSON.parse(s)}function T(t){l(t),b(t)}t.APPLAUSE_CASE_ID_PREFIX=f,t.ApplauseReporter=class{autoApi;initializer;reporter;runStarted=!1;runFinished=!1;constructor(t){this.autoApi=new u(t),this.initializer=new h(this.autoApi)}runnerStart(t){this.reporter=this.initializer.initializeRun(t),this.reporter.then((()=>{this.runStarted=!0}))}startTestCase(t,e,s){if(void 0===this.reporter)throw new Error("Cannot start a test case for a run that was never initialized");this.reporter.then((i=>i.startTestCase(t,e,s)))}submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw new Error("Cannot submit test case result for a run that was never initialized");this.reporter.then((i=>i.submitTestCaseResult(t,e,s)))}async runnerEnd(){if(void 0===this.reporter)throw new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.AutoApi=u,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new d(e,this.autoApi)}},t.Inbox=d,t.PublicApi=class{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,b(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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=h,t.RunReporter=I,t.TEST_RAIL_CASE_ID_PREFIX=R,t.TestRunHeartbeatService=c,t.isComplete=E,t.loadConfig=function(t){let e={...m,...o};if(e=void 0!==t&&void 0!==t.configFile?y(e,v(r.join(process.cwd(),t.configFile))):y(e,v()),void 0!==t&&void 0!==t.properties&&(e=y(e,t.properties)),!E(e))throw new Error("Config is not complete");const s=e;return T(s),s},t.loadConfigFromFile=v,t.overrideConfig=y,t.parseTestCaseName=g,t.validateConfig=T,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 c4b087b..5bd3daa 100644 --- a/dist/index.min.js.map +++ b/dist/index.min.js.map @@ -1 +1 @@ -{"version":3,"file":"index.min.js","sources":["../src/version.ts","../src/config.ts","../src/auto-api.ts","../src/dto.ts","../src/email/inbox.ts","../src/heartbeat.ts","../src/reporter.ts","../src/email-helper.ts"],"sourcesContent":["export const API_VERSION = '1.0.0';\n//# sourceMappingURL=version.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n baseUrl: DEFAULT_URL,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return (config.baseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.baseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`baseUrl is not valid HTTP/HTTPS URL, was: ${config.baseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateConfig } from './config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\n validateConfig(options);\n this.client = axios.create({\n baseURL: options.baseUrl,\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nconst TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nconst APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nfunction parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map"],"names":["validator","Validator","default","DEFAULT_URL","overrideConfig","config","overrides","Object","assign","fromEntries","entries","filter","_","v","undefined","isComplete","baseUrl","apiKey","productId","loadConfigFromFile","configFile","configFilePath","process","cwd","existsSync","fileCotents","readFileSync","JSON","parse","validateConfig","Number","isInteger","Error","isURL","protocols","require_tld","allow_query_components","disallow_auth","allow_fragments","allow_protocol_relative_urls","allow_trailing_dot","require_host","require_protocol","isEmpty","AutoApi","options","client","callsInFlight","getCallsInFlight","this","constructor","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","data","status","statusText","console","Promise","reject","startTestRun","info","post","sdkVersion","testRailReportingEnabled","testRailOptions","addAllTestsToPlan","testRailProjectId","projectId","testRailSuiteId","suiteId","testRailPlanName","planName","testRailRunName","runName","overrideTestRailRunNameUniqueness","overrideTestRailRunUniqueness","endTestRun","testRunId","delete","startTestCase","params","submitTestCaseResult","getProviderSessionLinks","resultIds","validIds","id","sendSdkHeartbeat","getEmailAddress","emailPrefix","get","getEmailContent","request","TestResultStatus","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","log","debug","RunInitializer","initializeRun","tests","cleanedTests","map","parseTestCaseName","parsed","testCaseName","trim","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","testCaseId","testRailTestCaseId","itwTestCaseId","applauseTestCaseId","testResultId","resultId","runnerEnd","all","values","jsonArray","length","stringify","outputPath","writeFileSync","pathJoin","join","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","tokens","split","forEach","token","startsWith","warn","substring","initializer","reporter","runStarted","runFinished","runnerStart","isSynchronized","getInbox","generatedAddress","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/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/heartbeat.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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nexport const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map"],"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","AutoApi","options","client","callsInFlight","getCallsInFlight","this","constructor","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","status","statusText","console","Promise","reject","startTestRun","info","post","sdkVersion","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","TestResultStatus","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","log","debug","RunInitializer","initializeRun","tests","cleanedTests","map","parseTestCaseName","parsed","testCaseName","trim","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","testCaseId","testRailTestCaseId","itwTestCaseId","applauseTestCaseId","Object","fromEntries","entries","_","v","testResultId","resultId","runnerEnd","all","values","jsonArray","length","JSON","stringify","outputPath","writeFileSync","pathJoin","join","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","tokens","split","forEach","token","startsWith","warn","substring","TestRunAutoResultStatus","DEFAULT_PUBLIC_API_PROPERTIES","publicApiBaseUrl","validatePublicApiConfig","overrideConfig","overrides","assign","isComplete","isAutoApiConfigComplete","isPublicApiConfigComplete","loadConfigFromFile","configFile","configFilePath","process","cwd","existsSync","fileCotents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","runnerStart","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 2149ac9..38da9b9 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -1,60 +1,26 @@ import axios from 'axios'; -import { existsSync, readFileSync, writeFileSync } from 'fs'; -import path, { join } from 'path'; import Validator from 'validator'; import { simpleParser } from 'mailparser'; +import { writeFileSync, existsSync, readFileSync } from 'fs'; +import path, { join } from 'path'; const API_VERSION = '1.0.0'; -const validator = Validator.default; -const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/'; -// Loads the configuration -function loadConfig(loadOptions) { - // Setup the initial config with any default properties - let config = { - baseUrl: DEFAULT_URL, - }; - // Load properties from the provided config file - if (loadOptions !== undefined && loadOptions.configFile !== undefined) { - config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))); - } - else { - // Override from the default config file - config = overrideConfig(config, loadConfigFromFile()); - } - // Then load in the file override properties - if (loadOptions !== undefined && loadOptions.properties !== undefined) { - config = overrideConfig(config, loadOptions.properties); - } - if (!isComplete(config)) { - throw new Error('Config is not complete'); - } - // We know that the config is complete, so we can cast - const finalConfig = config; - validateConfig(finalConfig); - return finalConfig; -} -function overrideConfig(config, overrides) { - return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined))); -} -function isComplete(config) { - return (config.baseUrl !== undefined && +const validator$1 = Validator.default; +const DEFAULT_URL$1 = 'https://prod-auto-api.cloud.applause.com/'; +const DEFAULT_AUTO_API_PROPERTIES = { + autoApiBaseUrl: DEFAULT_URL$1, +}; +function isAutoApiConfigComplete(config) { + return (config.autoApiBaseUrl !== undefined && config.apiKey !== undefined && config.productId !== undefined); } -function loadConfigFromFile(configFile) { - const configFilePath = configFile || process.cwd() + '/applause.json'; - if (!existsSync(configFilePath)) { - return {}; - } - const fileCotents = readFileSync(configFilePath, 'utf8'); - return JSON.parse(fileCotents); -} -function validateConfig(config) { +function validateAutoApiConfig(config) { if (!Number.isInteger(config.productId) || config.productId <= 0) { throw new Error(`productId must be a positive integer, was: '${config.productId}'`); } - if (!validator.isURL(config.baseUrl, { + if (!validator$1.isURL(config.autoApiBaseUrl, { protocols: ['http', 'https'], require_tld: false, allow_query_components: false, @@ -65,18 +31,12 @@ function validateConfig(config) { require_host: true, require_protocol: true, })) { - throw new Error(`baseUrl is not valid HTTP/HTTPS URL, was: ${config.baseUrl}`); + throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`); } - if (validator.isEmpty(config.apiKey)) { + if (validator$1.isEmpty(config.apiKey)) { throw new Error('apiKey is an empty string!'); } } -function validatePartialConfig(config) { - if (config.productId !== undefined && - (!Number.isInteger(config.productId) || config.productId <= 0)) { - throw new Error(`productId must be a positive integer, was: '${config.productId}'`); - } -} class AutoApi { options; @@ -91,9 +51,9 @@ class AutoApi { constructor(options) { this.options = options; this.callsInFlight = 0; - validateConfig(options); + validateAutoApiConfig(options); this.client = axios.create({ - baseURL: options.baseUrl, + baseURL: options.autoApiBaseUrl, timeout: 10000, headers: { 'X-Api-Key': options.apiKey, @@ -444,5 +404,147 @@ function parseTestCaseName(testCaseName) { }; } -export { ApplauseReporter, AutoApi, DEFAULT_URL, EmailHelper, Inbox, RunInitializer, RunReporter, TestResultStatus, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, validateConfig, validatePartialConfig }; +var TestRunAutoResultStatus; +(function (TestRunAutoResultStatus) { + TestRunAutoResultStatus["PASSED"] = "PASSED"; + TestRunAutoResultStatus["FAILED"] = "FAILED"; + TestRunAutoResultStatus["SKIPPED"] = "SKIPPED"; + TestRunAutoResultStatus["CANCELED"] = "CANCELED"; + TestRunAutoResultStatus["ERROR"] = "ERROR"; +})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {})); + +const validator = Validator.default; +const DEFAULT_URL = 'https://api.applause.com/'; +const DEFAULT_PUBLIC_API_PROPERTIES = { + publicApiBaseUrl: DEFAULT_URL, +}; +function isPublicApiConfigComplete(config) { + return (config.publicApiBaseUrl !== undefined && + config.apiKey !== undefined && + config.productId !== undefined); +} +function validatePublicApiConfig(config) { + if (!Number.isInteger(config.productId) || config.productId <= 0) { + throw new Error(`productId must be a positive integer, was: '${config.productId}'`); + } + if (!validator.isURL(config.publicApiBaseUrl, { + protocols: ['http', 'https'], + require_tld: false, + allow_query_components: false, + disallow_auth: true, + allow_fragments: false, + allow_protocol_relative_urls: false, + allow_trailing_dot: false, + require_host: true, + require_protocol: true, + })) { + throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`); + } + if (validator.isEmpty(config.apiKey)) { + throw new Error('apiKey is an empty string!'); + } +} + +class PublicApi { + options; + client; + callsInFlight; + /** + * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + */ + get getCallsInFlight() { + return this.callsInFlight; + } + constructor(options) { + this.options = options; + this.callsInFlight = 0; + validatePublicApiConfig(options); + this.client = axios.create({ + baseURL: options.publicApiBaseUrl, + timeout: 10000, + headers: { + 'X-Api-Key': options.apiKey, + 'Context-Type': 'application/json', + }, + responseType: 'json', + }); + this.client.interceptors.response.use(function (response) { + return response; + }, function (error) { + // log and rethrow + const errText = + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + error.data !== undefined + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + error.data + : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + `error-code [${error.response.status}] with error [${error.response.statusText}]`; + console.error(`Public-Api returned ${errText}`); + return Promise.reject(error); + }); + } + async submitResult(testCaseId, info) { + this.callsInFlight += 1; + try { + return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info); + } + finally { + this.callsInFlight -= 1; + } + } +} + +// Loads the configuration +function loadConfig(loadOptions) { + // Setup the initial config with any default properties + let config = { + ...DEFAULT_PUBLIC_API_PROPERTIES, + ...DEFAULT_AUTO_API_PROPERTIES, + }; + // Load properties from the provided config file + if (loadOptions !== undefined && loadOptions.configFile !== undefined) { + config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile))); + } + else { + // Override from the default config file + config = overrideConfig(config, loadConfigFromFile()); + } + // Then load in the file override properties + if (loadOptions !== undefined && loadOptions.properties !== undefined) { + config = overrideConfig(config, loadOptions.properties); + } + if (!isComplete(config)) { + throw new Error('Config is not complete'); + } + // We know that the config is complete, so we can cast + const finalConfig = config; + validateConfig(finalConfig); + return finalConfig; +} +function overrideConfig(config, overrides) { + return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined))); +} +function isComplete(config) { + return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config); +} +function loadConfigFromFile(configFile) { + const configFilePath = configFile || process.cwd() + '/applause.json'; + if (!existsSync(configFilePath)) { + return {}; + } + const fileCotents = readFileSync(configFilePath, 'utf8'); + return JSON.parse(fileCotents); +} +function validateConfig(config) { + validateAutoApiConfig(config); + validatePublicApiConfig(config); +} +function validatePartialConfig(config) { + if (config.productId !== undefined && + (!Number.isInteger(config.productId) || config.productId <= 0)) { + throw new Error(`productId must be a positive integer, was: '${config.productId}'`); + } +} + +export { APPLAUSE_CASE_ID_PREFIX, ApplauseReporter, AutoApi, EmailHelper, Inbox, PublicApi, RunInitializer, RunReporter, TEST_RAIL_CASE_ID_PREFIX, TestResultStatus, TestRunAutoResultStatus, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; //# sourceMappingURL=index.mjs.map diff --git a/dist/index.mjs.map b/dist/index.mjs.map index 0dd5046..2c0f91d 100644 --- a/dist/index.mjs.map +++ b/dist/index.mjs.map @@ -1 +1 @@ -{"version":3,"file":"index.mjs","sources":["../src/version.ts","../src/config.ts","../src/auto-api.ts","../src/dto.ts","../src/email/inbox.ts","../src/email-helper.ts","../src/heartbeat.ts","../src/reporter.ts"],"sourcesContent":["export const API_VERSION = '1.0.0';\n//# sourceMappingURL=version.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n baseUrl: DEFAULT_URL,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return (config.baseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.baseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`baseUrl is not valid HTTP/HTTPS URL, was: ${config.baseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateConfig } from './config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\n validateConfig(options);\n this.client = axios.create({\n baseURL: options.baseUrl,\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nconst TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nconst APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nfunction parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map"],"names":["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/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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nexport const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","pathJoin"],"mappings":"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"} \ No newline at end of file diff --git a/src/auto-api/auto-api-config.ts b/src/auto-api/auto-api-config.ts new file mode 100644 index 0000000..75bb37d --- /dev/null +++ b/src/auto-api/auto-api-config.ts @@ -0,0 +1,67 @@ +import { TestRailOptions } from './dto.ts'; +import Validator from 'validator'; +const validator = Validator.default; + +export interface AutoApiConfig { + readonly autoApiBaseUrl: string; + readonly apiKey: string; + readonly productId: number; + readonly testRailOptions?: TestRailOptions; + readonly applauseTestCycleId?: number; +} + +export const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/'; + +export const DEFAULT_AUTO_API_PROPERTIES: Partial = { + autoApiBaseUrl: DEFAULT_URL, +}; + +export function isAutoApiConfigComplete( + config: Partial +): boolean { + return ( + config.autoApiBaseUrl !== undefined && + config.apiKey !== undefined && + config.productId !== undefined + ); +} + +export function validatePartialAutoApiConfig(config: Partial) { + if ( + config.productId !== undefined && + (!Number.isInteger(config.productId) || config.productId <= 0) + ) { + throw new Error( + `productId must be a positive integer, was: '${config.productId}'` + ); + } +} + +export function validateAutoApiConfig(config: AutoApiConfig) { + if (!Number.isInteger(config.productId) || config.productId <= 0) { + throw new Error( + `productId must be a positive integer, was: '${config.productId}'` + ); + } + if ( + !validator.isURL(config.autoApiBaseUrl, { + protocols: ['http', 'https'], + require_tld: false, // allow localhost + allow_query_components: false, + disallow_auth: true, + allow_fragments: false, + allow_protocol_relative_urls: false, + allow_trailing_dot: false, + require_host: true, + require_protocol: true, + }) + ) { + throw new Error( + `autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}` + ); + } + + if (validator.isEmpty(config.apiKey)) { + throw new Error('apiKey is an empty string!'); + } +} diff --git a/src/auto-api.ts b/src/auto-api/auto-api.ts similarity index 96% rename from src/auto-api.ts rename to src/auto-api/auto-api.ts index 7d182de..09be203 100644 --- a/src/auto-api.ts +++ b/src/auto-api/auto-api.ts @@ -10,7 +10,7 @@ import { TestRunCreateResponseDto, } from './dto.ts'; import { API_VERSION } from './version.ts'; -import { ApplauseConfig, validateConfig } from './config.ts'; +import { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts'; export class AutoApi { private readonly client: AxiosInstance; @@ -23,11 +23,11 @@ export class AutoApi { return this.callsInFlight; } - constructor(readonly options: ApplauseConfig) { + constructor(readonly options: AutoApiConfig) { this.callsInFlight = 0; - validateConfig(options); + validateAutoApiConfig(options); this.client = axios.create({ - baseURL: options.baseUrl, + baseURL: options.autoApiBaseUrl, timeout: 10000, headers: { 'X-Api-Key': options.apiKey, diff --git a/src/dto.ts b/src/auto-api/dto.ts similarity index 100% rename from src/dto.ts rename to src/auto-api/dto.ts diff --git a/src/email-helper.ts b/src/auto-api/email-helper.ts similarity index 100% rename from src/email-helper.ts rename to src/auto-api/email-helper.ts diff --git a/src/email/attachment.ts b/src/auto-api/email/attachment.ts similarity index 100% rename from src/email/attachment.ts rename to src/auto-api/email/attachment.ts diff --git a/src/email/inbox.ts b/src/auto-api/email/inbox.ts similarity index 100% rename from src/email/inbox.ts rename to src/auto-api/email/inbox.ts diff --git a/src/heartbeat.ts b/src/auto-api/heartbeat.ts similarity index 100% rename from src/heartbeat.ts rename to src/auto-api/heartbeat.ts diff --git a/src/auto-api/index.ts b/src/auto-api/index.ts new file mode 100644 index 0000000..2f3586c --- /dev/null +++ b/src/auto-api/index.ts @@ -0,0 +1,6 @@ +// Re-export DTOs +export * from './auto-api.ts'; +export * from './dto.ts'; +export * from './email-helper.ts'; +export * from './heartbeat.ts'; +export * from './reporter.ts'; diff --git a/src/reporter.ts b/src/auto-api/reporter.ts similarity index 95% rename from src/reporter.ts rename to src/auto-api/reporter.ts index 85095f9..017f0d2 100644 --- a/src/reporter.ts +++ b/src/auto-api/reporter.ts @@ -7,7 +7,7 @@ import { } from './dto.ts'; import { TestRunHeartbeatService } from './heartbeat.ts'; import { join as pathJoin } from 'path'; -import { ApplauseConfig } from './config.ts'; +import { AutoApiConfig } from './auto-api-config.ts'; export class ApplauseReporter { private autoApi: AutoApi; @@ -16,7 +16,7 @@ export class ApplauseReporter { private runStarted: boolean = false; private runFinished: boolean = false; - constructor(config: ApplauseConfig) { + constructor(config: AutoApiConfig) { this.autoApi = new AutoApi(config); this.initializer = new RunInitializer(this.autoApi); } @@ -173,10 +173,10 @@ export class RunReporter { } } } -const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-'; -const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-'; +export const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-'; +export const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-'; -function parseTestCaseName(testCaseName: string): ParsedTestCaseName { +export function parseTestCaseName(testCaseName: string): ParsedTestCaseName { // Split the name on spaces. We will reassemble after parsing out the other ids const tokens = testCaseName.split(' '); let testRailTestCaseId: string | undefined; diff --git a/src/version.ts b/src/auto-api/version.ts similarity index 100% rename from src/version.ts rename to src/auto-api/version.ts diff --git a/src/config.ts b/src/config/config.ts similarity index 63% rename from src/config.ts rename to src/config/config.ts index 2b6705a..5aa9d90 100644 --- a/src/config.ts +++ b/src/config/config.ts @@ -1,19 +1,20 @@ import { existsSync, readFileSync } from 'fs'; -import { TestRailOptions } from './dto.ts'; import path from 'path'; -import Validator from 'validator'; -const validator = Validator.default; - -export interface ApplauseConfig { - readonly baseUrl: string; - readonly apiKey: string; - readonly productId: number; - readonly testRailOptions?: TestRailOptions; - readonly applauseTestCycleId?: number; -} - -export const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/'; +import { + AutoApiConfig, + DEFAULT_AUTO_API_PROPERTIES, + isAutoApiConfigComplete, + validateAutoApiConfig, +} from '../auto-api/auto-api-config.ts'; +import { + DEFAULT_PUBLIC_API_PROPERTIES, + isPublicApiConfigComplete, + PublicApiConfig, + validatePublicApiConfig, +} from '../public-api/public-api-config.ts'; + +export type ApplauseConfig = AutoApiConfig & PublicApiConfig; export interface ConfigLoadProperties { configFile?: string; @@ -24,7 +25,8 @@ export interface ConfigLoadProperties { export function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig { // Setup the initial config with any default properties let config: Partial = { - baseUrl: DEFAULT_URL, + ...DEFAULT_PUBLIC_API_PROPERTIES, + ...DEFAULT_AUTO_API_PROPERTIES, }; // Load properties from the provided config file @@ -69,11 +71,7 @@ export function overrideConfig( } export function isComplete(config: Partial): boolean { - return ( - config.baseUrl !== undefined && - config.apiKey !== undefined && - config.productId !== undefined - ); + return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config); } export function loadConfigFromFile( @@ -88,32 +86,8 @@ export function loadConfigFromFile( } export function validateConfig(config: ApplauseConfig) { - if (!Number.isInteger(config.productId) || config.productId <= 0) { - throw new Error( - `productId must be a positive integer, was: '${config.productId}'` - ); - } - if ( - !validator.isURL(config.baseUrl, { - protocols: ['http', 'https'], - require_tld: false, // allow localhost - allow_query_components: false, - disallow_auth: true, - allow_fragments: false, - allow_protocol_relative_urls: false, - allow_trailing_dot: false, - require_host: true, - require_protocol: true, - }) - ) { - throw new Error( - `baseUrl is not valid HTTP/HTTPS URL, was: ${config.baseUrl}` - ); - } - - if (validator.isEmpty(config.apiKey)) { - throw new Error('apiKey is an empty string!'); - } + validateAutoApiConfig(config); + validatePublicApiConfig(config); } export function validatePartialConfig(config: Partial) { diff --git a/src/index.ts b/src/index.ts index df3a0b7..317c871 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,3 @@ -// Re-export DTOs -export * from './auto-api.ts'; -export * from './config.ts'; -export * from './dto.ts'; -export * from './email-helper.ts'; -export * from './heartbeat.ts'; -export * from './reporter.ts'; +export * from './auto-api/index.ts'; +export * from './public-api/index.ts'; +export * from './config/config.ts'; diff --git a/src/public-api/dto.ts b/src/public-api/dto.ts new file mode 100644 index 0000000..4fc0b37 --- /dev/null +++ b/src/public-api/dto.ts @@ -0,0 +1,16 @@ +export interface TestRunAutoResultDto { + testCycleId: number; + status: TestRunAutoResultStatus; + failureReason?: string; + sessionDetailsJson?: object; + startTime?: Date; + endTime?: Date; +} + +export enum TestRunAutoResultStatus { + PASSED = 'PASSED', + FAILED = 'FAILED', + SKIPPED = 'SKIPPED', + CANCELED = 'CANCELED', + ERROR = 'ERROR', +} diff --git a/src/public-api/index.ts b/src/public-api/index.ts new file mode 100644 index 0000000..8c9c20a --- /dev/null +++ b/src/public-api/index.ts @@ -0,0 +1,2 @@ +export * from './dto.ts'; +export * from './public-api.ts'; diff --git a/src/public-api/public-api-config.ts b/src/public-api/public-api-config.ts new file mode 100644 index 0000000..aa8a063 --- /dev/null +++ b/src/public-api/public-api-config.ts @@ -0,0 +1,67 @@ +import Validator from 'validator'; +const validator = Validator.default; + +export interface PublicApiConfig { + readonly publicApiBaseUrl: string; + readonly apiKey: string; + readonly productId: number; + readonly applauseTestCycleId?: number; +} + +export const DEFAULT_URL = 'https://api.applause.com/'; + +export const DEFAULT_PUBLIC_API_PROPERTIES: Partial = { + publicApiBaseUrl: DEFAULT_URL, +}; + +export function isPublicApiConfigComplete( + config: Partial +): boolean { + return ( + config.publicApiBaseUrl !== undefined && + config.apiKey !== undefined && + config.productId !== undefined + ); +} + +export function validatePartialPublicApiConfig( + config: Partial +) { + if ( + config.productId !== undefined && + (!Number.isInteger(config.productId) || config.productId <= 0) + ) { + throw new Error( + `productId must be a positive integer, was: '${config.productId}'` + ); + } +} + +export function validatePublicApiConfig(config: PublicApiConfig) { + if (!Number.isInteger(config.productId) || config.productId <= 0) { + throw new Error( + `productId must be a positive integer, was: '${config.productId}'` + ); + } + if ( + !validator.isURL(config.publicApiBaseUrl, { + protocols: ['http', 'https'], + require_tld: false, // allow localhost + allow_query_components: false, + disallow_auth: true, + allow_fragments: false, + allow_protocol_relative_urls: false, + allow_trailing_dot: false, + require_host: true, + require_protocol: true, + }) + ) { + throw new Error( + `publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}` + ); + } + + if (validator.isEmpty(config.apiKey)) { + throw new Error('apiKey is an empty string!'); + } +} diff --git a/src/public-api/public-api.ts b/src/public-api/public-api.ts new file mode 100644 index 0000000..b7637d7 --- /dev/null +++ b/src/public-api/public-api.ts @@ -0,0 +1,64 @@ +import axios, { AxiosInstance, AxiosResponse } from 'axios'; +import { TestRunAutoResultDto } from './dto.ts'; +import { + PublicApiConfig, + validatePublicApiConfig, +} from './public-api-config.ts'; + +export class PublicApi { + private readonly client: AxiosInstance; + + private callsInFlight: number; + /** + * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + */ + public get getCallsInFlight(): number { + return this.callsInFlight; + } + + constructor(readonly options: PublicApiConfig) { + this.callsInFlight = 0; + validatePublicApiConfig(options); + this.client = axios.create({ + baseURL: options.publicApiBaseUrl, + timeout: 10000, + headers: { + 'X-Api-Key': options.apiKey, + 'Context-Type': 'application/json', + }, + responseType: 'json', + }); + this.client.interceptors.response.use( + function (response: AxiosResponse) { + return response; + }, + function (error) { + // log and rethrow + const errText = + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + error.data !== undefined + ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + error.data + : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + `error-code [${error.response.status}] with error [${error.response.statusText}]`; + console.error(`Public-Api returned ${errText}`); + return Promise.reject(error); + } + ); + } + + async submitResult( + testCaseId: number, + info: TestRunAutoResultDto + ): Promise> { + this.callsInFlight += 1; + try { + return await this.client.post( + `v2/test-case-results/${testCaseId}/submit`, + info + ); + } finally { + this.callsInFlight -= 1; + } + } +} diff --git a/test/auto-api.test.ts b/test/auto-api.test.ts index 1c342b6..8acf06e 100644 --- a/test/auto-api.test.ts +++ b/test/auto-api.test.ts @@ -1,9 +1,9 @@ -import { AutoApi } from '../src/auto-api.ts'; +import { AutoApi } from '../src/auto-api/auto-api.ts'; jest.setTimeout(400_000); test('should create the thing', () => { const autoApi = new AutoApi({ - baseUrl: 'http://www.example.com', + autoApiBaseUrl: 'http://www.example.com', apiKey: 'apiKey', productId: 1, }); @@ -13,7 +13,7 @@ test('should create the thing', () => { test('providing bogus productId should throw an exception', () => { const test = () => { new AutoApi({ - baseUrl: 'http://www.example.com', + autoApiBaseUrl: 'http://www.example.com', apiKey: 'apiKey', productId: -1, }); diff --git a/test/config.test.ts b/test/config.test.ts index 0d6704c..d540d46 100644 --- a/test/config.test.ts +++ b/test/config.test.ts @@ -1,4 +1,5 @@ -import { DEFAULT_URL, loadConfig } from '../src/config.ts'; +import { DEFAULT_URL } from '../src/auto-api/auto-api-config.ts'; +import { loadConfig } from '../src/config/config.ts'; describe('config loader', () => { it('should load the config and use the default url', () => { @@ -6,7 +7,7 @@ describe('config loader', () => { configFile: './test/resources/applause.json', }); - expect(config.baseUrl).toBe(DEFAULT_URL); + expect(config.autoApiBaseUrl).toBe(DEFAULT_URL); expect(config.apiKey).toBe('fakeKey'); expect(config.productId).toBe(1); expect(config.applauseTestCycleId).toBeUndefined(); @@ -18,7 +19,7 @@ describe('config loader', () => { configFile: './test/resources/applause-with-url.json', }); - expect(config.baseUrl).toBe('http://localhost:8080'); + expect(config.autoApiBaseUrl).toBe('http://localhost:8080'); expect(config.apiKey).toBe('fakeKey'); expect(config.productId).toBe(1); expect(config.applauseTestCycleId).toBeUndefined(); @@ -29,11 +30,11 @@ describe('config loader', () => { const config = loadConfig({ configFile: './test/resources/applause-with-url.json', properties: { - baseUrl: 'http://overwritten.com', + autoApiBaseUrl: 'http://overwritten.com', }, }); - expect(config.baseUrl).toBe('http://overwritten.com'); + expect(config.autoApiBaseUrl).toBe('http://overwritten.com'); expect(config.apiKey).toBe('fakeKey'); expect(config.productId).toBe(1); expect(config.applauseTestCycleId).toBeUndefined(); @@ -45,7 +46,7 @@ describe('config loader', () => { loadConfig({ configFile: './test/resources/bad-url-applause.json', }) - ).toThrowError('baseUrl is not valid HTTP/HTTPS URL, was: notAUrl'); + ).toThrowError('autoApiBaseUrl is not valid HTTP/HTTPS URL, was: notAUrl'); }); it('should fail for an invalid productId', () => { @@ -70,13 +71,13 @@ describe('config loader', () => { properties: { apiKey: undefined, applauseTestCycleId: undefined, - baseUrl: undefined, + autoApiBaseUrl: undefined, productId: undefined, testRailOptions: undefined, }, }); - expect(config.baseUrl).toBe('http://localhost:8080'); + expect(config.autoApiBaseUrl).toBe('http://localhost:8080'); expect(config.apiKey).toBe('fakeKey'); expect(config.productId).toBe(1); expect(config.applauseTestCycleId).toBeUndefined(); diff --git a/test/email.test.ts b/test/email.test.ts index 47faca6..ace624d 100644 --- a/test/email.test.ts +++ b/test/email.test.ts @@ -1,12 +1,12 @@ import { readFileSync } from "fs"; -import { AutoApi } from "../src/auto-api.ts"; -import { EmailAddressResponse } from "../src/dto.ts"; +import { AutoApi } from "../src/auto-api/auto-api.ts"; +import { EmailAddressResponse } from "../src/auto-api/dto.ts"; -import { EmailHelper } from "../src/email-helper.ts"; +import { EmailHelper } from "../src/auto-api/email-helper.ts"; import { AddressObject } from "mailparser"; import { randomUUID } from "crypto"; -jest.mock('../src/auto-api.ts', () => { +jest.mock('../src/auto-api/auto-api.ts', () => { return { AutoApi: jest.fn().mockImplementation(() => { return { @@ -33,7 +33,7 @@ describe('email tests', () => { it('should parse the email correctly', async () => { var emailHelper = new EmailHelper(new AutoApi({ - baseUrl: 'http://example.com', + autoApiBaseUrl: 'http://example.com', apiKey: 'apiKey', productId: -1, })); diff --git a/test/heartbeat.test.ts b/test/heartbeat.test.ts index b4396f1..35685ec 100644 --- a/test/heartbeat.test.ts +++ b/test/heartbeat.test.ts @@ -1,12 +1,12 @@ -import { AutoApi } from '../src/auto-api.ts'; +import { AutoApi } from '../src/auto-api/auto-api.ts'; import { TestResultProviderInfo, TestRunCreateResponseDto, -} from '../src/dto.ts'; -import { TestRunHeartbeatService } from '../src/heartbeat.ts'; +} from '../src/auto-api/dto.ts'; +import { TestRunHeartbeatService } from '../src/auto-api/heartbeat.ts'; jest.useFakeTimers(); -jest.mock('../src/auto-api.ts', () => { +jest.mock('../src/auto-api/auto-api.ts', () => { return { AutoApi: jest.fn().mockImplementation(() => { return { @@ -45,7 +45,7 @@ async function waitForNextHeartbeat() { } const autoApi = new AutoApi({ apiKey: 'apiKey', - baseUrl: 'http://localhost', + autoApiBaseUrl: 'http://localhost', productId: 1, }); const heartbeatCommandSpy = jest.spyOn(autoApi, 'sendSdkHeartbeat'); diff --git a/test/public-api.test.ts b/test/public-api.test.ts new file mode 100644 index 0000000..ed2a968 --- /dev/null +++ b/test/public-api.test.ts @@ -0,0 +1,23 @@ +import { PublicApi } from '../src/index.ts'; + +jest.setTimeout(400_000); + +test('should create the thing', () => { + const publicAPI = new PublicApi({ + publicApiBaseUrl: 'http://www.example.com', + apiKey: 'apiKey', + productId: 1, + }); + expect(publicAPI).not.toBeUndefined(); +}); + +test('providing bogus productId should throw an exception', () => { + const test = () => { + new PublicApi({ + publicApiBaseUrl: 'http://www.example.com', + apiKey: 'apiKey', + productId: -1, + }); + }; + expect(test).toThrow('productId must be a positive integer, was'); +}); diff --git a/test/reporter.test.ts b/test/reporter.test.ts index a73eb8b..2afffe2 100644 --- a/test/reporter.test.ts +++ b/test/reporter.test.ts @@ -1,13 +1,13 @@ -import { ApplauseReporter, RunInitializer, RunReporter } from '../src/reporter.ts'; +import { ApplauseReporter, RunInitializer, RunReporter } from '../src/auto-api/reporter.ts'; import { CreateTestCaseResultDto, CreateTestCaseResultResponseDto, TestResultProviderInfo, TestResultStatus, TestRunCreateDto, -} from '../src/dto.ts'; -import { TestRunHeartbeatService } from '../src/heartbeat.ts'; -import { AutoApi } from '../src/auto-api.ts'; +} from '../src/auto-api/dto.ts'; +import { TestRunHeartbeatService } from '../src/auto-api/heartbeat.ts'; +import { AutoApi } from '../src/auto-api/auto-api.ts'; const mockedAutoApi = { startTestRun: jest.fn((req: any) => { @@ -42,13 +42,13 @@ const mockedAutoApi = { }, }; -jest.mock('../src/auto-api.ts', () => { +jest.mock('../src/auto-api/auto-api.ts', () => { return { AutoApi: jest.fn().mockImplementation(() => mockedAutoApi), }; }); -jest.mock('../src/heartbeat.ts', () => { +jest.mock('../src/auto-api/heartbeat.ts', () => { return { TestRunHeartbeatService: jest.fn().mockImplementation(() => { return { @@ -70,7 +70,7 @@ describe('reporter test', () => { jest.clearAllMocks(); reporter = new ApplauseReporter({ apiKey: 'apiKey', - baseUrl: 'localhost', + autoApiBaseUrl: 'localhost', productId: 1, }); }); @@ -109,7 +109,7 @@ describe('reporter test', () => { it('should pass the test case name and run id', () => { const mockedAutoApi = new AutoApi({ apiKey: '', - baseUrl: '', + autoApiBaseUrl: '', productId: 0, }); const rr = new RunReporter( @@ -126,7 +126,7 @@ describe('reporter test', () => { it('should extract out the testrail id', () => { const mockedAutoApi = new AutoApi({ apiKey: '', - baseUrl: '', + autoApiBaseUrl: '', productId: 0, }); const rr = new RunReporter( @@ -144,7 +144,7 @@ describe('reporter test', () => { it('should extract out the applause test case id', () => { const mockedAutoApi = new AutoApi({ apiKey: '', - baseUrl: '', + autoApiBaseUrl: '', productId: 0, }); const rr = new RunReporter( @@ -162,7 +162,7 @@ describe('reporter test', () => { it('should allow overwriting of testrail test case id', () => { const mockedAutoApi = new AutoApi({ apiKey: '', - baseUrl: '', + autoApiBaseUrl: '', productId: 0, }); const rr = new RunReporter( @@ -180,7 +180,7 @@ describe('reporter test', () => { it('should allow overwriting of applause test case id', () => { const mockedAutoApi = new AutoApi({ apiKey: '', - baseUrl: '', + autoApiBaseUrl: '', productId: 0, }); const rr = new RunReporter( @@ -198,7 +198,7 @@ describe('reporter test', () => { it('should not overwrite the test case id if other values are passed', () => { const mockedAutoApi = new AutoApi({ apiKey: '', - baseUrl: '', + autoApiBaseUrl: '', productId: 0, }); const rr = new RunReporter( @@ -218,7 +218,7 @@ describe('reporter test', () => { it('should filter out Test Case IDs when precreating results', async () => { const mockedAutoApi = new AutoApi({ apiKey: '', - baseUrl: '', + autoApiBaseUrl: '', productId: 0, }); const ri = new RunInitializer( diff --git a/test/resources/applause-with-url.json b/test/resources/applause-with-url.json index 05d71fb..5d7fb78 100644 --- a/test/resources/applause-with-url.json +++ b/test/resources/applause-with-url.json @@ -1,5 +1,5 @@ { "apiKey": "fakeKey", - "baseUrl": "http://localhost:8080", + "autoApiBaseUrl": "http://localhost:8080", "productId": 1 } \ No newline at end of file diff --git a/test/resources/bad-url-applause.json b/test/resources/bad-url-applause.json index bce2556..4cbc781 100644 --- a/test/resources/bad-url-applause.json +++ b/test/resources/bad-url-applause.json @@ -1,5 +1,5 @@ { "apiKey": "fakeKey", - "baseUrl": "notAUrl", + "autoApiBaseUrl": "notAUrl", "productId": 1 } \ No newline at end of file From 75082fa12396b0d9955a0d86a2b5f7a86bf719be Mon Sep 17 00:00:00 2001 From: rconner46 Date: Tue, 30 Jul 2024 10:34:54 -0500 Subject: [PATCH 2/6] Minor updates to common reporter - Add interface for public api session details field - Better Handling of Test Case Name/ID Parsing --- dist/index.cjs | 57 ++++++++++++++++++-------------------- dist/index.cjs.map | 2 +- dist/index.d.ts | 31 ++++++++++++++------- dist/index.min.js | 2 +- dist/index.min.js.map | 2 +- dist/index.mjs | 57 ++++++++++++++++++-------------------- dist/index.mjs.map | 2 +- src/auto-api/reporter.ts | 44 +----------------------------- src/index.ts | 1 + src/public-api/dto.ts | 13 ++++++++- src/shared/index.ts | 1 + src/shared/test-case.ts | 35 ++++++++++++++++++++++++ test/test-case.test.ts | 59 ++++++++++++++++++++++++++++++++++++++++ 13 files changed, 186 insertions(+), 120 deletions(-) create mode 100644 src/shared/index.ts create mode 100644 src/shared/test-case.ts create mode 100644 test/test-case.test.ts diff --git a/dist/index.cjs b/dist/index.cjs index eea377a..0f6ea0b 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -257,6 +257,32 @@ class TestRunHeartbeatService { } } +const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-'; +const APPLAUSE_CASE_ID_PREFIX = 'Applause-'; +function parseTestCaseName(testCaseName) { + const matches = testCaseName.match(/(TestRail-\d+|Applause-\d+)/g); + const testRailCaseIds = matches + ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX)) + .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) || []; + const applauseCaseIds = matches + ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX)) + .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || []; + if (testRailCaseIds.length > 1) { + console.warn('Multiple TestRail case ids detected in testCase name'); + } + if (applauseCaseIds.length > 1) { + console.warn('Multiple Applause case ids detected in testCase name'); + } + return { + applauseTestCaseId: applauseCaseIds[0], + testRailTestCaseId: testRailCaseIds[0], + testCaseName: testCaseName + .replace(/(TestRail-\d+|Applause-\d+)/g, '') + .replace(/\s+/g, ' ') + .trim(), + }; +} + class ApplauseReporter { autoApi; initializer; @@ -374,37 +400,6 @@ class RunReporter { } } } -const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-'; -const APPLAUSE_CASE_ID_PREFIX = 'Applause-'; -function parseTestCaseName(testCaseName) { - // Split the name on spaces. We will reassemble after parsing out the other ids - const tokens = testCaseName.split(' '); - let testRailTestCaseId; - let applauseTestCaseId; - tokens.forEach(token => { - if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) { - if (testRailTestCaseId !== undefined) { - console.warn('Multiple TestRail case ids detected in testCase name'); - } - testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length); - } - else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) { - if (applauseTestCaseId !== undefined) { - console.warn('Multiple Applause case ids detected in testCase name'); - } - applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length); - } - }); - return { - applauseTestCaseId, - testRailTestCaseId, - testCaseName: tokens - .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`) - .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`) - .join(' ') - .trim(), - }; -} exports.TestRunAutoResultStatus = void 0; (function (TestRunAutoResultStatus) { diff --git a/dist/index.cjs.map b/dist/index.cjs.map index c71101e..f1a121f 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/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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nexport const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","TestResultStatus","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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","TestResultStatus","simpleParser","writeFileSync","pathJoin","TestRunAutoResultStatus","existsSync","readFileSync"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 7b3a652..7fbadf1 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -183,20 +183,12 @@ declare class RunReporter { submitTestCaseResult(id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams): void; runnerEnd(): Promise; } -declare const TEST_RAIL_CASE_ID_PREFIX: string; -declare const APPLAUSE_CASE_ID_PREFIX: string; -declare function parseTestCaseName(testCaseName: string): ParsedTestCaseName; -interface ParsedTestCaseName { - testCaseName: string; - testRailTestCaseId?: string; - applauseTestCaseId?: string; -} interface TestRunAutoResultDto { testCycleId: number; status: TestRunAutoResultStatus; failureReason?: string; - sessionDetailsJson?: object; + sessionDetailsJson?: SessionDetails; startTime?: Date; endTime?: Date; } @@ -207,6 +199,16 @@ declare enum TestRunAutoResultStatus { CANCELED = "CANCELED", ERROR = "ERROR" } +interface SessionDetails { + value: { + deviceName?: string; + orientation?: string; + platformName?: string; + platformVersion?: string; + browserName?: string; + browserVersion?: string; + }; +} interface PublicApiConfig { readonly publicApiBaseUrl: string; @@ -239,4 +241,13 @@ declare function loadConfigFromFile(configFile?: string): Partial): void; -export { APPLAUSE_CASE_ID_PREFIX, type AdditionalTestCaseParams, type AdditionalTestCaseResultParams, type ApplauseConfig, ApplauseReporter, type Attachment, AutoApi, type ClientConfig, type ConfigLoadProperties, type CreateTestCaseResultDto, type CreateTestCaseResultResponseDto, type EmailAddressResponse, type EmailFetchRequest, EmailHelper, Inbox, PublicApi, RunInitializer, RunReporter, type SubmitTestCaseResultDto, TEST_RAIL_CASE_ID_PREFIX, type TestRailOptions, type TestResultProviderInfo, TestResultStatus, type TestRunAutoResultDto, TestRunAutoResultStatus, type TestRunCreateDto, type TestRunCreateResponseDto, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; +declare const TEST_RAIL_CASE_ID_PREFIX: string; +declare const APPLAUSE_CASE_ID_PREFIX: string; +declare function parseTestCaseName(testCaseName: string): ParsedTestCaseName; +interface ParsedTestCaseName { + testCaseName: string; + testRailTestCaseId?: string; + applauseTestCaseId?: string; +} + +export { APPLAUSE_CASE_ID_PREFIX, type AdditionalTestCaseParams, type AdditionalTestCaseResultParams, type ApplauseConfig, ApplauseReporter, type Attachment, AutoApi, type ClientConfig, type ConfigLoadProperties, type CreateTestCaseResultDto, type CreateTestCaseResultResponseDto, type EmailAddressResponse, type EmailFetchRequest, EmailHelper, Inbox, type ParsedTestCaseName, PublicApi, RunInitializer, RunReporter, type SessionDetails, type SubmitTestCaseResultDto, TEST_RAIL_CASE_ID_PREFIX, type TestRailOptions, type TestResultProviderInfo, TestResultStatus, type TestRunAutoResultDto, TestRunAutoResultStatus, type TestRunCreateDto, type TestRunCreateResponseDto, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; diff --git a/dist/index.min.js b/dist/index.min.js index eaeff67..8ec3b83 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("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,a,r){"use strict";const n=s.default,o={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function l(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!n.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(n.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}class u{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,l(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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.0.0",productId:this.options.productId,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}}}var p;t.TestResultStatus=void 0,(p=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",p.IN_PROGRESS="IN_PROGRESS",p.PASSED="PASSED",p.FAILED="FAILED",p.SKIPPED="SKIPPED",p.CANCELED="CANCELED",p.ERROR="ERROR";class d{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await i.simpleParser(t.data)}}class c{testRunId;autoApi;enabled=!1;nextHeartbeat;constructor(t,e){this.testRunId=t,this.autoApi=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(){console.log("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),console.log("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,console.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,console.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}class h{autoApi;constructor(t){this.autoApi=t}async initializeRun(t){const e=t?.map(g).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e||[]});if(s.status<200||s.status>300)throw new Error("Unable to create test run");const i=s.data.runId;console.log("Test Run %d initialized",i);const a=new c(i,this.autoApi);return await a.start(),new I(this.autoApi,i,a)}}class I{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};constructor(t,e,s){this.autoApi=t,this.testRunId=e,this.heartbeatService=s}startTestCase(t,e,s){const i=g(e);this.uidToResultIdMap[t]=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))}submitTestCaseResult(t,e,s){this.resultSubmissionMap[t]=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s})))}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){console.info(JSON.stringify(e));const t=".";a.writeFileSync(r.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}const R="TestRail-",f="Applause-";function g(t){const e=t.split(" ");let s,i;return e.forEach((t=>{t?.startsWith(R)?(void 0!==s&&console.warn("Multiple TestRail case ids detected in testCase name"),s=t.substring(R.length)):t?.startsWith(f)&&(void 0!==i&&console.warn("Multiple Applause case ids detected in testCase name"),i=t.substring(f.length))})),{applauseTestCaseId:i,testRailTestCaseId:s,testCaseName:e.filter((t=>t!==`${R}${s||""}`)).filter((t=>t!==`${f}${i||""}`)).join(" ").trim()}}var w;t.TestRunAutoResultStatus=void 0,(w=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",w.FAILED="FAILED",w.SKIPPED="SKIPPED",w.CANCELED="CANCELED",w.ERROR="ERROR";const A=s.default,m={publicApiBaseUrl:"https://api.applause.com/"};function b(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!A.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(A.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function y(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e||{}).filter((([t,e])=>void 0!==e))))}function E(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 v(t){const e=t||process.cwd()+"/applause.json";if(!a.existsSync(e))return{};const s=a.readFileSync(e,"utf8");return JSON.parse(s)}function T(t){l(t),b(t)}t.APPLAUSE_CASE_ID_PREFIX=f,t.ApplauseReporter=class{autoApi;initializer;reporter;runStarted=!1;runFinished=!1;constructor(t){this.autoApi=new u(t),this.initializer=new h(this.autoApi)}runnerStart(t){this.reporter=this.initializer.initializeRun(t),this.reporter.then((()=>{this.runStarted=!0}))}startTestCase(t,e,s){if(void 0===this.reporter)throw new Error("Cannot start a test case for a run that was never initialized");this.reporter.then((i=>i.startTestCase(t,e,s)))}submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw new Error("Cannot submit test case result for a run that was never initialized");this.reporter.then((i=>i.submitTestCaseResult(t,e,s)))}async runnerEnd(){if(void 0===this.reporter)throw new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.AutoApi=u,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new d(e,this.autoApi)}},t.Inbox=d,t.PublicApi=class{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,b(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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=h,t.RunReporter=I,t.TEST_RAIL_CASE_ID_PREFIX=R,t.TestRunHeartbeatService=c,t.isComplete=E,t.loadConfig=function(t){let e={...m,...o};if(e=void 0!==t&&void 0!==t.configFile?y(e,v(r.join(process.cwd(),t.configFile))):y(e,v()),void 0!==t&&void 0!==t.properties&&(e=y(e,t.properties)),!E(e))throw new Error("Config is not complete");const s=e;return T(s),s},t.loadConfigFromFile=v,t.overrideConfig=y,t.parseTestCaseName=g,t.validateConfig=T,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("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,a,r){"use strict";const n=s.default,o={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function l(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!n.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(n.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}class u{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,l(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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.0.0",productId:this.options.productId,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}}}var p;t.TestResultStatus=void 0,(p=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",p.IN_PROGRESS="IN_PROGRESS",p.PASSED="PASSED",p.FAILED="FAILED",p.SKIPPED="SKIPPED",p.CANCELED="CANCELED",p.ERROR="ERROR";class d{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await i.simpleParser(t.data)}}class c{testRunId;autoApi;enabled=!1;nextHeartbeat;constructor(t,e){this.testRunId=t,this.autoApi=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(){console.log("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),console.log("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,console.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,console.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}const h="TestRail-",R="Applause-";function I(t){const e=t.match(/(TestRail-\d+|Applause-\d+)/g),s=e?.filter((t=>t.startsWith(h))).map((t=>t.substring(9)))||[],i=e?.filter((t=>t.startsWith(R))).map((t=>t.substring(9)))||[];return s.length>1&&console.warn("Multiple TestRail case ids detected in testCase name"),i.length>1&&console.warn("Multiple Applause case ids detected in testCase name"),{applauseTestCaseId:i[0],testRailTestCaseId:s[0],testCaseName:t.replace(/(TestRail-\d+|Applause-\d+)/g,"").replace(/\s+/g," ").trim()}}class g{autoApi;constructor(t){this.autoApi=t}async initializeRun(t){const e=t?.map(I).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e||[]});if(s.status<200||s.status>300)throw new Error("Unable to create test run");const i=s.data.runId;console.log("Test Run %d initialized",i);const a=new c(i,this.autoApi);return await a.start(),new f(this.autoApi,i,a)}}class f{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};constructor(t,e,s){this.autoApi=t,this.testRunId=e,this.heartbeatService=s}startTestCase(t,e,s){const i=I(e);this.uidToResultIdMap[t]=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))}submitTestCaseResult(t,e,s){this.resultSubmissionMap[t]=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s})))}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){console.info(JSON.stringify(e));const t=".";a.writeFileSync(r.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}var m;t.TestRunAutoResultStatus=void 0,(m=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",m.FAILED="FAILED",m.SKIPPED="SKIPPED",m.CANCELED="CANCELED",m.ERROR="ERROR";const A=s.default,w={publicApiBaseUrl:"https://api.applause.com/"};function b(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!A.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(A.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function y(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e||{}).filter((([t,e])=>void 0!==e))))}function T(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 E(t){const e=t||process.cwd()+"/applause.json";if(!a.existsSync(e))return{};const s=a.readFileSync(e,"utf8");return JSON.parse(s)}function v(t){l(t),b(t)}t.APPLAUSE_CASE_ID_PREFIX=R,t.ApplauseReporter=class{autoApi;initializer;reporter;runStarted=!1;runFinished=!1;constructor(t){this.autoApi=new u(t),this.initializer=new g(this.autoApi)}runnerStart(t){this.reporter=this.initializer.initializeRun(t),this.reporter.then((()=>{this.runStarted=!0}))}startTestCase(t,e,s){if(void 0===this.reporter)throw new Error("Cannot start a test case for a run that was never initialized");this.reporter.then((i=>i.startTestCase(t,e,s)))}submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw new Error("Cannot submit test case result for a run that was never initialized");this.reporter.then((i=>i.submitTestCaseResult(t,e,s)))}async runnerEnd(){if(void 0===this.reporter)throw new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.AutoApi=u,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new d(e,this.autoApi)}},t.Inbox=d,t.PublicApi=class{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,b(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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=g,t.RunReporter=f,t.TEST_RAIL_CASE_ID_PREFIX=h,t.TestRunHeartbeatService=c,t.isComplete=T,t.loadConfig=function(t){let e={...w,...o};if(e=void 0!==t&&void 0!==t.configFile?y(e,E(r.join(process.cwd(),t.configFile))):y(e,E()),void 0!==t&&void 0!==t.properties&&(e=y(e,t.properties)),!T(e))throw new Error("Config is not complete");const s=e;return v(s),s},t.loadConfigFromFile=E,t.overrideConfig=y,t.parseTestCaseName=I,t.validateConfig=v,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 5bd3daa..ad4392d 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/auto-api/auto-api.ts","../src/auto-api/dto.ts","../src/auto-api/email/inbox.ts","../src/auto-api/heartbeat.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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nexport const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map"],"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","AutoApi","options","client","callsInFlight","getCallsInFlight","this","constructor","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","status","statusText","console","Promise","reject","startTestRun","info","post","sdkVersion","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","TestResultStatus","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","log","debug","RunInitializer","initializeRun","tests","cleanedTests","map","parseTestCaseName","parsed","testCaseName","trim","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","testCaseId","testRailTestCaseId","itwTestCaseId","applauseTestCaseId","Object","fromEntries","entries","_","v","testResultId","resultId","runnerEnd","all","values","jsonArray","length","JSON","stringify","outputPath","writeFileSync","pathJoin","join","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","tokens","split","forEach","token","startsWith","warn","substring","TestRunAutoResultStatus","DEFAULT_PUBLIC_API_PROPERTIES","publicApiBaseUrl","validatePublicApiConfig","overrideConfig","overrides","assign","isComplete","isAutoApiConfigComplete","isPublicApiConfigComplete","loadConfigFromFile","configFile","configFilePath","process","cwd","existsSync","fileCotents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","runnerStart","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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map"],"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","AutoApi","options","client","callsInFlight","getCallsInFlight","this","constructor","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","status","statusText","console","Promise","reject","startTestRun","info","post","sdkVersion","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","TestResultStatus","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","log","debug","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","parseTestCaseName","testCaseName","matches","match","testRailCaseIds","startsWith","map","substring","applauseCaseIds","length","warn","applauseTestCaseId","testRailTestCaseId","replace","trim","RunInitializer","initializeRun","tests","cleanedTests","parsed","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","testCaseId","itwTestCaseId","Object","fromEntries","entries","_","v","testResultId","resultId","runnerEnd","all","values","jsonArray","JSON","stringify","outputPath","writeFileSync","pathJoin","join","TestRunAutoResultStatus","DEFAULT_PUBLIC_API_PROPERTIES","publicApiBaseUrl","validatePublicApiConfig","overrideConfig","overrides","assign","isComplete","isAutoApiConfigComplete","isPublicApiConfigComplete","loadConfigFromFile","configFile","configFilePath","process","cwd","existsSync","fileCotents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","runnerStart","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 38da9b9..ed025c1 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -255,6 +255,32 @@ class TestRunHeartbeatService { } } +const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-'; +const APPLAUSE_CASE_ID_PREFIX = 'Applause-'; +function parseTestCaseName(testCaseName) { + const matches = testCaseName.match(/(TestRail-\d+|Applause-\d+)/g); + const testRailCaseIds = matches + ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX)) + .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) || []; + const applauseCaseIds = matches + ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX)) + .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || []; + if (testRailCaseIds.length > 1) { + console.warn('Multiple TestRail case ids detected in testCase name'); + } + if (applauseCaseIds.length > 1) { + console.warn('Multiple Applause case ids detected in testCase name'); + } + return { + applauseTestCaseId: applauseCaseIds[0], + testRailTestCaseId: testRailCaseIds[0], + testCaseName: testCaseName + .replace(/(TestRail-\d+|Applause-\d+)/g, '') + .replace(/\s+/g, ' ') + .trim(), + }; +} + class ApplauseReporter { autoApi; initializer; @@ -372,37 +398,6 @@ class RunReporter { } } } -const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-'; -const APPLAUSE_CASE_ID_PREFIX = 'Applause-'; -function parseTestCaseName(testCaseName) { - // Split the name on spaces. We will reassemble after parsing out the other ids - const tokens = testCaseName.split(' '); - let testRailTestCaseId; - let applauseTestCaseId; - tokens.forEach(token => { - if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) { - if (testRailTestCaseId !== undefined) { - console.warn('Multiple TestRail case ids detected in testCase name'); - } - testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length); - } - else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) { - if (applauseTestCaseId !== undefined) { - console.warn('Multiple Applause case ids detected in testCase name'); - } - applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length); - } - }); - return { - applauseTestCaseId, - testRailTestCaseId, - testCaseName: tokens - .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`) - .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`) - .join(' ') - .trim(), - }; -} var TestRunAutoResultStatus; (function (TestRunAutoResultStatus) { diff --git a/dist/index.mjs.map b/dist/index.mjs.map index 2c0f91d..99fb136 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/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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\nexport const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n // Split the name on spaces. We will reassemble after parsing out the other ids\n const tokens = testCaseName.split(' ');\n let testRailTestCaseId;\n let applauseTestCaseId;\n tokens.forEach(token => {\n if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) {\n if (testRailTestCaseId !== undefined) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length);\n }\n else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) {\n if (applauseTestCaseId !== undefined) {\n console.warn('Multiple Applause case ids detected in testCase name');\n }\n applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length);\n }\n });\n return {\n applauseTestCaseId,\n testRailTestCaseId,\n testCaseName: tokens\n .filter(token => token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}`)\n .filter(token => token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}`)\n .join(' ')\n .trim(),\n };\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","pathJoin"],"mappings":"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"} \ No newline at end of file diff --git a/src/auto-api/reporter.ts b/src/auto-api/reporter.ts index 017f0d2..3e4001c 100644 --- a/src/auto-api/reporter.ts +++ b/src/auto-api/reporter.ts @@ -8,6 +8,7 @@ import { import { TestRunHeartbeatService } from './heartbeat.ts'; import { join as pathJoin } from 'path'; import { AutoApiConfig } from './auto-api-config.ts'; +import { parseTestCaseName } from '../shared/test-case.ts'; export class ApplauseReporter { private autoApi: AutoApi; @@ -173,46 +174,3 @@ export class RunReporter { } } } -export const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-'; -export const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-'; - -export function parseTestCaseName(testCaseName: string): ParsedTestCaseName { - // Split the name on spaces. We will reassemble after parsing out the other ids - const tokens = testCaseName.split(' '); - let testRailTestCaseId: string | undefined; - let applauseTestCaseId: string | undefined; - tokens.forEach(token => { - if (token?.startsWith(TEST_RAIL_CASE_ID_PREFIX)) { - if (testRailTestCaseId !== undefined) { - console.warn('Multiple TestRail case ids detected in testCase name'); - } - testRailTestCaseId = token.substring(TEST_RAIL_CASE_ID_PREFIX.length); - } else if (token?.startsWith(APPLAUSE_CASE_ID_PREFIX)) { - if (applauseTestCaseId !== undefined) { - console.warn('Multiple Applause case ids detected in testCase name'); - } - applauseTestCaseId = token.substring(APPLAUSE_CASE_ID_PREFIX.length); - } - }); - return { - applauseTestCaseId, - testRailTestCaseId, - testCaseName: tokens - .filter( - token => - token !== `${TEST_RAIL_CASE_ID_PREFIX}${testRailTestCaseId || ''}` - ) - .filter( - token => - token !== `${APPLAUSE_CASE_ID_PREFIX}${applauseTestCaseId || ''}` - ) - .join(' ') - .trim(), - }; -} - -interface ParsedTestCaseName { - testCaseName: string; - testRailTestCaseId?: string; - applauseTestCaseId?: string; -} diff --git a/src/index.ts b/src/index.ts index 317c871..b823842 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ export * from './auto-api/index.ts'; export * from './public-api/index.ts'; export * from './config/config.ts'; +export * from './shared/index.ts'; diff --git a/src/public-api/dto.ts b/src/public-api/dto.ts index 4fc0b37..a422c0d 100644 --- a/src/public-api/dto.ts +++ b/src/public-api/dto.ts @@ -2,7 +2,7 @@ export interface TestRunAutoResultDto { testCycleId: number; status: TestRunAutoResultStatus; failureReason?: string; - sessionDetailsJson?: object; + sessionDetailsJson?: SessionDetails; startTime?: Date; endTime?: Date; } @@ -14,3 +14,14 @@ export enum TestRunAutoResultStatus { CANCELED = 'CANCELED', ERROR = 'ERROR', } + +export interface SessionDetails { + value: { + deviceName?: string; + orientation?: string; + platformName?: string; + platformVersion?: string; + browserName?: string; + browserVersion?: string; + }; +} diff --git a/src/shared/index.ts b/src/shared/index.ts new file mode 100644 index 0000000..6e0d833 --- /dev/null +++ b/src/shared/index.ts @@ -0,0 +1 @@ +export * from './test-case.ts'; diff --git a/src/shared/test-case.ts b/src/shared/test-case.ts new file mode 100644 index 0000000..b59cd80 --- /dev/null +++ b/src/shared/test-case.ts @@ -0,0 +1,35 @@ +export const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-'; +export const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-'; + +export function parseTestCaseName(testCaseName: string): ParsedTestCaseName { + const matches = testCaseName.match(/(TestRail-\d+|Applause-\d+)/g); + const testRailCaseIds = + matches + ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX)) + .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) || []; + const applauseCaseIds = + matches + ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX)) + .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || []; + + if (testRailCaseIds.length > 1) { + console.warn('Multiple TestRail case ids detected in testCase name'); + } + if (applauseCaseIds.length > 1) { + console.warn('Multiple Applause case ids detected in testCase name'); + } + return { + applauseTestCaseId: applauseCaseIds[0], + testRailTestCaseId: testRailCaseIds[0], + testCaseName: testCaseName + .replace(/(TestRail-\d+|Applause-\d+)/g, '') + .replace(/\s+/g, ' ') + .trim(), + }; +} + +export interface ParsedTestCaseName { + testCaseName: string; + testRailTestCaseId?: string; + applauseTestCaseId?: string; +} diff --git a/test/test-case.test.ts b/test/test-case.test.ts new file mode 100644 index 0000000..bdac57c --- /dev/null +++ b/test/test-case.test.ts @@ -0,0 +1,59 @@ +import { parseTestCaseName, ParsedTestCaseName } from '../src/shared/test-case.ts'; + +describe('parseTestCaseName', () => { + it('should parse a test case name without any prefixes', () => { + const testCaseName = 'My Test Case'; + const parsedTestCaseName: ParsedTestCaseName = parseTestCaseName(testCaseName); + expect(parsedTestCaseName.testCaseName).toEqual(testCaseName); + expect(parsedTestCaseName.testRailTestCaseId).toBeUndefined(); + expect(parsedTestCaseName.applauseTestCaseId).toBeUndefined(); + }); + + it('should parse a test case name with TestRail prefix', () => { + const testCaseName = 'TestRail-123 My Test Case'; + const parsedTestCaseName: ParsedTestCaseName = parseTestCaseName(testCaseName); + expect(parsedTestCaseName.testCaseName).toEqual('My Test Case'); + expect(parsedTestCaseName.testRailTestCaseId).toEqual('123'); + expect(parsedTestCaseName.applauseTestCaseId).toBeUndefined(); + }); + + it('should parse a test case name with Applause prefix', () => { + const testCaseName = 'Applause-456 My Test Case'; + const parsedTestCaseName: ParsedTestCaseName = parseTestCaseName(testCaseName); + expect(parsedTestCaseName.testCaseName).toEqual('My Test Case'); + expect(parsedTestCaseName.testRailTestCaseId).toBeUndefined(); + expect(parsedTestCaseName.applauseTestCaseId).toEqual('456'); + }); + + it('should parse a test case name with both TestRail and Applause prefixes', () => { + const testCaseName = 'TestRail-123 Applause-456 My Test Case'; + const parsedTestCaseName: ParsedTestCaseName = parseTestCaseName(testCaseName); + expect(parsedTestCaseName.testCaseName).toEqual('My Test Case'); + expect(parsedTestCaseName.testRailTestCaseId).toEqual('123'); + expect(parsedTestCaseName.applauseTestCaseId).toEqual('456'); + }); + + it('should parse a test case name with both TestRail and Applause prefixes, with no spaces between', () => { + const testCaseName = 'TestRail-123Applause-456 My Test Case'; + const parsedTestCaseName: ParsedTestCaseName = parseTestCaseName(testCaseName); + expect(parsedTestCaseName.testCaseName).toEqual('My Test Case'); + expect(parsedTestCaseName.testRailTestCaseId).toEqual('123'); + expect(parsedTestCaseName.applauseTestCaseId).toEqual('456'); + }); + + it('should parse a test case name with test case ids at the end of the test case name', () => { + const testCaseName = 'My Test Case TestRail-123'; + const parsedTestCaseName: ParsedTestCaseName = parseTestCaseName(testCaseName); + expect(parsedTestCaseName.testCaseName).toEqual('My Test Case'); + expect(parsedTestCaseName.testRailTestCaseId).toEqual('123'); + expect(parsedTestCaseName.applauseTestCaseId).toBeUndefined(); + }); + + it('should parse a test case name with test case ids in the middle of the test case name', () => { + const testCaseName = 'My Test Case TestRail-123 Another Test Case'; + const parsedTestCaseName: ParsedTestCaseName = parseTestCaseName(testCaseName); + expect(parsedTestCaseName.testCaseName).toEqual('My Test Case Another Test Case'); + expect(parsedTestCaseName.testRailTestCaseId).toEqual('123'); + expect(parsedTestCaseName.applauseTestCaseId).toBeUndefined(); + }); +}); \ No newline at end of file From f43087f3bf8422773ec3b2f3f833a81784c8fc94 Mon Sep 17 00:00:00 2001 From: rconner46 Date: Thu, 1 Aug 2024 11:14:34 -0500 Subject: [PATCH 3/6] Fix Auto-API Error Logging --- dist/index.cjs | 8 +++----- dist/index.cjs.map | 2 +- dist/index.min.js | 2 +- dist/index.min.js.map | 2 +- dist/index.mjs | 8 +++----- dist/index.mjs.map | 2 +- src/auto-api/auto-api.ts | 12 +++++------- 7 files changed, 15 insertions(+), 21 deletions(-) diff --git a/dist/index.cjs b/dist/index.cjs index 0f6ea0b..335bb8b 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -69,11 +69,9 @@ class AutoApi { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data !== undefined - ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data - : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - `error-code [${error.response.status}] with error [${error.response.statusText}]`; + error.response?.data !== undefined + ? JSON.stringify(error.response.data) + : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; console.error(`Auto-Api returned ${errText}`); return Promise.reject(error); }); diff --git a/dist/index.cjs.map b/dist/index.cjs.map index f1a121f..3b74d46 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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","TestResultStatus","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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\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 console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","TestResultStatus","simpleParser","writeFileSync","pathJoin","TestRunAutoResultStatus","existsSync","readFileSync"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.min.js b/dist/index.min.js index 8ec3b83..0a8c139 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("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,a,r){"use strict";const n=s.default,o={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function l(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!n.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(n.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}class u{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,l(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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.0.0",productId:this.options.productId,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}}}var p;t.TestResultStatus=void 0,(p=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",p.IN_PROGRESS="IN_PROGRESS",p.PASSED="PASSED",p.FAILED="FAILED",p.SKIPPED="SKIPPED",p.CANCELED="CANCELED",p.ERROR="ERROR";class d{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await i.simpleParser(t.data)}}class c{testRunId;autoApi;enabled=!1;nextHeartbeat;constructor(t,e){this.testRunId=t,this.autoApi=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(){console.log("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),console.log("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,console.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,console.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}const h="TestRail-",R="Applause-";function I(t){const e=t.match(/(TestRail-\d+|Applause-\d+)/g),s=e?.filter((t=>t.startsWith(h))).map((t=>t.substring(9)))||[],i=e?.filter((t=>t.startsWith(R))).map((t=>t.substring(9)))||[];return s.length>1&&console.warn("Multiple TestRail case ids detected in testCase name"),i.length>1&&console.warn("Multiple Applause case ids detected in testCase name"),{applauseTestCaseId:i[0],testRailTestCaseId:s[0],testCaseName:t.replace(/(TestRail-\d+|Applause-\d+)/g,"").replace(/\s+/g," ").trim()}}class g{autoApi;constructor(t){this.autoApi=t}async initializeRun(t){const e=t?.map(I).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e||[]});if(s.status<200||s.status>300)throw new Error("Unable to create test run");const i=s.data.runId;console.log("Test Run %d initialized",i);const a=new c(i,this.autoApi);return await a.start(),new f(this.autoApi,i,a)}}class f{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};constructor(t,e,s){this.autoApi=t,this.testRunId=e,this.heartbeatService=s}startTestCase(t,e,s){const i=I(e);this.uidToResultIdMap[t]=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))}submitTestCaseResult(t,e,s){this.resultSubmissionMap[t]=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s})))}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){console.info(JSON.stringify(e));const t=".";a.writeFileSync(r.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}var m;t.TestRunAutoResultStatus=void 0,(m=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",m.FAILED="FAILED",m.SKIPPED="SKIPPED",m.CANCELED="CANCELED",m.ERROR="ERROR";const A=s.default,w={publicApiBaseUrl:"https://api.applause.com/"};function b(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!A.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(A.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function y(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e||{}).filter((([t,e])=>void 0!==e))))}function T(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 E(t){const e=t||process.cwd()+"/applause.json";if(!a.existsSync(e))return{};const s=a.readFileSync(e,"utf8");return JSON.parse(s)}function v(t){l(t),b(t)}t.APPLAUSE_CASE_ID_PREFIX=R,t.ApplauseReporter=class{autoApi;initializer;reporter;runStarted=!1;runFinished=!1;constructor(t){this.autoApi=new u(t),this.initializer=new g(this.autoApi)}runnerStart(t){this.reporter=this.initializer.initializeRun(t),this.reporter.then((()=>{this.runStarted=!0}))}startTestCase(t,e,s){if(void 0===this.reporter)throw new Error("Cannot start a test case for a run that was never initialized");this.reporter.then((i=>i.startTestCase(t,e,s)))}submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw new Error("Cannot submit test case result for a run that was never initialized");this.reporter.then((i=>i.submitTestCaseResult(t,e,s)))}async runnerEnd(){if(void 0===this.reporter)throw new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.AutoApi=u,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new d(e,this.autoApi)}},t.Inbox=d,t.PublicApi=class{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,b(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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=g,t.RunReporter=f,t.TEST_RAIL_CASE_ID_PREFIX=h,t.TestRunHeartbeatService=c,t.isComplete=T,t.loadConfig=function(t){let e={...w,...o};if(e=void 0!==t&&void 0!==t.configFile?y(e,E(r.join(process.cwd(),t.configFile))):y(e,E()),void 0!==t&&void 0!==t.properties&&(e=y(e,t.properties)),!T(e))throw new Error("Config is not complete");const s=e;return v(s),s},t.loadConfigFromFile=E,t.overrideConfig=y,t.parseTestCaseName=I,t.validateConfig=v,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("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,a,r){"use strict";const n=s.default,o={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function l(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!n.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(n.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}class u{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,l(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}),(function(t){const e=void 0!==t.response?.data?JSON.stringify(t.response.data):`error-code [${t.response?.status}] with error [${t.response?.statusText}]`;return console.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.0.0",productId:this.options.productId,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}}}var p;t.TestResultStatus=void 0,(p=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",p.IN_PROGRESS="IN_PROGRESS",p.PASSED="PASSED",p.FAILED="FAILED",p.SKIPPED="SKIPPED",p.CANCELED="CANCELED",p.ERROR="ERROR";class d{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await i.simpleParser(t.data)}}class c{testRunId;autoApi;enabled=!1;nextHeartbeat;constructor(t,e){this.testRunId=t,this.autoApi=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(){console.log("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),console.log("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,console.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,console.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}const h="TestRail-",R="Applause-";function I(t){const e=t.match(/(TestRail-\d+|Applause-\d+)/g),s=e?.filter((t=>t.startsWith(h))).map((t=>t.substring(9)))||[],i=e?.filter((t=>t.startsWith(R))).map((t=>t.substring(9)))||[];return s.length>1&&console.warn("Multiple TestRail case ids detected in testCase name"),i.length>1&&console.warn("Multiple Applause case ids detected in testCase name"),{applauseTestCaseId:i[0],testRailTestCaseId:s[0],testCaseName:t.replace(/(TestRail-\d+|Applause-\d+)/g,"").replace(/\s+/g," ").trim()}}class g{autoApi;constructor(t){this.autoApi=t}async initializeRun(t){const e=t?.map(I).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e||[]});if(s.status<200||s.status>300)throw new Error("Unable to create test run");const i=s.data.runId;console.log("Test Run %d initialized",i);const a=new c(i,this.autoApi);return await a.start(),new f(this.autoApi,i,a)}}class f{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};constructor(t,e,s){this.autoApi=t,this.testRunId=e,this.heartbeatService=s}startTestCase(t,e,s){const i=I(e);this.uidToResultIdMap[t]=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))}submitTestCaseResult(t,e,s){this.resultSubmissionMap[t]=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s})))}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){console.info(JSON.stringify(e));const t=".";a.writeFileSync(r.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}var m;t.TestRunAutoResultStatus=void 0,(m=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",m.FAILED="FAILED",m.SKIPPED="SKIPPED",m.CANCELED="CANCELED",m.ERROR="ERROR";const A=s.default,w={publicApiBaseUrl:"https://api.applause.com/"};function b(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!A.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(A.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function y(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e||{}).filter((([t,e])=>void 0!==e))))}function T(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 E(t){const e=t||process.cwd()+"/applause.json";if(!a.existsSync(e))return{};const s=a.readFileSync(e,"utf8");return JSON.parse(s)}function v(t){l(t),b(t)}t.APPLAUSE_CASE_ID_PREFIX=R,t.ApplauseReporter=class{autoApi;initializer;reporter;runStarted=!1;runFinished=!1;constructor(t){this.autoApi=new u(t),this.initializer=new g(this.autoApi)}runnerStart(t){this.reporter=this.initializer.initializeRun(t),this.reporter.then((()=>{this.runStarted=!0}))}startTestCase(t,e,s){if(void 0===this.reporter)throw new Error("Cannot start a test case for a run that was never initialized");this.reporter.then((i=>i.startTestCase(t,e,s)))}submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw new Error("Cannot submit test case result for a run that was never initialized");this.reporter.then((i=>i.submitTestCaseResult(t,e,s)))}async runnerEnd(){if(void 0===this.reporter)throw new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.AutoApi=u,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new d(e,this.autoApi)}},t.Inbox=d,t.PublicApi=class{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,b(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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=g,t.RunReporter=f,t.TEST_RAIL_CASE_ID_PREFIX=h,t.TestRunHeartbeatService=c,t.isComplete=T,t.loadConfig=function(t){let e={...w,...o};if(e=void 0!==t&&void 0!==t.configFile?y(e,E(r.join(process.cwd(),t.configFile))):y(e,E()),void 0!==t&&void 0!==t.properties&&(e=y(e,t.properties)),!T(e))throw new Error("Config is not complete");const s=e;return v(s),s},t.loadConfigFromFile=E,t.overrideConfig=y,t.parseTestCaseName=I,t.validateConfig=v,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 ad4392d..63450e8 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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map"],"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","AutoApi","options","client","callsInFlight","getCallsInFlight","this","constructor","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","status","statusText","console","Promise","reject","startTestRun","info","post","sdkVersion","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","TestResultStatus","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","log","debug","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","parseTestCaseName","testCaseName","matches","match","testRailCaseIds","startsWith","map","substring","applauseCaseIds","length","warn","applauseTestCaseId","testRailTestCaseId","replace","trim","RunInitializer","initializeRun","tests","cleanedTests","parsed","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","testCaseId","itwTestCaseId","Object","fromEntries","entries","_","v","testResultId","resultId","runnerEnd","all","values","jsonArray","JSON","stringify","outputPath","writeFileSync","pathJoin","join","TestRunAutoResultStatus","DEFAULT_PUBLIC_API_PROPERTIES","publicApiBaseUrl","validatePublicApiConfig","overrideConfig","overrides","assign","isComplete","isAutoApiConfigComplete","isPublicApiConfigComplete","loadConfigFromFile","configFile","configFilePath","process","cwd","existsSync","fileCotents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","runnerStart","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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\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 console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map"],"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","AutoApi","options","client","callsInFlight","getCallsInFlight","this","constructor","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","JSON","stringify","status","statusText","console","Promise","reject","startTestRun","info","post","sdkVersion","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","TestResultStatus","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","log","debug","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","parseTestCaseName","testCaseName","matches","match","testRailCaseIds","startsWith","map","substring","applauseCaseIds","length","warn","applauseTestCaseId","testRailTestCaseId","replace","trim","RunInitializer","initializeRun","tests","cleanedTests","parsed","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","testCaseId","itwTestCaseId","Object","fromEntries","entries","_","v","testResultId","resultId","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","fileCotents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","runnerStart","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 ed025c1..54fdd0c 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -67,11 +67,9 @@ class AutoApi { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data !== undefined - ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data - : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - `error-code [${error.response.status}] with error [${error.response.statusText}]`; + error.response?.data !== undefined + ? JSON.stringify(error.response.data) + : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; console.error(`Auto-Api returned ${errText}`); return Promise.reject(error); }); diff --git a/dist/index.mjs.map b/dist/index.mjs.map index 99fb136..0dc0987 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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\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 console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"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 09be203..d6d9540 100644 --- a/src/auto-api/auto-api.ts +++ b/src/auto-api/auto-api.ts @@ -1,4 +1,4 @@ -import axios, { AxiosInstance, AxiosResponse } from 'axios'; +import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; import { CreateTestCaseResultDto, CreateTestCaseResultResponseDto, @@ -39,15 +39,13 @@ export class AutoApi { function (response: AxiosResponse) { return response; }, - function (error) { + function (error: AxiosError) { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data !== undefined - ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data - : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - `error-code [${error.response.status}] with error [${error.response.statusText}]`; + error.response?.data !== undefined + ? JSON.stringify(error.response.data) + : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; console.error(`Auto-Api returned ${errText}`); return Promise.reject(error); } From a9eda1367913d6b90725bf64854b343560096c4f Mon Sep 17 00:00:00 2001 From: rconner46 Date: Thu, 11 Jul 2024 09:22:03 -0400 Subject: [PATCH 4/6] Allow for asset upload --- README.md | 74 +- dist/index.cjs | 531 +++++- dist/index.cjs.map | 2 +- dist/index.d.ts | 346 +++- dist/index.min.js | 2 +- dist/index.min.js.map | 2 +- dist/index.mjs | 509 +++++- dist/index.mjs.map | 2 +- package.json | 5 +- src/auto-api/auto-api.ts | 102 +- src/auto-api/dto.ts | 22 + src/auto-api/email-helper.ts | 9 + src/auto-api/email/attachment.ts | 10 + src/auto-api/email/inbox.ts | 12 + src/auto-api/heartbeat.ts | 40 +- src/auto-api/reporter.ts | 280 ++- src/auto-api/version.ts | 2 +- src/config/config.ts | 47 +- src/public-api/public-api.ts | 23 +- src/shared/index.ts | 1 + src/shared/logging.ts | 102 ++ src/shared/test-case.ts | 19 +- test/logging.test.ts | 128 ++ tsconfig.json | 1 + yarn.lock | 2852 +++++++++++++++--------------- 25 files changed, 3483 insertions(+), 1640 deletions(-) create mode 100644 src/shared/logging.ts create mode 100644 test/logging.test.ts diff --git a/README.md b/README.md index 573cfc3..d5d7c36 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,25 @@ -# Client API for automation backend -Used by reporter integrations for JS test frameworks. +# Applause Automation API Access -Written in TypeScript, transpiled to JS for NPM packaging using Rollup +This project contains a shared interface into the Applause Automation API for JS/TS projects that need to communicate with the Applause Services. Each testing framework +requires a custom integration to handle adding these methods into the correct hooks provided by the framework. These methods can also be called manually if a custom integration +is needed. -creates NPM package in /dist folder in ES, UMD, and CJS module formats +## Implementations -also publishes Typescript types and sourcemaps into NPM package +You can find the following reporter interfaces to be used with their corresponding JS/TS Test Runners: +- wdio-applause-reporter: https://github.com/ApplauseOSS/wdio-applause-reporter +- jest-applause-reporter: https://github.com/ApplauseOSS/jest-applause-reporter +- mocha-applause-reporter: https://github.com/ApplauseOSS/mocha-applause-reporter +- cucumber-applause-reporter: https://github.com/ApplauseOSS/cucumber-applause-reporter -runs tests using Node and Jest +## Requirements: +- Node 20.x +- TypeScript -Configured for Node 14+ . To update, change base tsconfig from "extends": "@tsconfig/node14/tsconfig.json", update "engines" section in package.json, and update .node-version file -# Running -Use `yarn run all` . It will configure and run all the build steps +## Running -## Run through local dev setup and build +### Run through local dev setup and build `yarn all` @@ -34,7 +39,52 @@ Use `yarn run all` . It will configure and run all the build steps `yarn lint` -## Publishing +### Publishing `yarn publish-verify` -CI will do actual pubish on merge +## Implementation Information + +### Applause Shared Reporter +The file reporter.ts contains the implementation of the ApplauseReporter class, which serves as a reporter for the Applause testing framework. This class provides methods to interact with the Applause API and perform various actions related to test runs, test cases, and test case results. + +Here's a breakdown of the key components and functionalities of the ApplauseReporter class: + +#### startTestCase(...) Method: + +Starts a test case by calling the startTestCase method on the reporter property. +If the reporter property is undefined, it throws an error indicating that a run was never initialized. +Returns a promise that resolves to the testCaseId. + +#### submitTestCaseResult Method: + +Submits a test case result by calling the submitTestCaseResult method on the reporter property. +If the reporter property is undefined, it throws an error indicating that a run was never initialized. +Returns a promise that resolves to the testCaseResultId. + +#### runnerEnd Method: + +Ends the Applause runner by calling the runnerEnd method on the reporter property. +If the reporter property is undefined, it throws an error indicating that a run was never initialized. +Returns a promise that resolves when the runner is ended. + +#### attachTestCaseAsset Method: + +Attaches an asset to a test case by calling the attachTestCaseAsset method on the reporter property. +If the reporter property is undefined, it throws an error indicating that a run was never initialized. +Returns a promise that resolves when the asset is attached. + +#### isSynchronized Method: + +Checks if the Applause runner is synchronized by verifying if the run has started and finished, and if there are no pending API calls. +Returns true if the runner is not yet started or has ended, and all calls made to the Applause API have finished. + +Overall, the ApplauseReporter class provides a convenient interface for interacting with the Applause testing framework, allowing you to start test runs, manage test cases, submit test case results, attach assets, and check the synchronization status of the runner. + +### Email Testing + +The file email-helper.ts, along with the src/email/** directory contains the implementation of our email helper utilities. It handes allocating an email address from the applause services for testing and fetching emails from it. We utilize the 'mailparser' dependency for interacting with the email content. + + +### Logging Integration + +The file logging.ts offers a winston Transport class that allows the Applause reporter to gain access to log messages from the tests. These get stored as assets attched to the test results in the Applause automation service. diff --git a/dist/index.cjs b/dist/index.cjs index 335bb8b..136114d 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -2,11 +2,32 @@ var axios = require('axios'); var Validator = require('validator'); +var winston = require('winston'); +var TransportStream = require('winston-transport'); var mailparser = require('mailparser'); var fs = require('fs'); var path = require('path'); -const API_VERSION = '1.0.0'; +function _interopNamespaceDefault(e) { + var n = Object.create(null); + if (e) { + Object.keys(e).forEach(function (k) { + if (k !== 'default') { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + } + n.default = e; + return Object.freeze(n); +} + +var winston__namespace = /*#__PURE__*/_interopNamespaceDefault(winston); + +const API_VERSION = '1.1.0'; const validator$1 = Validator.default; const DEFAULT_URL$1 = 'https://prod-auto-api.cloud.applause.com/'; @@ -24,7 +45,7 @@ function validateAutoApiConfig(config) { } if (!validator$1.isURL(config.autoApiBaseUrl, { protocols: ['http', 'https'], - require_tld: false, + require_tld: false, // allow localhost allow_query_components: false, disallow_auth: true, allow_fragments: false, @@ -40,19 +61,107 @@ function validateAutoApiConfig(config) { } } +const MESSAGE = Symbol.for('message'); +const WINSTON_DEFAULT_LOG_FORMAT = winston__namespace.format.printf(({ level, message, label, timestamp }) => { + return `${timestamp} [${label}] ${level}: ${message}`; +}); +function constructDefaultLogger() { + return winston__namespace.createLogger({ + format: winston__namespace.format.combine(winston__namespace.format.label({ label: 'Applause Tests' }), winston__namespace.format.timestamp(), winston__namespace.format.splat(), WINSTON_DEFAULT_LOG_FORMAT), + transports: [ + new winston__namespace.transports.File({ filename: 'error.log', level: 'error' }), + new winston__namespace.transports.File({ filename: 'combined.log' }), + new ApplauseTransport(), + new winston__namespace.transports.Console({ + level: 'info', + format: winston__namespace.format.combine(winston__namespace.format.colorize(), WINSTON_DEFAULT_LOG_FORMAT), + }), + ], + }); +} +/** + * A simple Class for storing and retrieving log messages. + */ +class LoggingContainer { + logs = []; + /** + * Retrieves all logs stored in the container. + * + * @returns An array of log messages. + */ + getLogs() { + return this.logs; + } + /** + * Retrieves and clears all logs stored in the container. + * + * @returns An array of log messages. + */ + drainLogs() { + const logs = this.logs; + this.clearLogs(); + return logs; + } + /** + * Clears all logs stored in the container. + */ + clearLogs() { + this.logs = []; + } + /** + * Adds a log message to the container. + * + * @param log - The log message to add. + */ + addLog(log) { + this.logs.push(log); + } +} +// Create a new Shared LoggingContainer to store logs +const APPLAUSE_LOG_RECORDS = new LoggingContainer(); +/** + * A Custom Winston Transport that sends logs to the Applause LoggingContainer + */ +class ApplauseTransport extends TransportStream { + constructor(opts) { + super(opts); + } + log(info, callback) { + setImmediate(() => { + this.emit('logged', info); + }); + this.format?.transform(info); + APPLAUSE_LOG_RECORDS.addLog(info[MESSAGE] ?? info.message); + // Continue to the next transport + callback(); + } +} + +/** + * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform. + * 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. + * It also includes properties and methods to track the number of HTTP calls in progress. + */ class AutoApi { options; client; + logger; callsInFlight; /** - * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + * Tracks the number of HTTP calls in progress. + * This property is used by reporters that want to know when the async work is finished. */ get getCallsInFlight() { return this.callsInFlight; } - constructor(options) { + /** + * Creates an instance of the `AutoApi` class. + * @param options - The configuration options for the Applause API. + */ + constructor(options, logger) { this.options = options; this.callsInFlight = 0; + this.logger = logger ?? constructDefaultLogger(); validateAutoApiConfig(options); this.client = axios.create({ baseURL: options.autoApiBaseUrl, @@ -65,17 +174,22 @@ class AutoApi { }); this.client.interceptors.response.use(function (response) { return response; - }, function (error) { + }, (error) => { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access error.response?.data !== undefined ? JSON.stringify(error.response.data) : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; - console.error(`Auto-Api returned ${errText}`); + this.logger.error(`Auto-Api returned ${errText}`); return Promise.reject(error); }); } + /** + * Starts a new test run. + * @param info - The information for creating the test run. + * @returns A promise that resolves to the response containing the created test run. + */ async startTestRun(info) { this.callsInFlight += 1; try { @@ -100,6 +214,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Ends a test run. + * @param testRunId - The ID of the test run to end. + * @returns A promise that resolves to the response indicating the completion of the test run. + */ async endTestRun(testRunId) { this.callsInFlight += 1; try { @@ -109,6 +228,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Starts a new test case. + * @param params - The parameters for creating the test case. + * @returns A promise that resolves to the response containing the created test case. + */ async startTestCase(params) { this.callsInFlight += 1; try { @@ -119,6 +243,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Submits a test case result. + * @param params - The parameters for submitting the test case result. + * @returns A promise that resolves when the test case result is submitted. + */ async submitTestCaseResult(params) { this.callsInFlight += 1; try { @@ -128,6 +257,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Retrieves the provider session links for the specified test results. + * @param resultIds - The IDs of the test results. + * @returns A promise that resolves to the response containing the provider session links. + */ async getProviderSessionLinks(resultIds) { this.callsInFlight += 1; try { @@ -139,6 +273,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Sends a heartbeat for the specified test run. + * @param testRunId - The ID of the test run. + * @returns A promise that resolves to the response indicating the heartbeat was sent. + */ async sendSdkHeartbeat(testRunId) { this.callsInFlight += 1; try { @@ -151,6 +290,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Retrieves the email address for the specified email prefix. + * @param emailPrefix - The prefix of the email address. + * @returns A promise that resolves to the response containing the email address. + */ async getEmailAddress(emailPrefix) { this.callsInFlight += 1; try { @@ -161,6 +305,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Retrieves the content of the specified email. + * @param request - The request parameters for retrieving the email content. + * @returns A promise that resolves to the response containing the email content. + */ async getEmailContent(request) { this.callsInFlight += 1; try { @@ -171,6 +320,30 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Uploads an asset for the specified test result. + * @param resultId - The ID of the test result. + * @param file - The file to upload as an asset. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The GUID of the provider session. + * @param assetType - The type of the asset. + * @returns A promise that resolves to the response indicating the asset was uploaded. + */ + async uploadAsset(resultId, file, assetName, providerSessionGuid, assetType) { + this.callsInFlight += 1; + try { + // this filters out falsy values (null, undefined, 0) + return await this.client.postForm(`/api/v1.0/test-result/${resultId}/upload`, { + file, + assetName, + providerSessionGuid, + assetType, + }); + } + finally { + this.callsInFlight -= 1; + } + } } /** @@ -186,14 +359,48 @@ exports.TestResultStatus = void 0; TestResultStatus["CANCELED"] = "CANCELED"; TestResultStatus["ERROR"] = "ERROR"; })(exports.TestResultStatus || (exports.TestResultStatus = {})); +exports.AssetType = void 0; +(function (AssetType) { + AssetType["SCREENSHOT"] = "SCREENSHOT"; + AssetType["FAILURE_SCREENSHOT"] = "FAILURE_SCREENSHOT"; + AssetType["VIDEO"] = "VIDEO"; + AssetType["NETWORK_HAR"] = "NETWORK_HAR"; + AssetType["VITALS_LOG"] = "VITALS_LOG"; + AssetType["CONSOLE_LOG"] = "CONSOLE_LOG"; + AssetType["NETWORK_LOG"] = "NETWORK_LOG"; + AssetType["DEVICE_LOG"] = "DEVICE_LOG"; + AssetType["SELENIUM_LOG"] = "SELENIUM_LOG"; + AssetType["SELENIUM_LOG_JSON"] = "SELENIUM_LOG_JSON"; + AssetType["BROWSER_LOG"] = "BROWSER_LOG"; + AssetType["FRAMEWORK_LOG"] = "FRAMEWORK_LOG"; + AssetType["EMAIL"] = "EMAIL"; + AssetType["PAGE_SOURCE"] = "PAGE_SOURCE"; + AssetType["CODE_BUNDLE"] = "CODE_BUNDLE"; + AssetType["RESULTS_ZIP"] = "RESULTS_ZIP"; + AssetType["SESSION_DETAILS"] = "SESSION_DETAILS"; + AssetType["DEVICE_DETAILS"] = "DEVICE_DETAILS"; + AssetType["UNKNOWN"] = "UNKNOWN"; +})(exports.AssetType || (exports.AssetType = {})); +/** + * Represents an email inbox. + */ class Inbox { emailAddress; autoApi; + /** + * Creates an instance of Inbox. + * @param emailAddress - The email address associated with the inbox. + * @param autoApi - An instance of the AutoApi class. + */ constructor(emailAddress, autoApi) { this.emailAddress = emailAddress; this.autoApi = autoApi; } + /** + * Retrieves the content of an email from the inbox. + * @returns A Promise that resolves to the parsed email content. + */ async getEmail() { const res = await this.autoApi.getEmailContent({ emailAddress: this.emailAddress, @@ -202,33 +409,60 @@ class Inbox { } } +/** + * Helper class for managing email functionality. + */ class EmailHelper { autoApi; constructor(autoApi) { this.autoApi = autoApi; } + /** + * Retrieves the inbox for the specified email prefix. + * + * @param emailPrefix - The prefix used to generate the email address. + * @returns A Promise that resolves to an Inbox object. + */ async getInbox(emailPrefix) { const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress; return new Inbox(generatedAddress, this.autoApi); } } +/** + * Represents a service for sending heartbeats during a test run. + */ class TestRunHeartbeatService { testRunId; autoApi; enabled = false; nextHeartbeat; - constructor(testRunId, autoApi) { + logger; + /** + * Creates an instance of TestRunHeartbeatService. + * @param testRunId - The ID of the test run. + * @param autoApi - The AutoApi instance used for sending heartbeats. + */ + constructor(testRunId, autoApi, logger) { this.testRunId = testRunId; this.autoApi = autoApi; + this.logger = logger ?? constructDefaultLogger(); } + /** + * Starts sending heartbeats. + * @returns A promise that resolves when the heartbeats are started. + */ async start() { // End the current heartbeat if it has started await this.end(); - // Set up va new interval + // Set up a new interval this.enabled = true; this.scheduleNextHeartbeat(); } + /** + * Checks if the heartbeats are enabled. + * @returns True if the heartbeats are enabled, false otherwise. + */ isEnabled() { return this.enabled; } @@ -239,17 +473,21 @@ class TestRunHeartbeatService { this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat()); } async sendHeartbeat() { - console.log('Sending heartbeat'); + this.logger.debug('Sending heartbeat'); await this.autoApi.sendSdkHeartbeat(this.testRunId); - console.log('Heartbeat sent'); + this.logger.debug('Heartbeat sent'); this.scheduleNextHeartbeat(); } + /** + * Ends the heartbeats. + * @returns A promise that resolves when the heartbeats are ended. + */ async end() { if (this.nextHeartbeat !== undefined) { this.enabled = false; - console.debug('Ending Applause SDK Heartbeat'); + this.logger.debug('Ending Applause SDK Heartbeat'); await this.nextHeartbeat; - console.debug('Applause SDK Heartbeat Ended Successfully'); + this.logger.debug('Applause SDK Heartbeat Ended Successfully'); } this.nextHeartbeat = undefined; } @@ -257,19 +495,19 @@ class TestRunHeartbeatService { const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-'; const APPLAUSE_CASE_ID_PREFIX = 'Applause-'; -function parseTestCaseName(testCaseName) { +function parseTestCaseName(testCaseName, logger) { const matches = testCaseName.match(/(TestRail-\d+|Applause-\d+)/g); const testRailCaseIds = matches ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX)) - .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) || []; + .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? []; const applauseCaseIds = matches ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX)) - .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || []; + .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? []; if (testRailCaseIds.length > 1) { - console.warn('Multiple TestRail case ids detected in testCase name'); + (logger ?? console).warn('Multiple TestRail case ids detected in testCase name'); } if (applauseCaseIds.length > 1) { - console.warn('Multiple Applause case ids detected in testCase name'); + (logger ?? console).warn('Multiple Applause case ids detected in testCase name'); } return { applauseTestCaseId: applauseCaseIds[0], @@ -281,85 +519,192 @@ function parseTestCaseName(testCaseName) { }; } +/** + * Represents an Applause reporter. + */ class ApplauseReporter { autoApi; initializer; + logger; reporter; runStarted = false; runFinished = false; - constructor(config) { - this.autoApi = new AutoApi(config); - this.initializer = new RunInitializer(this.autoApi); + /** + * Creates an instance of ApplauseReporter. + * @param config - The Applause configuration. + */ + constructor(config, logger) { + this.logger = logger ?? constructDefaultLogger(); + this.autoApi = new AutoApi(config, this.logger); + this.initializer = new RunInitializer(this.autoApi, this.logger); + const runId = process.env['APPLAUSE_RUN_ID']; + if (runId !== undefined) { + const r = new RunReporter(this.autoApi, parseInt(runId), undefined, this.logger); + this.reporter = new Promise(resolve => resolve(r)); + this.runStarted = true; + } } - runnerStart(tests) { + /** + * Starts the Applause runner. + * @param tests - Optional array of test names to run. + * @returns A promise that resolves to the test run ID. + * @throws Error if a run is already started or finished. + */ + async runnerStart(tests) { + if (this.reporter !== undefined) { + this.logger.error('Cannot start a run - run already started or run already finished'); + throw new Error('Cannot start a run - run already started or run already finished'); + } this.reporter = this.initializer.initializeRun(tests); - void this.reporter.then(() => { - this.runStarted = true; - }); + const initializedReporter = await this.reporter; + this.runStarted = true; + process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString(); + return initializedReporter.testRunId; } - startTestCase(id, testCaseName, params) { + /** + * Starts a test case. + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Optional additional parameters for the test case. + * @returns A promise that resolves to the test case ID. + * @throws Error if a run was never initialized. + */ + async startTestCase(id, testCaseName, params) { if (this.reporter === undefined) { + this.logger.error('Cannot start a test case for a run that was never initialized'); throw new Error('Cannot start a test case for a run that was never initialized'); } - void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params)); + const reporter = await this.reporter; + return reporter.startTestCase(id, testCaseName, params); } - submitTestCaseResult(id, status, params) { + /** + * Submits a test case result. + * @param id - The ID of the test case. + * @param status - The status of the test case result. + * @param params - Optional additional parameters for the test case result. + * @returns A promise that resolves to the test case result ID. + * @throws Error if a run was never initialized. + */ + async submitTestCaseResult(id, status, params) { if (this.reporter === undefined) { + this.logger.error('Cannot submit test case result for a run that was never initialized'); throw new Error('Cannot submit test case result for a run that was never initialized'); } - void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params)); + const reporter = await this.reporter; + return reporter.submitTestCaseResult(id, status, params); } + /** + * Ends the Applause runner. + * @returns A promise that resolves when the runner is ended. + * @throws Error if a run was never initialized. + */ async runnerEnd() { if (this.reporter === undefined) { + this.logger.error('Cannot end a run that was never initialized'); throw new Error('Cannot end a run that was never initialized'); } await this.reporter .then(reporter => reporter.runnerEnd()) .then(() => (this.runFinished = true)); } + /** + * Attaches an asset to a test case. + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset data as a Buffer. + * @returns A promise that resolves when the asset is attached. + * @throws Error if a run was never initialized. + */ + async attachTestCaseAsset(id, assetName, providerSessionGuid, assetType, asset) { + if (this.reporter === undefined) { + this.logger.error('Cannot attach an asset for a run that was never initialized'); + throw new Error('Cannot attach an asset for a run that was never initialized'); + } + return await this.reporter.then(reporter => reporter.attachTestCaseAsset(id, assetName, providerSessionGuid, assetType, asset)); + } + /** + * Checks if the Applause runner is synchronized. + * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished. + */ isSynchronized() { - // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished return ((!this.runStarted || (this.runStarted && this.runFinished)) && this.autoApi.getCallsInFlight == 0); } } +/** + * Represents a Run Initializer. + */ class RunInitializer { autoApi; - constructor(autoApi) { + logger; + constructor(autoApi, logger) { this.autoApi = autoApi; + this.logger = logger ?? constructDefaultLogger(); } + /** + * Initializes a test run. + * @param tests - An optional array of test names to include in the run. + * @returns A promise that resolves to a RunReporter instance. + * @throws An error if unable to create the test run. + */ async initializeRun(tests) { const cleanedTests = tests - ?.map(parseTestCaseName) + ?.map(testName => parseTestCaseName(testName, this.logger)) .map(parsed => parsed.testCaseName.trim()); const testRunCreateResponse = await this.autoApi.startTestRun({ - tests: cleanedTests || [], + tests: cleanedTests ?? [], }); if (testRunCreateResponse.status < 200 || testRunCreateResponse.status > 300) { + this.logger.error(`Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`); throw new Error('Unable to create test run'); } const runId = testRunCreateResponse.data.runId; - console.log('Test Run %d initialized', runId); - const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi); + this.logger.info(`Test Run ${runId} initialized`); + const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi, this.logger); await heartbeatService.start(); - return new RunReporter(this.autoApi, runId, heartbeatService); + return new RunReporter(this.autoApi, runId, heartbeatService, this.logger); } } +/** + * Handles reporting test results to the Applause API. + */ class RunReporter { autoApi; testRunId; heartbeatService; uidToResultIdMap = {}; resultSubmissionMap = {}; - constructor(autoApi, testRunId, heartbeatService) { + logger; + /** + * Creates a new instance of the Reporter class. + * @param autoApi - The AutoApi instance. + * @param testRunId - The ID of the test run. + * @param heartbeatService - (Optional) The TestRunHeartbeatService instance. + */ + constructor(autoApi, testRunId, heartbeatService, logger) { this.autoApi = autoApi; this.testRunId = testRunId; this.heartbeatService = heartbeatService; + this.logger = logger ?? constructDefaultLogger(); } + /** + * Starts a test case and returns a promise that resolves to the test result ID. + * + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Additional parameters for the test case. + * @returns A promise that resolves to the test result ID. + */ startTestCase(id, testCaseName, params) { - const parsedTestCase = parseTestCaseName(testCaseName); - this.uidToResultIdMap[id] = this.autoApi + if (!testCaseName) { + this.logger.error('testCaseName is required'); + throw new Error('testCaseName is required'); + } + const parsedTestCase = parseTestCaseName(testCaseName, this.logger); + const submission = this.autoApi .startTestCase({ testCaseName: parsedTestCase.testCaseName, testCaseId: parsedTestCase.testRailTestCaseId, @@ -371,27 +716,58 @@ class RunReporter { .then(res => { return res.data.testResultId; }); + this.uidToResultIdMap[id] = submission; + return submission; } + /** + * Submits the result of a test case. + * + * @param id - The ID of the test case. + * @param status - The status of the test result. + * @param params - Additional parameters for the test result. + * @returns A promise that resolves to the result ID. + */ submitTestCaseResult(id, status, params) { - this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({ + const submission = this.uidToResultIdMap[id]?.then(resultId => this.autoApi + .submitTestCaseResult({ status: status, testResultId: resultId, ...params, - })); + }) + .then(() => resultId)); + this.resultSubmissionMap[id] = submission; + return submission; } + /** + * Attaches a test case asset to a result. + * + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset to attach. + * @returns A promise that resolves when the asset is attached. + */ + async attachTestCaseAsset(id, assetName, providerSessionGuid, assetType, asset) { + await this.uidToResultIdMap[id]?.then(resultId => this.autoApi.uploadAsset(resultId, asset, assetName, providerSessionGuid, assetType)); + } + /** + * Ends the test runner and performs necessary cleanup tasks. + * @returns A promise that resolves when the runner has ended. + */ async runnerEnd() { // Wait for all results to be created - const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || []; + const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) ?? []; // Wait for the results to be submitted void (await Promise.all(Object.values(this.resultSubmissionMap))); // Wait the heartbeat to be ended - void (await this.heartbeatService.end()); + void (await this.heartbeatService?.end()); void (await this.autoApi.endTestRun(this.testRunId)); // Fetch the provider session asset links and save them off to a file const resp = await this.autoApi.getProviderSessionLinks(resultIds); - const jsonArray = resp.data || []; + const jsonArray = resp.data ?? []; if (jsonArray.length > 0) { - console.info(JSON.stringify(jsonArray)); + this.logger.info(JSON.stringify(jsonArray)); // this is the wdio.conf outputDir const outputPath = '.'; fs.writeFileSync(path.join(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1)); @@ -424,7 +800,7 @@ function validatePublicApiConfig(config) { } if (!validator.isURL(config.publicApiBaseUrl, { protocols: ['http', 'https'], - require_tld: false, + require_tld: false, // allow localhost allow_query_components: false, disallow_auth: true, allow_fragments: false, @@ -444,15 +820,17 @@ class PublicApi { options; client; callsInFlight; + logger; /** * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished */ get getCallsInFlight() { return this.callsInFlight; } - constructor(options) { + constructor(options, logger) { this.options = options; this.callsInFlight = 0; + this.logger = logger ?? constructDefaultLogger(); validatePublicApiConfig(options); this.client = axios.create({ baseURL: options.publicApiBaseUrl, @@ -465,16 +843,14 @@ class PublicApi { }); this.client.interceptors.response.use(function (response) { return response; - }, function (error) { + }, (error) => { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data !== undefined - ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data - : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - `error-code [${error.response.status}] with error [${error.response.statusText}]`; - console.error(`Public-Api returned ${errText}`); + error.response?.data !== undefined + ? JSON.stringify(error.response.data) + : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; + this.logger.error(`Public-Api returned ${errText}`); return Promise.reject(error); }); } @@ -489,7 +865,15 @@ class PublicApi { } } -// Loads the configuration +/** + * Represents the configuration options for the Applause Reporter. + */ +/** + * Loads the configuration for the Applause Reporter. + * @param loadOptions - The options for loading the configuration. + * @returns The loaded Applause configuration. + * @throws Error if the configuration is not complete or invalid. + */ function loadConfig(loadOptions) { // Setup the initial config with any default properties let config = { @@ -516,24 +900,50 @@ function loadConfig(loadOptions) { validateConfig(finalConfig); return finalConfig; } +/** + * Overrides the configuration with the provided overrides. + * @param config - The base configuration. + * @param overrides - The overrides to apply. + * @returns The overridden configuration. + */ function overrideConfig(config, overrides) { - return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined))); + return Object.assign({}, config, Object.fromEntries(Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined))); } +/** + * Checks if the configuration is complete. + * @param config - The configuration to check. + * @returns True if the configuration is complete, false otherwise. + */ function isComplete(config) { return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config); } +/** + * Loads the configuration from the specified file. + * @param configFile - The path to the configuration file. + * @returns The loaded configuration from the file. + */ function loadConfigFromFile(configFile) { - const configFilePath = configFile || process.cwd() + '/applause.json'; + const configFilePath = configFile ?? `${process.cwd()}/applause.json`; if (!fs.existsSync(configFilePath)) { return {}; } - const fileCotents = fs.readFileSync(configFilePath, 'utf8'); - return JSON.parse(fileCotents); + const fileContents = fs.readFileSync(configFilePath, 'utf8'); + return JSON.parse(fileContents); } +/** + * Validates the configuration. + * @param config - The configuration to validate. + * @throws Error if the configuration is invalid. + */ function validateConfig(config) { validateAutoApiConfig(config); validatePublicApiConfig(config); } +/** + * Validates a partial configuration. + * @param config - The partial configuration to validate. + * @throws Error if the partial configuration is invalid. + */ function validatePartialConfig(config) { if (config.productId !== undefined && (!Number.isInteger(config.productId) || config.productId <= 0)) { @@ -542,15 +952,20 @@ function validatePartialConfig(config) { } exports.APPLAUSE_CASE_ID_PREFIX = APPLAUSE_CASE_ID_PREFIX; +exports.APPLAUSE_LOG_RECORDS = APPLAUSE_LOG_RECORDS; exports.ApplauseReporter = ApplauseReporter; +exports.ApplauseTransport = ApplauseTransport; exports.AutoApi = AutoApi; exports.EmailHelper = EmailHelper; exports.Inbox = Inbox; +exports.LoggingContainer = LoggingContainer; exports.PublicApi = PublicApi; exports.RunInitializer = RunInitializer; exports.RunReporter = RunReporter; exports.TEST_RAIL_CASE_ID_PREFIX = TEST_RAIL_CASE_ID_PREFIX; exports.TestRunHeartbeatService = TestRunHeartbeatService; +exports.WINSTON_DEFAULT_LOG_FORMAT = WINSTON_DEFAULT_LOG_FORMAT; +exports.constructDefaultLogger = constructDefaultLogger; exports.isComplete = isComplete; exports.loadConfig = loadConfig; exports.loadConfigFromFile = loadConfigFromFile; diff --git a/dist/index.cjs.map b/dist/index.cjs.map index 3b74d46..1c700af 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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\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 console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"names":["validator","DEFAULT_URL","TestResultStatus","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 // 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 // Optional: an applause test cycle id\n itwTestCycleId?: number;\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 diff --git a/dist/index.d.ts b/dist/index.d.ts index 7fbadf1..14be0a0 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,5 +1,9 @@ import { AxiosResponse } from 'axios'; +import * as winston from 'winston'; +import winston__default from 'winston'; import { ParsedMail } from 'mailparser'; +import { TransformableInfo } from 'logform'; +import TransportStream from 'winston-transport'; /** * Configuration of the auto-api client @@ -95,6 +99,27 @@ interface EmailAddressResponse { interface EmailFetchRequest { emailAddress: string; } +declare enum AssetType { + SCREENSHOT = "SCREENSHOT", + FAILURE_SCREENSHOT = "FAILURE_SCREENSHOT", + VIDEO = "VIDEO", + NETWORK_HAR = "NETWORK_HAR", + VITALS_LOG = "VITALS_LOG", + CONSOLE_LOG = "CONSOLE_LOG", + NETWORK_LOG = "NETWORK_LOG", + DEVICE_LOG = "DEVICE_LOG", + SELENIUM_LOG = "SELENIUM_LOG", + SELENIUM_LOG_JSON = "SELENIUM_LOG_JSON", + BROWSER_LOG = "BROWSER_LOG", + FRAMEWORK_LOG = "FRAMEWORK_LOG", + EMAIL = "EMAIL", + PAGE_SOURCE = "PAGE_SOURCE", + CODE_BUNDLE = "CODE_BUNDLE", + RESULTS_ZIP = "RESULTS_ZIP", + SESSION_DETAILS = "SESSION_DETAILS", + DEVICE_DETAILS = "DEVICE_DETAILS", + UNKNOWN = "UNKNOWN" +} interface AutoApiConfig { readonly autoApiBaseUrl: string; @@ -104,83 +129,297 @@ interface AutoApiConfig { readonly applauseTestCycleId?: number; } +/** + * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform. + * 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. + * It also includes properties and methods to track the number of HTTP calls in progress. + */ + declare class AutoApi { readonly options: AutoApiConfig; private readonly client; + private logger; private callsInFlight; /** - * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + * Tracks the number of HTTP calls in progress. + * This property is used by reporters that want to know when the async work is finished. */ get getCallsInFlight(): number; - constructor(options: AutoApiConfig); + /** + * Creates an instance of the `AutoApi` class. + * @param options - The configuration options for the Applause API. + */ + constructor(options: AutoApiConfig, logger?: winston.Logger); + /** + * Starts a new test run. + * @param info - The information for creating the test run. + * @returns A promise that resolves to the response containing the created test run. + */ startTestRun(info: TestRunCreateDto): Promise>; + /** + * Ends a test run. + * @param testRunId - The ID of the test run to end. + * @returns A promise that resolves to the response indicating the completion of the test run. + */ endTestRun(testRunId: number): Promise>; + /** + * Starts a new test case. + * @param params - The parameters for creating the test case. + * @returns A promise that resolves to the response containing the created test case. + */ startTestCase(params: CreateTestCaseResultDto): Promise>; + /** + * Submits a test case result. + * @param params - The parameters for submitting the test case result. + * @returns A promise that resolves when the test case result is submitted. + */ submitTestCaseResult(params: SubmitTestCaseResultDto): Promise; + /** + * Retrieves the provider session links for the specified test results. + * @param resultIds - The IDs of the test results. + * @returns A promise that resolves to the response containing the provider session links. + */ getProviderSessionLinks(resultIds: number[]): Promise>; + /** + * Sends a heartbeat for the specified test run. + * @param testRunId - The ID of the test run. + * @returns A promise that resolves to the response indicating the heartbeat was sent. + */ sendSdkHeartbeat(testRunId: number): Promise>; + /** + * Retrieves the email address for the specified email prefix. + * @param emailPrefix - The prefix of the email address. + * @returns A promise that resolves to the response containing the email address. + */ getEmailAddress(emailPrefix: string): Promise>; + /** + * Retrieves the content of the specified email. + * @param request - The request parameters for retrieving the email content. + * @returns A promise that resolves to the response containing the email content. + */ getEmailContent(request: EmailFetchRequest): Promise>; + /** + * Uploads an asset for the specified test result. + * @param resultId - The ID of the test result. + * @param file - The file to upload as an asset. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The GUID of the provider session. + * @param assetType - The type of the asset. + * @returns A promise that resolves to the response indicating the asset was uploaded. + */ + uploadAsset(resultId: number, file: Buffer, assetName: string, providerSessionGuid: string, assetType: AssetType): Promise>; } +/** + * Represents an email inbox. + */ declare class Inbox { readonly emailAddress: string; private autoApi; + /** + * Creates an instance of Inbox. + * @param emailAddress - The email address associated with the inbox. + * @param autoApi - An instance of the AutoApi class. + */ constructor(emailAddress: string, autoApi: AutoApi); + /** + * Retrieves the content of an email from the inbox. + * @returns A Promise that resolves to the parsed email content. + */ getEmail(): Promise; } +/** + * Represents an email attachment. + */ interface Attachment { + /** + * The name of the file. + */ fileName: string; + /** + * The content of the file as a Uint16Array. + */ context: Uint16Array; } +/** + * Helper class for managing email functionality. + */ declare class EmailHelper { private autoApi; constructor(autoApi: AutoApi); + /** + * Retrieves the inbox for the specified email prefix. + * + * @param emailPrefix - The prefix used to generate the email address. + * @returns A Promise that resolves to an Inbox object. + */ getInbox(emailPrefix: string): Promise; } +/** + * Represents a service for sending heartbeats during a test run. + */ declare class TestRunHeartbeatService { readonly testRunId: number; readonly autoApi: AutoApi; private enabled; private nextHeartbeat?; - constructor(testRunId: number, autoApi: AutoApi); + private readonly logger; + /** + * Creates an instance of TestRunHeartbeatService. + * @param testRunId - The ID of the test run. + * @param autoApi - The AutoApi instance used for sending heartbeats. + */ + constructor(testRunId: number, autoApi: AutoApi, logger?: winston__default.Logger); + /** + * Starts sending heartbeats. + * @returns A promise that resolves when the heartbeats are started. + */ start(): Promise; + /** + * Checks if the heartbeats are enabled. + * @returns True if the heartbeats are enabled, false otherwise. + */ isEnabled(): boolean; private scheduleNextHeartbeat; private sendHeartbeat; + /** + * Ends the heartbeats. + * @returns A promise that resolves when the heartbeats are ended. + */ end(): Promise; } +/** + * Represents an Applause reporter. + */ declare class ApplauseReporter { private autoApi; private initializer; + private logger; private reporter?; private runStarted; private runFinished; - constructor(config: AutoApiConfig); - runnerStart(tests?: string[]): void; - startTestCase(id: string, testCaseName: string, params?: AdditionalTestCaseParams): void; - submitTestCaseResult(id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams): void; + /** + * Creates an instance of ApplauseReporter. + * @param config - The Applause configuration. + */ + constructor(config: AutoApiConfig, logger?: winston.Logger); + /** + * Starts the Applause runner. + * @param tests - Optional array of test names to run. + * @returns A promise that resolves to the test run ID. + * @throws Error if a run is already started or finished. + */ + runnerStart(tests?: string[]): Promise; + /** + * Starts a test case. + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Optional additional parameters for the test case. + * @returns A promise that resolves to the test case ID. + * @throws Error if a run was never initialized. + */ + startTestCase(id: string, testCaseName: string, params?: AdditionalTestCaseParams): Promise; + /** + * Submits a test case result. + * @param id - The ID of the test case. + * @param status - The status of the test case result. + * @param params - Optional additional parameters for the test case result. + * @returns A promise that resolves to the test case result ID. + * @throws Error if a run was never initialized. + */ + submitTestCaseResult(id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams): Promise; + /** + * Ends the Applause runner. + * @returns A promise that resolves when the runner is ended. + * @throws Error if a run was never initialized. + */ runnerEnd(): Promise; + /** + * Attaches an asset to a test case. + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset data as a Buffer. + * @returns A promise that resolves when the asset is attached. + * @throws Error if a run was never initialized. + */ + attachTestCaseAsset(id: string, assetName: string, providerSessionGuid: string, assetType: AssetType, asset: Buffer): Promise; + /** + * Checks if the Applause runner is synchronized. + * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished. + */ isSynchronized(): boolean; } +/** + * Represents a Run Initializer. + */ declare class RunInitializer { private autoApi; - constructor(autoApi: AutoApi); + private logger; + constructor(autoApi: AutoApi, logger?: winston.Logger); + /** + * Initializes a test run. + * @param tests - An optional array of test names to include in the run. + * @returns A promise that resolves to a RunReporter instance. + * @throws An error if unable to create the test run. + */ initializeRun(tests?: string[]): Promise; } +/** + * Handles reporting test results to the Applause API. + */ declare class RunReporter { private autoApi; - private testRunId; - private heartbeatService; + readonly testRunId: number; + private heartbeatService?; private uidToResultIdMap; private resultSubmissionMap; - constructor(autoApi: AutoApi, testRunId: number, heartbeatService: TestRunHeartbeatService); - startTestCase(id: string, testCaseName: string, params?: AdditionalTestCaseParams): void; - submitTestCaseResult(id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams): void; + private logger; + /** + * Creates a new instance of the Reporter class. + * @param autoApi - The AutoApi instance. + * @param testRunId - The ID of the test run. + * @param heartbeatService - (Optional) The TestRunHeartbeatService instance. + */ + constructor(autoApi: AutoApi, testRunId: number, heartbeatService?: TestRunHeartbeatService | undefined, logger?: winston.Logger); + /** + * Starts a test case and returns a promise that resolves to the test result ID. + * + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Additional parameters for the test case. + * @returns A promise that resolves to the test result ID. + */ + startTestCase(id: string, testCaseName: string, params?: AdditionalTestCaseParams): Promise; + /** + * Submits the result of a test case. + * + * @param id - The ID of the test case. + * @param status - The status of the test result. + * @param params - Additional parameters for the test result. + * @returns A promise that resolves to the result ID. + */ + submitTestCaseResult(id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams): Promise; + /** + * Attaches a test case asset to a result. + * + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset to attach. + * @returns A promise that resolves when the asset is attached. + */ + attachTestCaseAsset(id: string, assetName: string, providerSessionGuid: string, assetType: AssetType, asset: Buffer): Promise; + /** + * Ends the test runner and performs necessary cleanup tasks. + * @returns A promise that resolves when the runner has ended. + */ runnerEnd(): Promise; } @@ -221,33 +460,108 @@ declare class PublicApi { readonly options: PublicApiConfig; private readonly client; private callsInFlight; + private logger; /** * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished */ get getCallsInFlight(): number; - constructor(options: PublicApiConfig); + constructor(options: PublicApiConfig, logger?: winston.Logger); submitResult(testCaseId: number, info: TestRunAutoResultDto): Promise>; } type ApplauseConfig = AutoApiConfig & PublicApiConfig; +/** + * Represents the properties for loading the configuration. + */ interface ConfigLoadProperties { configFile?: string; properties?: Partial; } +/** + * Loads the configuration for the Applause Reporter. + * @param loadOptions - The options for loading the configuration. + * @returns The loaded Applause configuration. + * @throws Error if the configuration is not complete or invalid. + */ declare function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig; +/** + * Overrides the configuration with the provided overrides. + * @param config - The base configuration. + * @param overrides - The overrides to apply. + * @returns The overridden configuration. + */ declare function overrideConfig(config: Partial, overrides?: Partial): Partial; +/** + * Checks if the configuration is complete. + * @param config - The configuration to check. + * @returns True if the configuration is complete, false otherwise. + */ declare function isComplete(config: Partial): boolean; +/** + * Loads the configuration from the specified file. + * @param configFile - The path to the configuration file. + * @returns The loaded configuration from the file. + */ declare function loadConfigFromFile(configFile?: string): Partial; +/** + * Validates the configuration. + * @param config - The configuration to validate. + * @throws Error if the configuration is invalid. + */ declare function validateConfig(config: ApplauseConfig): void; +/** + * Validates a partial configuration. + * @param config - The partial configuration to validate. + * @throws Error if the partial configuration is invalid. + */ declare function validatePartialConfig(config: Partial): void; declare const TEST_RAIL_CASE_ID_PREFIX: string; declare const APPLAUSE_CASE_ID_PREFIX: string; -declare function parseTestCaseName(testCaseName: string): ParsedTestCaseName; +declare function parseTestCaseName(testCaseName: string, logger?: winston.Logger): ParsedTestCaseName; interface ParsedTestCaseName { testCaseName: string; testRailTestCaseId?: string; applauseTestCaseId?: string; } -export { APPLAUSE_CASE_ID_PREFIX, type AdditionalTestCaseParams, type AdditionalTestCaseResultParams, type ApplauseConfig, ApplauseReporter, type Attachment, AutoApi, type ClientConfig, type ConfigLoadProperties, type CreateTestCaseResultDto, type CreateTestCaseResultResponseDto, type EmailAddressResponse, type EmailFetchRequest, EmailHelper, Inbox, type ParsedTestCaseName, PublicApi, RunInitializer, RunReporter, type SessionDetails, type SubmitTestCaseResultDto, TEST_RAIL_CASE_ID_PREFIX, type TestRailOptions, type TestResultProviderInfo, TestResultStatus, type TestRunAutoResultDto, TestRunAutoResultStatus, type TestRunCreateDto, type TestRunCreateResponseDto, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; +declare const WINSTON_DEFAULT_LOG_FORMAT: winston.Logform.Format; +declare function constructDefaultLogger(): winston.Logger; +/** + * A simple Class for storing and retrieving log messages. + */ +declare class LoggingContainer { + private logs; + /** + * Retrieves all logs stored in the container. + * + * @returns An array of log messages. + */ + getLogs(): string[]; + /** + * Retrieves and clears all logs stored in the container. + * + * @returns An array of log messages. + */ + drainLogs(): string[]; + /** + * Clears all logs stored in the container. + */ + clearLogs(): void; + /** + * Adds a log message to the container. + * + * @param log - The log message to add. + */ + addLog(log: string): void; +} +declare const APPLAUSE_LOG_RECORDS: LoggingContainer; +/** + * A Custom Winston Transport that sends logs to the Applause LoggingContainer + */ +declare class ApplauseTransport extends TransportStream { + constructor(opts?: TransportStream.TransportStreamOptions); + log(info: TransformableInfo, callback: () => void): void; +} + +export { APPLAUSE_CASE_ID_PREFIX, APPLAUSE_LOG_RECORDS, type AdditionalTestCaseParams, type AdditionalTestCaseResultParams, type ApplauseConfig, ApplauseReporter, ApplauseTransport, AssetType, type Attachment, AutoApi, type ClientConfig, type ConfigLoadProperties, type CreateTestCaseResultDto, type CreateTestCaseResultResponseDto, type EmailAddressResponse, type EmailFetchRequest, EmailHelper, Inbox, LoggingContainer, type ParsedTestCaseName, PublicApi, RunInitializer, RunReporter, type SessionDetails, type SubmitTestCaseResultDto, TEST_RAIL_CASE_ID_PREFIX, type TestRailOptions, type TestResultProviderInfo, TestResultStatus, type TestRunAutoResultDto, TestRunAutoResultStatus, type TestRunCreateDto, type TestRunCreateResponseDto, TestRunHeartbeatService, WINSTON_DEFAULT_LOG_FORMAT, constructDefaultLogger, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; diff --git a/dist/index.min.js b/dist/index.min.js index 0a8c139..cb2ffab 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("mailparser"),require("fs"),require("path")):"function"==typeof define&&define.amd?define(["exports","axios","validator","mailparser","fs","path"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self)["applause-reporter-common"]={},t.axios,t.Validator,t.mailparser,t.fs,t.path)}(this,(function(t,e,s,i,a,r){"use strict";const n=s.default,o={autoApiBaseUrl:"https://prod-auto-api.cloud.applause.com/"};function l(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!n.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(n.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}class u{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,l(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}),(function(t){const e=void 0!==t.response?.data?JSON.stringify(t.response.data):`error-code [${t.response?.status}] with error [${t.response?.statusText}]`;return console.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.0.0",productId:this.options.productId,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}}}var p;t.TestResultStatus=void 0,(p=t.TestResultStatus||(t.TestResultStatus={})).NOT_RUN="NOT_RUN",p.IN_PROGRESS="IN_PROGRESS",p.PASSED="PASSED",p.FAILED="FAILED",p.SKIPPED="SKIPPED",p.CANCELED="CANCELED",p.ERROR="ERROR";class d{emailAddress;autoApi;constructor(t,e){this.emailAddress=t,this.autoApi=e}async getEmail(){const t=await this.autoApi.getEmailContent({emailAddress:this.emailAddress});return await i.simpleParser(t.data)}}class c{testRunId;autoApi;enabled=!1;nextHeartbeat;constructor(t,e){this.testRunId=t,this.autoApi=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(){console.log("Sending heartbeat"),await this.autoApi.sendSdkHeartbeat(this.testRunId),console.log("Heartbeat sent"),this.scheduleNextHeartbeat()}async end(){void 0!==this.nextHeartbeat&&(this.enabled=!1,console.debug("Ending Applause SDK Heartbeat"),await this.nextHeartbeat,console.debug("Applause SDK Heartbeat Ended Successfully")),this.nextHeartbeat=void 0}}const h="TestRail-",R="Applause-";function I(t){const e=t.match(/(TestRail-\d+|Applause-\d+)/g),s=e?.filter((t=>t.startsWith(h))).map((t=>t.substring(9)))||[],i=e?.filter((t=>t.startsWith(R))).map((t=>t.substring(9)))||[];return s.length>1&&console.warn("Multiple TestRail case ids detected in testCase name"),i.length>1&&console.warn("Multiple Applause case ids detected in testCase name"),{applauseTestCaseId:i[0],testRailTestCaseId:s[0],testCaseName:t.replace(/(TestRail-\d+|Applause-\d+)/g,"").replace(/\s+/g," ").trim()}}class g{autoApi;constructor(t){this.autoApi=t}async initializeRun(t){const e=t?.map(I).map((t=>t.testCaseName.trim())),s=await this.autoApi.startTestRun({tests:e||[]});if(s.status<200||s.status>300)throw new Error("Unable to create test run");const i=s.data.runId;console.log("Test Run %d initialized",i);const a=new c(i,this.autoApi);return await a.start(),new f(this.autoApi,i,a)}}class f{autoApi;testRunId;heartbeatService;uidToResultIdMap={};resultSubmissionMap={};constructor(t,e,s){this.autoApi=t,this.testRunId=e,this.heartbeatService=s}startTestCase(t,e,s){const i=I(e);this.uidToResultIdMap[t]=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))}submitTestCaseResult(t,e,s){this.resultSubmissionMap[t]=this.uidToResultIdMap[t]?.then((t=>this.autoApi.submitTestCaseResult({status:e,testResultId:t,...s})))}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){console.info(JSON.stringify(e));const t=".";a.writeFileSync(r.join(t,"providerUrls.txt"),JSON.stringify(e,null,1))}}}var m;t.TestRunAutoResultStatus=void 0,(m=t.TestRunAutoResultStatus||(t.TestRunAutoResultStatus={})).PASSED="PASSED",m.FAILED="FAILED",m.SKIPPED="SKIPPED",m.CANCELED="CANCELED",m.ERROR="ERROR";const A=s.default,w={publicApiBaseUrl:"https://api.applause.com/"};function b(t){if(!Number.isInteger(t.productId)||t.productId<=0)throw new Error(`productId must be a positive integer, was: '${t.productId}'`);if(!A.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(A.isEmpty(t.apiKey))throw new Error("apiKey is an empty string!")}function y(t,e){return Object.assign({},t,Object.fromEntries(Object.entries(e||{}).filter((([t,e])=>void 0!==e))))}function T(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 E(t){const e=t||process.cwd()+"/applause.json";if(!a.existsSync(e))return{};const s=a.readFileSync(e,"utf8");return JSON.parse(s)}function v(t){l(t),b(t)}t.APPLAUSE_CASE_ID_PREFIX=R,t.ApplauseReporter=class{autoApi;initializer;reporter;runStarted=!1;runFinished=!1;constructor(t){this.autoApi=new u(t),this.initializer=new g(this.autoApi)}runnerStart(t){this.reporter=this.initializer.initializeRun(t),this.reporter.then((()=>{this.runStarted=!0}))}startTestCase(t,e,s){if(void 0===this.reporter)throw new Error("Cannot start a test case for a run that was never initialized");this.reporter.then((i=>i.startTestCase(t,e,s)))}submitTestCaseResult(t,e,s){if(void 0===this.reporter)throw new Error("Cannot submit test case result for a run that was never initialized");this.reporter.then((i=>i.submitTestCaseResult(t,e,s)))}async runnerEnd(){if(void 0===this.reporter)throw new Error("Cannot end a run that was never initialized");await this.reporter.then((t=>t.runnerEnd())).then((()=>this.runFinished=!0))}isSynchronized(){return(!this.runStarted||this.runStarted&&this.runFinished)&&0==this.autoApi.getCallsInFlight}},t.AutoApi=u,t.EmailHelper=class{autoApi;constructor(t){this.autoApi=t}async getInbox(t){const e=(await this.autoApi.getEmailAddress(t)).data.emailAddress;return new d(e,this.autoApi)}},t.Inbox=d,t.PublicApi=class{options;client;callsInFlight;get getCallsInFlight(){return this.callsInFlight}constructor(t){this.options=t,this.callsInFlight=0,b(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}),(function(t){const e=void 0!==t.data?t.data:`error-code [${t.response.status}] with error [${t.response.statusText}]`;return console.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=g,t.RunReporter=f,t.TEST_RAIL_CASE_ID_PREFIX=h,t.TestRunHeartbeatService=c,t.isComplete=T,t.loadConfig=function(t){let e={...w,...o};if(e=void 0!==t&&void 0!==t.configFile?y(e,E(r.join(process.cwd(),t.configFile))):y(e,E()),void 0!==t&&void 0!==t.properties&&(e=y(e,t.properties)),!T(e))throw new Error("Config is not complete");const s=e;return v(s),s},t.loadConfigFromFile=E,t.overrideConfig=y,t.parseTestCaseName=I,t.validateConfig=v,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 R{logs=[];getLogs(){return this.logs}drainLogs(){const t=this.logs;return this.clearLogs(),t}clearLogs(){this.logs=[]}addLog(t){this.logs.push(t)}}const I=new R;class f extends r{constructor(t){super(t)}log(t,e){setImmediate((()=>{this.emit("logged",t)})),this.format?.transform(t),I.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,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 b="TestRail-",y="Applause-";function O(t,e){const s=t.match(/(TestRail-\d+|Applause-\d+)/g),i=s?.filter((t=>t.startsWith(b))).map((t=>t.substring(9)))??[],r=s?.filter((t=>t.startsWith(y))).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=y,t.APPLAUSE_LOG_RECORDS=I,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=R,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=b,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 63450e8..400ff9a 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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\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 console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map"],"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","AutoApi","options","client","callsInFlight","getCallsInFlight","this","constructor","axios","create","baseURL","timeout","headers","responseType","interceptors","response","use","error","errText","undefined","data","JSON","stringify","status","statusText","console","Promise","reject","startTestRun","info","post","sdkVersion","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","TestResultStatus","exports","Inbox","emailAddress","autoApi","getEmail","res","simpleParser","TestRunHeartbeatService","enabled","nextHeartbeat","start","end","scheduleNextHeartbeat","isEnabled","resolve","setTimeout","then","sendHeartbeat","log","debug","TEST_RAIL_CASE_ID_PREFIX","APPLAUSE_CASE_ID_PREFIX","parseTestCaseName","testCaseName","matches","match","testRailCaseIds","startsWith","map","substring","applauseCaseIds","length","warn","applauseTestCaseId","testRailTestCaseId","replace","trim","RunInitializer","initializeRun","tests","cleanedTests","parsed","testRunCreateResponse","runId","heartbeatService","RunReporter","uidToResultIdMap","resultSubmissionMap","parsedTestCase","testCaseId","itwTestCaseId","Object","fromEntries","entries","_","v","testResultId","resultId","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","fileCotents","readFileSync","parse","validateConfig","initializer","reporter","runStarted","runFinished","runnerStart","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 // 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 // Optional: an applause test cycle id\n itwTestCycleId?: number;\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","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 54fdd0c..821ff71 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -1,10 +1,12 @@ import axios from 'axios'; import Validator from 'validator'; +import * as winston from 'winston'; +import TransportStream from 'winston-transport'; import { simpleParser } from 'mailparser'; import { writeFileSync, existsSync, readFileSync } from 'fs'; import path, { join } from 'path'; -const API_VERSION = '1.0.0'; +const API_VERSION = '1.1.0'; const validator$1 = Validator.default; const DEFAULT_URL$1 = 'https://prod-auto-api.cloud.applause.com/'; @@ -22,7 +24,7 @@ function validateAutoApiConfig(config) { } if (!validator$1.isURL(config.autoApiBaseUrl, { protocols: ['http', 'https'], - require_tld: false, + require_tld: false, // allow localhost allow_query_components: false, disallow_auth: true, allow_fragments: false, @@ -38,19 +40,107 @@ function validateAutoApiConfig(config) { } } +const MESSAGE = Symbol.for('message'); +const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf(({ level, message, label, timestamp }) => { + return `${timestamp} [${label}] ${level}: ${message}`; +}); +function constructDefaultLogger() { + return winston.createLogger({ + format: winston.format.combine(winston.format.label({ label: 'Applause Tests' }), winston.format.timestamp(), winston.format.splat(), WINSTON_DEFAULT_LOG_FORMAT), + transports: [ + new winston.transports.File({ filename: 'error.log', level: 'error' }), + new winston.transports.File({ filename: 'combined.log' }), + new ApplauseTransport(), + new winston.transports.Console({ + level: 'info', + format: winston.format.combine(winston.format.colorize(), WINSTON_DEFAULT_LOG_FORMAT), + }), + ], + }); +} +/** + * A simple Class for storing and retrieving log messages. + */ +class LoggingContainer { + logs = []; + /** + * Retrieves all logs stored in the container. + * + * @returns An array of log messages. + */ + getLogs() { + return this.logs; + } + /** + * Retrieves and clears all logs stored in the container. + * + * @returns An array of log messages. + */ + drainLogs() { + const logs = this.logs; + this.clearLogs(); + return logs; + } + /** + * Clears all logs stored in the container. + */ + clearLogs() { + this.logs = []; + } + /** + * Adds a log message to the container. + * + * @param log - The log message to add. + */ + addLog(log) { + this.logs.push(log); + } +} +// Create a new Shared LoggingContainer to store logs +const APPLAUSE_LOG_RECORDS = new LoggingContainer(); +/** + * A Custom Winston Transport that sends logs to the Applause LoggingContainer + */ +class ApplauseTransport extends TransportStream { + constructor(opts) { + super(opts); + } + log(info, callback) { + setImmediate(() => { + this.emit('logged', info); + }); + this.format?.transform(info); + APPLAUSE_LOG_RECORDS.addLog(info[MESSAGE] ?? info.message); + // Continue to the next transport + callback(); + } +} + +/** + * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform. + * 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. + * It also includes properties and methods to track the number of HTTP calls in progress. + */ class AutoApi { options; client; + logger; callsInFlight; /** - * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + * Tracks the number of HTTP calls in progress. + * This property is used by reporters that want to know when the async work is finished. */ get getCallsInFlight() { return this.callsInFlight; } - constructor(options) { + /** + * Creates an instance of the `AutoApi` class. + * @param options - The configuration options for the Applause API. + */ + constructor(options, logger) { this.options = options; this.callsInFlight = 0; + this.logger = logger ?? constructDefaultLogger(); validateAutoApiConfig(options); this.client = axios.create({ baseURL: options.autoApiBaseUrl, @@ -63,17 +153,22 @@ class AutoApi { }); this.client.interceptors.response.use(function (response) { return response; - }, function (error) { + }, (error) => { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access error.response?.data !== undefined ? JSON.stringify(error.response.data) : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; - console.error(`Auto-Api returned ${errText}`); + this.logger.error(`Auto-Api returned ${errText}`); return Promise.reject(error); }); } + /** + * Starts a new test run. + * @param info - The information for creating the test run. + * @returns A promise that resolves to the response containing the created test run. + */ async startTestRun(info) { this.callsInFlight += 1; try { @@ -98,6 +193,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Ends a test run. + * @param testRunId - The ID of the test run to end. + * @returns A promise that resolves to the response indicating the completion of the test run. + */ async endTestRun(testRunId) { this.callsInFlight += 1; try { @@ -107,6 +207,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Starts a new test case. + * @param params - The parameters for creating the test case. + * @returns A promise that resolves to the response containing the created test case. + */ async startTestCase(params) { this.callsInFlight += 1; try { @@ -117,6 +222,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Submits a test case result. + * @param params - The parameters for submitting the test case result. + * @returns A promise that resolves when the test case result is submitted. + */ async submitTestCaseResult(params) { this.callsInFlight += 1; try { @@ -126,6 +236,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Retrieves the provider session links for the specified test results. + * @param resultIds - The IDs of the test results. + * @returns A promise that resolves to the response containing the provider session links. + */ async getProviderSessionLinks(resultIds) { this.callsInFlight += 1; try { @@ -137,6 +252,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Sends a heartbeat for the specified test run. + * @param testRunId - The ID of the test run. + * @returns A promise that resolves to the response indicating the heartbeat was sent. + */ async sendSdkHeartbeat(testRunId) { this.callsInFlight += 1; try { @@ -149,6 +269,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Retrieves the email address for the specified email prefix. + * @param emailPrefix - The prefix of the email address. + * @returns A promise that resolves to the response containing the email address. + */ async getEmailAddress(emailPrefix) { this.callsInFlight += 1; try { @@ -159,6 +284,11 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Retrieves the content of the specified email. + * @param request - The request parameters for retrieving the email content. + * @returns A promise that resolves to the response containing the email content. + */ async getEmailContent(request) { this.callsInFlight += 1; try { @@ -169,6 +299,30 @@ class AutoApi { this.callsInFlight -= 1; } } + /** + * Uploads an asset for the specified test result. + * @param resultId - The ID of the test result. + * @param file - The file to upload as an asset. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The GUID of the provider session. + * @param assetType - The type of the asset. + * @returns A promise that resolves to the response indicating the asset was uploaded. + */ + async uploadAsset(resultId, file, assetName, providerSessionGuid, assetType) { + this.callsInFlight += 1; + try { + // this filters out falsy values (null, undefined, 0) + return await this.client.postForm(`/api/v1.0/test-result/${resultId}/upload`, { + file, + assetName, + providerSessionGuid, + assetType, + }); + } + finally { + this.callsInFlight -= 1; + } + } } /** @@ -184,14 +338,48 @@ var TestResultStatus; TestResultStatus["CANCELED"] = "CANCELED"; TestResultStatus["ERROR"] = "ERROR"; })(TestResultStatus || (TestResultStatus = {})); +var AssetType; +(function (AssetType) { + AssetType["SCREENSHOT"] = "SCREENSHOT"; + AssetType["FAILURE_SCREENSHOT"] = "FAILURE_SCREENSHOT"; + AssetType["VIDEO"] = "VIDEO"; + AssetType["NETWORK_HAR"] = "NETWORK_HAR"; + AssetType["VITALS_LOG"] = "VITALS_LOG"; + AssetType["CONSOLE_LOG"] = "CONSOLE_LOG"; + AssetType["NETWORK_LOG"] = "NETWORK_LOG"; + AssetType["DEVICE_LOG"] = "DEVICE_LOG"; + AssetType["SELENIUM_LOG"] = "SELENIUM_LOG"; + AssetType["SELENIUM_LOG_JSON"] = "SELENIUM_LOG_JSON"; + AssetType["BROWSER_LOG"] = "BROWSER_LOG"; + AssetType["FRAMEWORK_LOG"] = "FRAMEWORK_LOG"; + AssetType["EMAIL"] = "EMAIL"; + AssetType["PAGE_SOURCE"] = "PAGE_SOURCE"; + AssetType["CODE_BUNDLE"] = "CODE_BUNDLE"; + AssetType["RESULTS_ZIP"] = "RESULTS_ZIP"; + AssetType["SESSION_DETAILS"] = "SESSION_DETAILS"; + AssetType["DEVICE_DETAILS"] = "DEVICE_DETAILS"; + AssetType["UNKNOWN"] = "UNKNOWN"; +})(AssetType || (AssetType = {})); +/** + * Represents an email inbox. + */ class Inbox { emailAddress; autoApi; + /** + * Creates an instance of Inbox. + * @param emailAddress - The email address associated with the inbox. + * @param autoApi - An instance of the AutoApi class. + */ constructor(emailAddress, autoApi) { this.emailAddress = emailAddress; this.autoApi = autoApi; } + /** + * Retrieves the content of an email from the inbox. + * @returns A Promise that resolves to the parsed email content. + */ async getEmail() { const res = await this.autoApi.getEmailContent({ emailAddress: this.emailAddress, @@ -200,33 +388,60 @@ class Inbox { } } +/** + * Helper class for managing email functionality. + */ class EmailHelper { autoApi; constructor(autoApi) { this.autoApi = autoApi; } + /** + * Retrieves the inbox for the specified email prefix. + * + * @param emailPrefix - The prefix used to generate the email address. + * @returns A Promise that resolves to an Inbox object. + */ async getInbox(emailPrefix) { const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress; return new Inbox(generatedAddress, this.autoApi); } } +/** + * Represents a service for sending heartbeats during a test run. + */ class TestRunHeartbeatService { testRunId; autoApi; enabled = false; nextHeartbeat; - constructor(testRunId, autoApi) { + logger; + /** + * Creates an instance of TestRunHeartbeatService. + * @param testRunId - The ID of the test run. + * @param autoApi - The AutoApi instance used for sending heartbeats. + */ + constructor(testRunId, autoApi, logger) { this.testRunId = testRunId; this.autoApi = autoApi; + this.logger = logger ?? constructDefaultLogger(); } + /** + * Starts sending heartbeats. + * @returns A promise that resolves when the heartbeats are started. + */ async start() { // End the current heartbeat if it has started await this.end(); - // Set up va new interval + // Set up a new interval this.enabled = true; this.scheduleNextHeartbeat(); } + /** + * Checks if the heartbeats are enabled. + * @returns True if the heartbeats are enabled, false otherwise. + */ isEnabled() { return this.enabled; } @@ -237,17 +452,21 @@ class TestRunHeartbeatService { this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat()); } async sendHeartbeat() { - console.log('Sending heartbeat'); + this.logger.debug('Sending heartbeat'); await this.autoApi.sendSdkHeartbeat(this.testRunId); - console.log('Heartbeat sent'); + this.logger.debug('Heartbeat sent'); this.scheduleNextHeartbeat(); } + /** + * Ends the heartbeats. + * @returns A promise that resolves when the heartbeats are ended. + */ async end() { if (this.nextHeartbeat !== undefined) { this.enabled = false; - console.debug('Ending Applause SDK Heartbeat'); + this.logger.debug('Ending Applause SDK Heartbeat'); await this.nextHeartbeat; - console.debug('Applause SDK Heartbeat Ended Successfully'); + this.logger.debug('Applause SDK Heartbeat Ended Successfully'); } this.nextHeartbeat = undefined; } @@ -255,19 +474,19 @@ class TestRunHeartbeatService { const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-'; const APPLAUSE_CASE_ID_PREFIX = 'Applause-'; -function parseTestCaseName(testCaseName) { +function parseTestCaseName(testCaseName, logger) { const matches = testCaseName.match(/(TestRail-\d+|Applause-\d+)/g); const testRailCaseIds = matches ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX)) - .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) || []; + .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? []; const applauseCaseIds = matches ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX)) - .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || []; + .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? []; if (testRailCaseIds.length > 1) { - console.warn('Multiple TestRail case ids detected in testCase name'); + (logger ?? console).warn('Multiple TestRail case ids detected in testCase name'); } if (applauseCaseIds.length > 1) { - console.warn('Multiple Applause case ids detected in testCase name'); + (logger ?? console).warn('Multiple Applause case ids detected in testCase name'); } return { applauseTestCaseId: applauseCaseIds[0], @@ -279,85 +498,192 @@ function parseTestCaseName(testCaseName) { }; } +/** + * Represents an Applause reporter. + */ class ApplauseReporter { autoApi; initializer; + logger; reporter; runStarted = false; runFinished = false; - constructor(config) { - this.autoApi = new AutoApi(config); - this.initializer = new RunInitializer(this.autoApi); + /** + * Creates an instance of ApplauseReporter. + * @param config - The Applause configuration. + */ + constructor(config, logger) { + this.logger = logger ?? constructDefaultLogger(); + this.autoApi = new AutoApi(config, this.logger); + this.initializer = new RunInitializer(this.autoApi, this.logger); + const runId = process.env['APPLAUSE_RUN_ID']; + if (runId !== undefined) { + const r = new RunReporter(this.autoApi, parseInt(runId), undefined, this.logger); + this.reporter = new Promise(resolve => resolve(r)); + this.runStarted = true; + } } - runnerStart(tests) { + /** + * Starts the Applause runner. + * @param tests - Optional array of test names to run. + * @returns A promise that resolves to the test run ID. + * @throws Error if a run is already started or finished. + */ + async runnerStart(tests) { + if (this.reporter !== undefined) { + this.logger.error('Cannot start a run - run already started or run already finished'); + throw new Error('Cannot start a run - run already started or run already finished'); + } this.reporter = this.initializer.initializeRun(tests); - void this.reporter.then(() => { - this.runStarted = true; - }); + const initializedReporter = await this.reporter; + this.runStarted = true; + process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString(); + return initializedReporter.testRunId; } - startTestCase(id, testCaseName, params) { + /** + * Starts a test case. + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Optional additional parameters for the test case. + * @returns A promise that resolves to the test case ID. + * @throws Error if a run was never initialized. + */ + async startTestCase(id, testCaseName, params) { if (this.reporter === undefined) { + this.logger.error('Cannot start a test case for a run that was never initialized'); throw new Error('Cannot start a test case for a run that was never initialized'); } - void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params)); + const reporter = await this.reporter; + return reporter.startTestCase(id, testCaseName, params); } - submitTestCaseResult(id, status, params) { + /** + * Submits a test case result. + * @param id - The ID of the test case. + * @param status - The status of the test case result. + * @param params - Optional additional parameters for the test case result. + * @returns A promise that resolves to the test case result ID. + * @throws Error if a run was never initialized. + */ + async submitTestCaseResult(id, status, params) { if (this.reporter === undefined) { + this.logger.error('Cannot submit test case result for a run that was never initialized'); throw new Error('Cannot submit test case result for a run that was never initialized'); } - void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params)); + const reporter = await this.reporter; + return reporter.submitTestCaseResult(id, status, params); } + /** + * Ends the Applause runner. + * @returns A promise that resolves when the runner is ended. + * @throws Error if a run was never initialized. + */ async runnerEnd() { if (this.reporter === undefined) { + this.logger.error('Cannot end a run that was never initialized'); throw new Error('Cannot end a run that was never initialized'); } await this.reporter .then(reporter => reporter.runnerEnd()) .then(() => (this.runFinished = true)); } + /** + * Attaches an asset to a test case. + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset data as a Buffer. + * @returns A promise that resolves when the asset is attached. + * @throws Error if a run was never initialized. + */ + async attachTestCaseAsset(id, assetName, providerSessionGuid, assetType, asset) { + if (this.reporter === undefined) { + this.logger.error('Cannot attach an asset for a run that was never initialized'); + throw new Error('Cannot attach an asset for a run that was never initialized'); + } + return await this.reporter.then(reporter => reporter.attachTestCaseAsset(id, assetName, providerSessionGuid, assetType, asset)); + } + /** + * Checks if the Applause runner is synchronized. + * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished. + */ isSynchronized() { - // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished return ((!this.runStarted || (this.runStarted && this.runFinished)) && this.autoApi.getCallsInFlight == 0); } } +/** + * Represents a Run Initializer. + */ class RunInitializer { autoApi; - constructor(autoApi) { + logger; + constructor(autoApi, logger) { this.autoApi = autoApi; + this.logger = logger ?? constructDefaultLogger(); } + /** + * Initializes a test run. + * @param tests - An optional array of test names to include in the run. + * @returns A promise that resolves to a RunReporter instance. + * @throws An error if unable to create the test run. + */ async initializeRun(tests) { const cleanedTests = tests - ?.map(parseTestCaseName) + ?.map(testName => parseTestCaseName(testName, this.logger)) .map(parsed => parsed.testCaseName.trim()); const testRunCreateResponse = await this.autoApi.startTestRun({ - tests: cleanedTests || [], + tests: cleanedTests ?? [], }); if (testRunCreateResponse.status < 200 || testRunCreateResponse.status > 300) { + this.logger.error(`Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.`); throw new Error('Unable to create test run'); } const runId = testRunCreateResponse.data.runId; - console.log('Test Run %d initialized', runId); - const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi); + this.logger.info(`Test Run ${runId} initialized`); + const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi, this.logger); await heartbeatService.start(); - return new RunReporter(this.autoApi, runId, heartbeatService); + return new RunReporter(this.autoApi, runId, heartbeatService, this.logger); } } +/** + * Handles reporting test results to the Applause API. + */ class RunReporter { autoApi; testRunId; heartbeatService; uidToResultIdMap = {}; resultSubmissionMap = {}; - constructor(autoApi, testRunId, heartbeatService) { + logger; + /** + * Creates a new instance of the Reporter class. + * @param autoApi - The AutoApi instance. + * @param testRunId - The ID of the test run. + * @param heartbeatService - (Optional) The TestRunHeartbeatService instance. + */ + constructor(autoApi, testRunId, heartbeatService, logger) { this.autoApi = autoApi; this.testRunId = testRunId; this.heartbeatService = heartbeatService; + this.logger = logger ?? constructDefaultLogger(); } + /** + * Starts a test case and returns a promise that resolves to the test result ID. + * + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Additional parameters for the test case. + * @returns A promise that resolves to the test result ID. + */ startTestCase(id, testCaseName, params) { - const parsedTestCase = parseTestCaseName(testCaseName); - this.uidToResultIdMap[id] = this.autoApi + if (!testCaseName) { + this.logger.error('testCaseName is required'); + throw new Error('testCaseName is required'); + } + const parsedTestCase = parseTestCaseName(testCaseName, this.logger); + const submission = this.autoApi .startTestCase({ testCaseName: parsedTestCase.testCaseName, testCaseId: parsedTestCase.testRailTestCaseId, @@ -369,27 +695,58 @@ class RunReporter { .then(res => { return res.data.testResultId; }); + this.uidToResultIdMap[id] = submission; + return submission; } + /** + * Submits the result of a test case. + * + * @param id - The ID of the test case. + * @param status - The status of the test result. + * @param params - Additional parameters for the test result. + * @returns A promise that resolves to the result ID. + */ submitTestCaseResult(id, status, params) { - this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({ + const submission = this.uidToResultIdMap[id]?.then(resultId => this.autoApi + .submitTestCaseResult({ status: status, testResultId: resultId, ...params, - })); + }) + .then(() => resultId)); + this.resultSubmissionMap[id] = submission; + return submission; + } + /** + * Attaches a test case asset to a result. + * + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset to attach. + * @returns A promise that resolves when the asset is attached. + */ + async attachTestCaseAsset(id, assetName, providerSessionGuid, assetType, asset) { + await this.uidToResultIdMap[id]?.then(resultId => this.autoApi.uploadAsset(resultId, asset, assetName, providerSessionGuid, assetType)); } + /** + * Ends the test runner and performs necessary cleanup tasks. + * @returns A promise that resolves when the runner has ended. + */ async runnerEnd() { // Wait for all results to be created - const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || []; + const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) ?? []; // Wait for the results to be submitted void (await Promise.all(Object.values(this.resultSubmissionMap))); // Wait the heartbeat to be ended - void (await this.heartbeatService.end()); + void (await this.heartbeatService?.end()); void (await this.autoApi.endTestRun(this.testRunId)); // Fetch the provider session asset links and save them off to a file const resp = await this.autoApi.getProviderSessionLinks(resultIds); - const jsonArray = resp.data || []; + const jsonArray = resp.data ?? []; if (jsonArray.length > 0) { - console.info(JSON.stringify(jsonArray)); + this.logger.info(JSON.stringify(jsonArray)); // this is the wdio.conf outputDir const outputPath = '.'; writeFileSync(join(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1)); @@ -422,7 +779,7 @@ function validatePublicApiConfig(config) { } if (!validator.isURL(config.publicApiBaseUrl, { protocols: ['http', 'https'], - require_tld: false, + require_tld: false, // allow localhost allow_query_components: false, disallow_auth: true, allow_fragments: false, @@ -442,15 +799,17 @@ class PublicApi { options; client; callsInFlight; + logger; /** * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished */ get getCallsInFlight() { return this.callsInFlight; } - constructor(options) { + constructor(options, logger) { this.options = options; this.callsInFlight = 0; + this.logger = logger ?? constructDefaultLogger(); validatePublicApiConfig(options); this.client = axios.create({ baseURL: options.publicApiBaseUrl, @@ -463,16 +822,14 @@ class PublicApi { }); this.client.interceptors.response.use(function (response) { return response; - }, function (error) { + }, (error) => { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data !== undefined - ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data - : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - `error-code [${error.response.status}] with error [${error.response.statusText}]`; - console.error(`Public-Api returned ${errText}`); + error.response?.data !== undefined + ? JSON.stringify(error.response.data) + : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; + this.logger.error(`Public-Api returned ${errText}`); return Promise.reject(error); }); } @@ -487,7 +844,15 @@ class PublicApi { } } -// Loads the configuration +/** + * Represents the configuration options for the Applause Reporter. + */ +/** + * Loads the configuration for the Applause Reporter. + * @param loadOptions - The options for loading the configuration. + * @returns The loaded Applause configuration. + * @throws Error if the configuration is not complete or invalid. + */ function loadConfig(loadOptions) { // Setup the initial config with any default properties let config = { @@ -514,24 +879,50 @@ function loadConfig(loadOptions) { validateConfig(finalConfig); return finalConfig; } +/** + * Overrides the configuration with the provided overrides. + * @param config - The base configuration. + * @param overrides - The overrides to apply. + * @returns The overridden configuration. + */ function overrideConfig(config, overrides) { - return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined))); + return Object.assign({}, config, Object.fromEntries(Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined))); } +/** + * Checks if the configuration is complete. + * @param config - The configuration to check. + * @returns True if the configuration is complete, false otherwise. + */ function isComplete(config) { return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config); } +/** + * Loads the configuration from the specified file. + * @param configFile - The path to the configuration file. + * @returns The loaded configuration from the file. + */ function loadConfigFromFile(configFile) { - const configFilePath = configFile || process.cwd() + '/applause.json'; + const configFilePath = configFile ?? `${process.cwd()}/applause.json`; if (!existsSync(configFilePath)) { return {}; } - const fileCotents = readFileSync(configFilePath, 'utf8'); - return JSON.parse(fileCotents); + const fileContents = readFileSync(configFilePath, 'utf8'); + return JSON.parse(fileContents); } +/** + * Validates the configuration. + * @param config - The configuration to validate. + * @throws Error if the configuration is invalid. + */ function validateConfig(config) { validateAutoApiConfig(config); validatePublicApiConfig(config); } +/** + * Validates a partial configuration. + * @param config - The partial configuration to validate. + * @throws Error if the partial configuration is invalid. + */ function validatePartialConfig(config) { if (config.productId !== undefined && (!Number.isInteger(config.productId) || config.productId <= 0)) { @@ -539,5 +930,5 @@ function validatePartialConfig(config) { } } -export { APPLAUSE_CASE_ID_PREFIX, ApplauseReporter, AutoApi, EmailHelper, Inbox, PublicApi, RunInitializer, RunReporter, TEST_RAIL_CASE_ID_PREFIX, TestResultStatus, TestRunAutoResultStatus, TestRunHeartbeatService, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; +export { APPLAUSE_CASE_ID_PREFIX, APPLAUSE_LOG_RECORDS, ApplauseReporter, ApplauseTransport, AssetType, AutoApi, EmailHelper, Inbox, LoggingContainer, PublicApi, RunInitializer, RunReporter, TEST_RAIL_CASE_ID_PREFIX, TestResultStatus, TestRunAutoResultStatus, TestRunHeartbeatService, WINSTON_DEFAULT_LOG_FORMAT, constructDefaultLogger, isComplete, loadConfig, loadConfigFromFile, overrideConfig, parseTestCaseName, validateConfig, validatePartialConfig }; //# sourceMappingURL=index.mjs.map diff --git a/dist/index.mjs.map b/dist/index.mjs.map index 0dc0987..a9d9a97 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/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.0.0';\n//# sourceMappingURL=version.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://prod-auto-api.cloud.applause.com/';\nexport const DEFAULT_AUTO_API_PROPERTIES = {\n autoApiBaseUrl: DEFAULT_URL,\n};\nexport function isAutoApiConfigComplete(config) {\n return (config.autoApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialAutoApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validateAutoApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.autoApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`autoApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.autoApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=auto-api-config.js.map","import axios from 'axios';\nimport { API_VERSION } from './version.ts';\nimport { validateAutoApiConfig } from './auto-api-config.ts';\nexport class AutoApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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 this.client.interceptors.response.use(function (response) {\n return response;\n }, function (error) {\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 console.error(`Auto-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async startTestRun(info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post('/api/v1.0/test-run/create', {\n // Provided params\n ...info,\n // API Version\n sdkVersion: `js:${API_VERSION}`,\n // Copy over the product id\n productId: this.options.productId,\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: this.options.testRailOptions?.overrideTestRailRunUniqueness,\n });\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async endTestRun(testRunId) {\n this.callsInFlight += 1;\n try {\n return await this.client.delete(`/api/v1.0/test-run/${testRunId}?endingStatus=COMPLETE`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async startTestCase(params) {\n this.callsInFlight += 1;\n try {\n const res = await this.client.post('/api/v1.0/test-result/create-result', params);\n return res;\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async submitTestCaseResult(params) {\n this.callsInFlight += 1;\n try {\n await this.client.post('/api/v1.0/test-result', params);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getProviderSessionLinks(resultIds) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n const validIds = resultIds.filter(id => id);\n return await this.client.post('/api/v1.0/test-result/provider-info', validIds);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async sendSdkHeartbeat(testRunId) {\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 }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailAddress(emailPrefix) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.get(`/api/v1.0/email/get-address?prefix=${emailPrefix}`);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n async getEmailContent(request) {\n this.callsInFlight += 1;\n try {\n // this filters out falsy values (null, undefined, 0)\n return await this.client.post('/api/v1.0/email/download-email', request);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=auto-api.js.map","/**\n * Enum representing a test result's status\n */\nexport var TestResultStatus;\n(function (TestResultStatus) {\n TestResultStatus[\"NOT_RUN\"] = \"NOT_RUN\";\n TestResultStatus[\"IN_PROGRESS\"] = \"IN_PROGRESS\";\n TestResultStatus[\"PASSED\"] = \"PASSED\";\n TestResultStatus[\"FAILED\"] = \"FAILED\";\n TestResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestResultStatus || (TestResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import { simpleParser } from 'mailparser';\nexport class Inbox {\n emailAddress;\n autoApi;\n constructor(emailAddress, autoApi) {\n this.emailAddress = emailAddress;\n this.autoApi = autoApi;\n }\n async getEmail() {\n const res = await this.autoApi.getEmailContent({\n emailAddress: this.emailAddress,\n });\n return await simpleParser(res.data);\n }\n}\n//# sourceMappingURL=inbox.js.map","import { Inbox } from './email/inbox.ts';\nexport class EmailHelper {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async getInbox(emailPrefix) {\n const generatedAddress = (await this.autoApi.getEmailAddress(emailPrefix)).data.emailAddress;\n return new Inbox(generatedAddress, this.autoApi);\n }\n}\nexport * from './email/attachment.ts';\nexport * from './email/inbox.ts';\n//# sourceMappingURL=email-helper.js.map","export class TestRunHeartbeatService {\n testRunId;\n autoApi;\n enabled = false;\n nextHeartbeat;\n constructor(testRunId, autoApi) {\n this.testRunId = testRunId;\n this.autoApi = autoApi;\n }\n async start() {\n // End the current heartbeat if it has started\n await this.end();\n // Set up va new interval\n this.enabled = true;\n this.scheduleNextHeartbeat();\n }\n isEnabled() {\n return this.enabled;\n }\n scheduleNextHeartbeat() {\n if (!this.enabled) {\n return;\n }\n this.nextHeartbeat = new Promise(resolve => setTimeout(resolve, 5000)).then(() => this.sendHeartbeat());\n }\n async sendHeartbeat() {\n console.log('Sending heartbeat');\n await this.autoApi.sendSdkHeartbeat(this.testRunId);\n console.log('Heartbeat sent');\n this.scheduleNextHeartbeat();\n }\n async end() {\n if (this.nextHeartbeat !== undefined) {\n this.enabled = false;\n console.debug('Ending Applause SDK Heartbeat');\n await this.nextHeartbeat;\n console.debug('Applause SDK Heartbeat Ended Successfully');\n }\n this.nextHeartbeat = undefined;\n }\n}\n//# sourceMappingURL=heartbeat.js.map","export const TEST_RAIL_CASE_ID_PREFIX = 'TestRail-';\nexport const APPLAUSE_CASE_ID_PREFIX = 'Applause-';\nexport function parseTestCaseName(testCaseName) {\n const matches = testCaseName.match(/(TestRail-\\d+|Applause-\\d+)/g);\n const testRailCaseIds = 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 = matches\n ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX))\n .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || [];\n if (testRailCaseIds.length > 1) {\n console.warn('Multiple TestRail case ids detected in testCase name');\n }\n if (applauseCaseIds.length > 1) {\n console.warn('Multiple Applause case ids detected in testCase name');\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//# sourceMappingURL=test-case.js.map","import { writeFileSync } from 'fs';\nimport { AutoApi } from './auto-api.ts';\nimport { TestRunHeartbeatService } from './heartbeat.ts';\nimport { join as pathJoin } from 'path';\nimport { parseTestCaseName } from '../shared/test-case.ts';\nexport class ApplauseReporter {\n autoApi;\n initializer;\n reporter;\n runStarted = false;\n runFinished = false;\n constructor(config) {\n this.autoApi = new AutoApi(config);\n this.initializer = new RunInitializer(this.autoApi);\n }\n runnerStart(tests) {\n this.reporter = this.initializer.initializeRun(tests);\n void this.reporter.then(() => {\n this.runStarted = true;\n });\n }\n startTestCase(id, testCaseName, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot start a test case for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.startTestCase(id, testCaseName, params));\n }\n submitTestCaseResult(id, status, params) {\n if (this.reporter === undefined) {\n throw new Error('Cannot submit test case result for a run that was never initialized');\n }\n void this.reporter.then(reporter => reporter.submitTestCaseResult(id, status, params));\n }\n async runnerEnd() {\n if (this.reporter === undefined) {\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 isSynchronized() {\n // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished\n return ((!this.runStarted || (this.runStarted && this.runFinished)) &&\n this.autoApi.getCallsInFlight == 0);\n }\n}\nexport class RunInitializer {\n autoApi;\n constructor(autoApi) {\n this.autoApi = autoApi;\n }\n async initializeRun(tests) {\n const cleanedTests = tests\n ?.map(parseTestCaseName)\n .map(parsed => parsed.testCaseName.trim());\n const testRunCreateResponse = await this.autoApi.startTestRun({\n tests: cleanedTests || [],\n });\n if (testRunCreateResponse.status < 200 ||\n testRunCreateResponse.status > 300) {\n throw new Error('Unable to create test run');\n }\n const runId = testRunCreateResponse.data.runId;\n console.log('Test Run %d initialized', runId);\n const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi);\n await heartbeatService.start();\n return new RunReporter(this.autoApi, runId, heartbeatService);\n }\n}\nexport class RunReporter {\n autoApi;\n testRunId;\n heartbeatService;\n uidToResultIdMap = {};\n resultSubmissionMap = {};\n constructor(autoApi, testRunId, heartbeatService) {\n this.autoApi = autoApi;\n this.testRunId = testRunId;\n this.heartbeatService = heartbeatService;\n }\n startTestCase(id, testCaseName, params) {\n const parsedTestCase = parseTestCaseName(testCaseName);\n this.uidToResultIdMap[id] = this.autoApi\n .startTestCase({\n testCaseName: parsedTestCase.testCaseName,\n testCaseId: parsedTestCase.testRailTestCaseId,\n itwTestCaseId: parsedTestCase.applauseTestCaseId,\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(Object.entries(params || {}).filter(([_, v]) => v !== undefined)),\n })\n .then(res => {\n return res.data.testResultId;\n });\n }\n submitTestCaseResult(id, status, params) {\n this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => this.autoApi.submitTestCaseResult({\n status: status,\n testResultId: resultId,\n ...params,\n }));\n }\n async runnerEnd() {\n // Wait for all results to be created\n const resultIds = (await Promise.all(Object.values(this.uidToResultIdMap))) || [];\n // Wait for the results to be submitted\n void (await Promise.all(Object.values(this.resultSubmissionMap)));\n // Wait the heartbeat to be ended\n void (await this.heartbeatService.end());\n void (await this.autoApi.endTestRun(this.testRunId));\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 console.info(JSON.stringify(jsonArray));\n // this is the wdio.conf outputDir\n const outputPath = '.';\n writeFileSync(pathJoin(outputPath, 'providerUrls.txt'), JSON.stringify(jsonArray, null, 1));\n }\n }\n}\n//# sourceMappingURL=reporter.js.map","export var TestRunAutoResultStatus;\n(function (TestRunAutoResultStatus) {\n TestRunAutoResultStatus[\"PASSED\"] = \"PASSED\";\n TestRunAutoResultStatus[\"FAILED\"] = \"FAILED\";\n TestRunAutoResultStatus[\"SKIPPED\"] = \"SKIPPED\";\n TestRunAutoResultStatus[\"CANCELED\"] = \"CANCELED\";\n TestRunAutoResultStatus[\"ERROR\"] = \"ERROR\";\n})(TestRunAutoResultStatus || (TestRunAutoResultStatus = {}));\n//# sourceMappingURL=dto.js.map","import Validator from 'validator';\nconst validator = Validator.default;\nexport const DEFAULT_URL = 'https://api.applause.com/';\nexport const DEFAULT_PUBLIC_API_PROPERTIES = {\n publicApiBaseUrl: DEFAULT_URL,\n};\nexport function isPublicApiConfigComplete(config) {\n return (config.publicApiBaseUrl !== undefined &&\n config.apiKey !== undefined &&\n config.productId !== undefined);\n}\nexport function validatePartialPublicApiConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\nexport function validatePublicApiConfig(config) {\n if (!Number.isInteger(config.productId) || config.productId <= 0) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n if (!validator.isURL(config.publicApiBaseUrl, {\n protocols: ['http', 'https'],\n require_tld: false,\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 throw new Error(`publicApiBaseUrl is not valid HTTP/HTTPS URL, was: ${config.publicApiBaseUrl}`);\n }\n if (validator.isEmpty(config.apiKey)) {\n throw new Error('apiKey is an empty string!');\n }\n}\n//# sourceMappingURL=public-api-config.js.map","import axios from 'axios';\nimport { validatePublicApiConfig, } from './public-api-config.ts';\nexport class PublicApi {\n options;\n client;\n callsInFlight;\n /**\n * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished\n */\n get getCallsInFlight() {\n return this.callsInFlight;\n }\n constructor(options) {\n this.options = options;\n this.callsInFlight = 0;\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(function (response) {\n return response;\n }, function (error) {\n // log and rethrow\n const errText = \n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data !== undefined\n ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n error.data\n : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n `error-code [${error.response.status}] with error [${error.response.statusText}]`;\n console.error(`Public-Api returned ${errText}`);\n return Promise.reject(error);\n });\n }\n async submitResult(testCaseId, info) {\n this.callsInFlight += 1;\n try {\n return await this.client.post(`v2/test-case-results/${testCaseId}/submit`, info);\n }\n finally {\n this.callsInFlight -= 1;\n }\n }\n}\n//# sourceMappingURL=public-api.js.map","import { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { DEFAULT_AUTO_API_PROPERTIES, isAutoApiConfigComplete, validateAutoApiConfig, } from '../auto-api/auto-api-config.ts';\nimport { DEFAULT_PUBLIC_API_PROPERTIES, isPublicApiConfigComplete, validatePublicApiConfig, } from '../public-api/public-api-config.ts';\n// Loads the configuration\nexport function loadConfig(loadOptions) {\n // Setup the initial config with any default properties\n let config = {\n ...DEFAULT_PUBLIC_API_PROPERTIES,\n ...DEFAULT_AUTO_API_PROPERTIES,\n };\n // Load properties from the provided config file\n if (loadOptions !== undefined && loadOptions.configFile !== undefined) {\n config = overrideConfig(config, loadConfigFromFile(path.join(process.cwd(), loadOptions.configFile)));\n }\n else {\n // Override from the default config file\n config = overrideConfig(config, loadConfigFromFile());\n }\n // Then load in the file override properties\n if (loadOptions !== undefined && loadOptions.properties !== undefined) {\n config = overrideConfig(config, loadOptions.properties);\n }\n if (!isComplete(config)) {\n throw new Error('Config is not complete');\n }\n // We know that the config is complete, so we can cast\n const finalConfig = config;\n validateConfig(finalConfig);\n return finalConfig;\n}\nexport function overrideConfig(config, overrides) {\n return Object.assign({}, config, Object.fromEntries(Object.entries(overrides || {}).filter(([_, v]) => v !== undefined)));\n}\nexport function isComplete(config) {\n return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config);\n}\nexport function loadConfigFromFile(configFile) {\n const configFilePath = configFile || process.cwd() + '/applause.json';\n if (!existsSync(configFilePath)) {\n return {};\n }\n const fileCotents = readFileSync(configFilePath, 'utf8');\n return JSON.parse(fileCotents);\n}\nexport function validateConfig(config) {\n validateAutoApiConfig(config);\n validatePublicApiConfig(config);\n}\nexport function validatePartialConfig(config) {\n if (config.productId !== undefined &&\n (!Number.isInteger(config.productId) || config.productId <= 0)) {\n throw new Error(`productId must be a positive integer, was: '${config.productId}'`);\n }\n}\n//# sourceMappingURL=config.js.map"],"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 // 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 // Optional: an applause test cycle id\n itwTestCycleId?: number;\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/package.json b/package.json index 29fe941..b698e49 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.0.1", + "version": "1.1.0", "name": "applause-reporter-common", "umd:name": "applause-reporter-common", "repository": "https://github.com/ApplauseOSS/applause-reporter-common", @@ -64,8 +64,11 @@ }, "dependencies": { "axios": "^1.6.0", + "logform": "^2.6.0", "mailparser": "^3.6.5", "validator": "^13.11.0", + "winston": "^3.13.0", + "winston-transport": "^4.7.0", "yarn": "^1.22.19" } } diff --git a/src/auto-api/auto-api.ts b/src/auto-api/auto-api.ts index d6d9540..54481c7 100644 --- a/src/auto-api/auto-api.ts +++ b/src/auto-api/auto-api.ts @@ -1,5 +1,12 @@ +/** + * This file contains the implementation of the `AutoApi` class, which is responsible for making API calls to interact with the Applause platform. + * 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. + * It also includes properties and methods to track the number of HTTP calls in progress. + */ + import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; import { + AssetType, CreateTestCaseResultDto, CreateTestCaseResultResponseDto, EmailAddressResponse, @@ -11,20 +18,32 @@ import { } from './dto.ts'; import { API_VERSION } from './version.ts'; import { AutoApiConfig, validateAutoApiConfig } from './auto-api-config.ts'; +import { constructDefaultLogger } from '../shared/logging.ts'; +import * as winston from 'winston'; export class AutoApi { private readonly client: AxiosInstance; + private logger: winston.Logger; private callsInFlight: number; /** - * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished + * Tracks the number of HTTP calls in progress. + * This property is used by reporters that want to know when the async work is finished. */ public get getCallsInFlight(): number { return this.callsInFlight; } - constructor(readonly options: AutoApiConfig) { + /** + * Creates an instance of the `AutoApi` class. + * @param options - The configuration options for the Applause API. + */ + constructor( + readonly options: AutoApiConfig, + logger?: winston.Logger + ) { this.callsInFlight = 0; + this.logger = logger ?? constructDefaultLogger(); validateAutoApiConfig(options); this.client = axios.create({ baseURL: options.autoApiBaseUrl, @@ -35,23 +54,29 @@ export class AutoApi { }, responseType: 'json', }); + this.client.interceptors.response.use( function (response: AxiosResponse) { return response; }, - function (error: AxiosError) { + (error: AxiosError) => { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access error.response?.data !== undefined ? JSON.stringify(error.response.data) : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; - console.error(`Auto-Api returned ${errText}`); + this.logger.error(`Auto-Api returned ${errText}`); return Promise.reject(error); } ); } + /** + * Starts a new test run. + * @param info - The information for creating the test run. + * @returns A promise that resolves to the response containing the created test run. + */ async startTestRun( info: TestRunCreateDto ): Promise> { @@ -85,6 +110,11 @@ export class AutoApi { } } + /** + * Ends a test run. + * @param testRunId - The ID of the test run to end. + * @returns A promise that resolves to the response indicating the completion of the test run. + */ async endTestRun(testRunId: number): Promise> { this.callsInFlight += 1; try { @@ -96,6 +126,11 @@ export class AutoApi { } } + /** + * Starts a new test case. + * @param params - The parameters for creating the test case. + * @returns A promise that resolves to the response containing the created test case. + */ async startTestCase( params: CreateTestCaseResultDto ): Promise> { @@ -111,6 +146,11 @@ export class AutoApi { } } + /** + * Submits a test case result. + * @param params - The parameters for submitting the test case result. + * @returns A promise that resolves when the test case result is submitted. + */ async submitTestCaseResult(params: SubmitTestCaseResultDto): Promise { this.callsInFlight += 1; try { @@ -120,6 +160,11 @@ export class AutoApi { } } + /** + * Retrieves the provider session links for the specified test results. + * @param resultIds - The IDs of the test results. + * @returns A promise that resolves to the response containing the provider session links. + */ async getProviderSessionLinks( resultIds: number[] ): Promise> { @@ -136,6 +181,11 @@ export class AutoApi { } } + /** + * Sends a heartbeat for the specified test run. + * @param testRunId - The ID of the test run. + * @returns A promise that resolves to the response indicating the heartbeat was sent. + */ async sendSdkHeartbeat(testRunId: number): Promise> { this.callsInFlight += 1; try { @@ -148,6 +198,11 @@ export class AutoApi { } } + /** + * Retrieves the email address for the specified email prefix. + * @param emailPrefix - The prefix of the email address. + * @returns A promise that resolves to the response containing the email address. + */ async getEmailAddress( emailPrefix: string ): Promise> { @@ -162,6 +217,11 @@ export class AutoApi { } } + /** + * Retrieves the content of the specified email. + * @param request - The request parameters for retrieving the email content. + * @returns A promise that resolves to the response containing the email content. + */ async getEmailContent( request: EmailFetchRequest ): Promise> { @@ -176,4 +236,38 @@ export class AutoApi { this.callsInFlight -= 1; } } + + /** + * Uploads an asset for the specified test result. + * @param resultId - The ID of the test result. + * @param file - The file to upload as an asset. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The GUID of the provider session. + * @param assetType - The type of the asset. + * @returns A promise that resolves to the response indicating the asset was uploaded. + */ + async uploadAsset( + resultId: number, + file: Buffer, + assetName: string, + providerSessionGuid: string, + assetType: AssetType + ): Promise> { + this.callsInFlight += 1; + + try { + // this filters out falsy values (null, undefined, 0) + return await this.client.postForm( + `/api/v1.0/test-result/${resultId}/upload`, + { + file, + assetName, + providerSessionGuid, + assetType, + } + ); + } finally { + this.callsInFlight -= 1; + } + } } diff --git a/src/auto-api/dto.ts b/src/auto-api/dto.ts index edab69f..ca1a1ee 100644 --- a/src/auto-api/dto.ts +++ b/src/auto-api/dto.ts @@ -127,3 +127,25 @@ export interface EmailAddressResponse { export interface EmailFetchRequest { emailAddress: string; } + +export enum AssetType { + SCREENSHOT = 'SCREENSHOT', + FAILURE_SCREENSHOT = 'FAILURE_SCREENSHOT', + VIDEO = 'VIDEO', + NETWORK_HAR = 'NETWORK_HAR', + VITALS_LOG = 'VITALS_LOG', + CONSOLE_LOG = 'CONSOLE_LOG', + NETWORK_LOG = 'NETWORK_LOG', + DEVICE_LOG = 'DEVICE_LOG', + SELENIUM_LOG = 'SELENIUM_LOG', + SELENIUM_LOG_JSON = 'SELENIUM_LOG_JSON', + BROWSER_LOG = 'BROWSER_LOG', + FRAMEWORK_LOG = 'FRAMEWORK_LOG', + EMAIL = 'EMAIL', + PAGE_SOURCE = 'PAGE_SOURCE', + CODE_BUNDLE = 'CODE_BUNDLE', + RESULTS_ZIP = 'RESULTS_ZIP', + SESSION_DETAILS = 'SESSION_DETAILS', + DEVICE_DETAILS = 'DEVICE_DETAILS', + UNKNOWN = 'UNKNOWN', +} diff --git a/src/auto-api/email-helper.ts b/src/auto-api/email-helper.ts index b4bd23a..efb37d0 100644 --- a/src/auto-api/email-helper.ts +++ b/src/auto-api/email-helper.ts @@ -1,9 +1,18 @@ import { AutoApi } from './auto-api.ts'; import { Inbox } from './email/inbox.ts'; +/** + * Helper class for managing email functionality. + */ export class EmailHelper { constructor(private autoApi: AutoApi) {} + /** + * Retrieves the inbox for the specified email prefix. + * + * @param emailPrefix - The prefix used to generate the email address. + * @returns A Promise that resolves to an Inbox object. + */ async getInbox(emailPrefix: string): Promise { const generatedAddress: string = ( await this.autoApi.getEmailAddress(emailPrefix) diff --git a/src/auto-api/email/attachment.ts b/src/auto-api/email/attachment.ts index 1245418..734e9ad 100644 --- a/src/auto-api/email/attachment.ts +++ b/src/auto-api/email/attachment.ts @@ -1,4 +1,14 @@ +/** + * Represents an email attachment. + */ export interface Attachment { + /** + * The name of the file. + */ fileName: string; + + /** + * The content of the file as a Uint16Array. + */ context: Uint16Array; } diff --git a/src/auto-api/email/inbox.ts b/src/auto-api/email/inbox.ts index 8723663..0cfe0f8 100644 --- a/src/auto-api/email/inbox.ts +++ b/src/auto-api/email/inbox.ts @@ -1,12 +1,24 @@ import { AutoApi } from '../auto-api.ts'; import { ParsedMail, simpleParser } from 'mailparser'; +/** + * Represents an email inbox. + */ export class Inbox { + /** + * Creates an instance of Inbox. + * @param emailAddress - The email address associated with the inbox. + * @param autoApi - An instance of the AutoApi class. + */ constructor( public readonly emailAddress: string, private autoApi: AutoApi ) {} + /** + * Retrieves the content of an email from the inbox. + * @returns A Promise that resolves to the parsed email content. + */ async getEmail(): Promise { const res = await this.autoApi.getEmailContent({ emailAddress: this.emailAddress, diff --git a/src/auto-api/heartbeat.ts b/src/auto-api/heartbeat.ts index 9f2afe5..2d1be8e 100644 --- a/src/auto-api/heartbeat.ts +++ b/src/auto-api/heartbeat.ts @@ -1,23 +1,45 @@ +import winston = require('winston'); import { AutoApi } from './auto-api.ts'; +import { constructDefaultLogger } from '../shared/logging.ts'; +/** + * Represents a service for sending heartbeats during a test run. + */ export class TestRunHeartbeatService { private enabled = false; private nextHeartbeat?: Promise; + private readonly logger: winston.Logger; + /** + * Creates an instance of TestRunHeartbeatService. + * @param testRunId - The ID of the test run. + * @param autoApi - The AutoApi instance used for sending heartbeats. + */ constructor( readonly testRunId: number, - readonly autoApi: AutoApi - ) {} + readonly autoApi: AutoApi, + logger?: winston.Logger + ) { + this.logger = logger ?? constructDefaultLogger(); + } + /** + * Starts sending heartbeats. + * @returns A promise that resolves when the heartbeats are started. + */ async start(): Promise { // End the current heartbeat if it has started await this.end(); - // Set up va new interval + // Set up a new interval this.enabled = true; this.scheduleNextHeartbeat(); } + /** + * Checks if the heartbeats are enabled. + * @returns True if the heartbeats are enabled, false otherwise. + */ public isEnabled(): boolean { return this.enabled; } @@ -32,18 +54,22 @@ export class TestRunHeartbeatService { } private async sendHeartbeat(): Promise { - console.log('Sending heartbeat'); + this.logger.debug('Sending heartbeat'); await this.autoApi.sendSdkHeartbeat(this.testRunId); - console.log('Heartbeat sent'); + this.logger.debug('Heartbeat sent'); this.scheduleNextHeartbeat(); } + /** + * Ends the heartbeats. + * @returns A promise that resolves when the heartbeats are ended. + */ async end(): Promise { if (this.nextHeartbeat !== undefined) { this.enabled = false; - console.debug('Ending Applause SDK Heartbeat'); + this.logger.debug('Ending Applause SDK Heartbeat'); await this.nextHeartbeat; - console.debug('Applause SDK Heartbeat Ended Successfully'); + this.logger.debug('Applause SDK Heartbeat Ended Successfully'); } this.nextHeartbeat = undefined; } diff --git a/src/auto-api/reporter.ts b/src/auto-api/reporter.ts index 3e4001c..07b8d95 100644 --- a/src/auto-api/reporter.ts +++ b/src/auto-api/reporter.ts @@ -3,64 +3,128 @@ import { AutoApi } from './auto-api.ts'; import { AdditionalTestCaseParams, AdditionalTestCaseResultParams, + AssetType, TestResultStatus, } from './dto.ts'; import { TestRunHeartbeatService } from './heartbeat.ts'; import { join as pathJoin } from 'path'; import { AutoApiConfig } from './auto-api-config.ts'; import { parseTestCaseName } from '../shared/test-case.ts'; +import * as winston from 'winston'; +import { constructDefaultLogger } from '../shared/logging.ts'; +/** + * Represents an Applause reporter. + */ export class ApplauseReporter { private autoApi: AutoApi; private initializer: RunInitializer; + private logger: winston.Logger; private reporter?: Promise; private runStarted: boolean = false; private runFinished: boolean = false; - constructor(config: AutoApiConfig) { - this.autoApi = new AutoApi(config); - this.initializer = new RunInitializer(this.autoApi); + /** + * Creates an instance of ApplauseReporter. + * @param config - The Applause configuration. + */ + constructor(config: AutoApiConfig, logger?: winston.Logger) { + this.logger = logger ?? constructDefaultLogger(); + this.autoApi = new AutoApi(config, this.logger); + this.initializer = new RunInitializer(this.autoApi, this.logger); + const runId = process.env['APPLAUSE_RUN_ID']; + if (runId !== undefined) { + const r = new RunReporter( + this.autoApi, + parseInt(runId), + undefined, + this.logger + ); + this.reporter = new Promise(resolve => resolve(r)); + this.runStarted = true; + } } - public runnerStart(tests?: string[]): void { + /** + * Starts the Applause runner. + * @param tests - Optional array of test names to run. + * @returns A promise that resolves to the test run ID. + * @throws Error if a run is already started or finished. + */ + public async runnerStart(tests?: string[]): Promise { + if (this.reporter !== undefined) { + this.logger.error( + 'Cannot start a run - run already started or run already finished' + ); + throw new Error( + 'Cannot start a run - run already started or run already finished' + ); + } this.reporter = this.initializer.initializeRun(tests); - void this.reporter.then(() => { - this.runStarted = true; - }); + const initializedReporter = await this.reporter; + this.runStarted = true; + process.env['APPLAUSE_RUN_ID'] = initializedReporter.testRunId.toString(); + return initializedReporter.testRunId; } - public startTestCase( + /** + * Starts a test case. + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Optional additional parameters for the test case. + * @returns A promise that resolves to the test case ID. + * @throws Error if a run was never initialized. + */ + public async startTestCase( id: string, testCaseName: string, params?: AdditionalTestCaseParams - ): void { + ): Promise { if (this.reporter === undefined) { + this.logger.error( + 'Cannot start a test case for a run that was never initialized' + ); throw new Error( 'Cannot start a test case for a run that was never initialized' ); } - void this.reporter.then(reporter => - reporter.startTestCase(id, testCaseName, params) - ); + const reporter = await this.reporter; + return reporter.startTestCase(id, testCaseName, params); } - public submitTestCaseResult( + /** + * Submits a test case result. + * @param id - The ID of the test case. + * @param status - The status of the test case result. + * @param params - Optional additional parameters for the test case result. + * @returns A promise that resolves to the test case result ID. + * @throws Error if a run was never initialized. + */ + public async submitTestCaseResult( id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams - ): void { + ): Promise { if (this.reporter === undefined) { + this.logger.error( + 'Cannot submit test case result for a run that was never initialized' + ); throw new Error( 'Cannot submit test case result for a run that was never initialized' ); } - void this.reporter.then(reporter => - reporter.submitTestCaseResult(id, status, params) - ); + const reporter = await this.reporter; + return reporter.submitTestCaseResult(id, status, params); } + /** + * Ends the Applause runner. + * @returns A promise that resolves when the runner is ended. + * @throws Error if a run was never initialized. + */ public async runnerEnd(): Promise { if (this.reporter === undefined) { + this.logger.error('Cannot end a run that was never initialized'); throw new Error('Cannot end a run that was never initialized'); } await this.reporter @@ -68,8 +132,47 @@ export class ApplauseReporter { .then(() => (this.runFinished = true)); } + /** + * Attaches an asset to a test case. + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset data as a Buffer. + * @returns A promise that resolves when the asset is attached. + * @throws Error if a run was never initialized. + */ + public async attachTestCaseAsset( + id: string, + assetName: string, + providerSessionGuid: string, + assetType: AssetType, + asset: Buffer + ): Promise { + if (this.reporter === undefined) { + this.logger.error( + 'Cannot attach an asset for a run that was never initialized' + ); + throw new Error( + 'Cannot attach an asset for a run that was never initialized' + ); + } + return await this.reporter.then(reporter => + reporter.attachTestCaseAsset( + id, + assetName, + providerSessionGuid, + assetType, + asset + ) + ); + } + + /** + * Checks if the Applause runner is synchronized. + * @returns True if the runner is not yet started or has ended, and all calls made to the applause API have finished. + */ public isSynchronized(): boolean { - // Verify the run is not yet started or it has ended, and all calls made to the applause api have finished return ( (!this.runStarted || (this.runStarted && this.runFinished)) && this.autoApi.getCallsInFlight == 0 @@ -77,47 +180,94 @@ export class ApplauseReporter { } } +/** + * Represents a Run Initializer. + */ export class RunInitializer { - constructor(private autoApi: AutoApi) {} + private logger: winston.Logger; + constructor( + private autoApi: AutoApi, + logger?: winston.Logger + ) { + this.logger = logger ?? constructDefaultLogger(); + } + /** + * Initializes a test run. + * @param tests - An optional array of test names to include in the run. + * @returns A promise that resolves to a RunReporter instance. + * @throws An error if unable to create the test run. + */ async initializeRun(tests?: string[]): Promise { const cleanedTests = tests - ?.map(parseTestCaseName) + ?.map(testName => parseTestCaseName(testName, this.logger)) .map(parsed => parsed.testCaseName.trim()); const testRunCreateResponse = await this.autoApi.startTestRun({ - tests: cleanedTests || [], + tests: cleanedTests ?? [], }); if ( testRunCreateResponse.status < 200 || testRunCreateResponse.status > 300 ) { + this.logger.error( + `Failed to create Applause Test Run: received error response with status ${testRunCreateResponse.status}.` + ); throw new Error('Unable to create test run'); } const runId = testRunCreateResponse.data.runId; - console.log('Test Run %d initialized', runId); - const heartbeatService = new TestRunHeartbeatService(runId, this.autoApi); + this.logger.info(`Test Run ${runId} initialized`); + const heartbeatService = new TestRunHeartbeatService( + runId, + this.autoApi, + this.logger + ); await heartbeatService.start(); - return new RunReporter(this.autoApi, runId, heartbeatService); + return new RunReporter(this.autoApi, runId, heartbeatService, this.logger); } } +/** + * Handles reporting test results to the Applause API. + */ export class RunReporter { private uidToResultIdMap: Record> = {}; - private resultSubmissionMap: Record> = {}; + private resultSubmissionMap: Record> = {}; + private logger: winston.Logger; + /** + * Creates a new instance of the Reporter class. + * @param autoApi - The AutoApi instance. + * @param testRunId - The ID of the test run. + * @param heartbeatService - (Optional) The TestRunHeartbeatService instance. + */ constructor( private autoApi: AutoApi, - private testRunId: number, - private heartbeatService: TestRunHeartbeatService - ) {} + public readonly testRunId: number, + private heartbeatService?: TestRunHeartbeatService, + logger?: winston.Logger + ) { + this.logger = logger ?? constructDefaultLogger(); + } + /** + * Starts a test case and returns a promise that resolves to the test result ID. + * + * @param id - The ID of the test case. + * @param testCaseName - The name of the test case. + * @param params - Additional parameters for the test case. + * @returns A promise that resolves to the test result ID. + */ public startTestCase( id: string, testCaseName: string, params?: AdditionalTestCaseParams - ): void { - const parsedTestCase = parseTestCaseName(testCaseName); - this.uidToResultIdMap[id] = this.autoApi + ): Promise { + if (!testCaseName) { + this.logger.error('testCaseName is required'); + throw new Error('testCaseName is required'); + } + const parsedTestCase = parseTestCaseName(testCaseName, this.logger); + const submission = this.autoApi .startTestCase({ testCaseName: parsedTestCase.testCaseName, testCaseId: parsedTestCase.testRailTestCaseId, @@ -132,39 +282,85 @@ export class RunReporter { .then(res => { return res.data.testResultId; }); + this.uidToResultIdMap[id] = submission; + return submission; } + /** + * Submits the result of a test case. + * + * @param id - The ID of the test case. + * @param status - The status of the test result. + * @param params - Additional parameters for the test result. + * @returns A promise that resolves to the result ID. + */ public submitTestCaseResult( id: string, status: TestResultStatus, params?: AdditionalTestCaseResultParams - ): void { - this.resultSubmissionMap[id] = this.uidToResultIdMap[id]?.then(resultId => - this.autoApi.submitTestCaseResult({ - status: status, - testResultId: resultId, - ...params, - }) + ): Promise { + const submission = this.uidToResultIdMap[id]?.then(resultId => + this.autoApi + .submitTestCaseResult({ + status: status, + testResultId: resultId, + ...params, + }) + .then(() => resultId) + ); + this.resultSubmissionMap[id] = submission; + return submission; + } + + /** + * Attaches a test case asset to a result. + * + * @param id - The ID of the test case. + * @param assetName - The name of the asset. + * @param providerSessionGuid - The provider session GUID. + * @param assetType - The type of the asset. + * @param asset - The asset to attach. + * @returns A promise that resolves when the asset is attached. + */ + public async attachTestCaseAsset( + id: string, + assetName: string, + providerSessionGuid: string, + assetType: AssetType, + asset: Buffer + ): Promise { + await this.uidToResultIdMap[id]?.then(resultId => + this.autoApi.uploadAsset( + resultId, + asset, + assetName, + providerSessionGuid, + assetType + ) ); } + /** + * Ends the test runner and performs necessary cleanup tasks. + * @returns A promise that resolves when the runner has ended. + */ public async runnerEnd(): Promise { // Wait for all results to be created const resultIds = - (await Promise.all(Object.values(this.uidToResultIdMap))) || []; + (await Promise.all(Object.values(this.uidToResultIdMap))) ?? []; // Wait for the results to be submitted void (await Promise.all(Object.values(this.resultSubmissionMap))); // Wait the heartbeat to be ended - void (await this.heartbeatService.end()); + void (await this.heartbeatService?.end()); void (await this.autoApi.endTestRun(this.testRunId)); // Fetch the provider session asset links and save them off to a file const resp = await this.autoApi.getProviderSessionLinks(resultIds); - const jsonArray = resp.data || []; + const jsonArray = resp.data ?? []; if (jsonArray.length > 0) { - console.info(JSON.stringify(jsonArray)); + this.logger.info(JSON.stringify(jsonArray)); // this is the wdio.conf outputDir const outputPath = '.'; writeFileSync( diff --git a/src/auto-api/version.ts b/src/auto-api/version.ts index 3c76b58..37cd57f 100644 --- a/src/auto-api/version.ts +++ b/src/auto-api/version.ts @@ -1 +1 @@ -export const API_VERSION = '1.0.0'; +export const API_VERSION = '1.1.0'; diff --git a/src/config/config.ts b/src/config/config.ts index 5aa9d90..f80641b 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -1,3 +1,6 @@ +/** + * Represents the configuration options for the Applause Reporter. + */ import { existsSync, readFileSync } from 'fs'; import path from 'path'; @@ -16,12 +19,20 @@ import { export type ApplauseConfig = AutoApiConfig & PublicApiConfig; +/** + * Represents the properties for loading the configuration. + */ export interface ConfigLoadProperties { configFile?: string; properties?: Partial; } -// Loads the configuration +/** + * Loads the configuration for the Applause Reporter. + * @param loadOptions - The options for loading the configuration. + * @returns The loaded Applause configuration. + * @throws Error if the configuration is not complete or invalid. + */ export function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig { // Setup the initial config with any default properties let config: Partial = { @@ -57,6 +68,12 @@ export function loadConfig(loadOptions?: ConfigLoadProperties): ApplauseConfig { return finalConfig; } +/** + * Overrides the configuration with the provided overrides. + * @param config - The base configuration. + * @param overrides - The overrides to apply. + * @returns The overridden configuration. + */ export function overrideConfig( config: Partial, overrides?: Partial @@ -65,31 +82,51 @@ export function overrideConfig( {}, config, Object.fromEntries( - Object.entries(overrides || {}).filter(([_, v]) => v !== undefined) + Object.entries(overrides ?? {}).filter(([_, v]) => v !== undefined) ) ); } +/** + * Checks if the configuration is complete. + * @param config - The configuration to check. + * @returns True if the configuration is complete, false otherwise. + */ export function isComplete(config: Partial): boolean { return isAutoApiConfigComplete(config) && isPublicApiConfigComplete(config); } +/** + * Loads the configuration from the specified file. + * @param configFile - The path to the configuration file. + * @returns The loaded configuration from the file. + */ export function loadConfigFromFile( configFile?: string ): Partial { - const configFilePath = configFile || process.cwd() + '/applause.json'; + const configFilePath = configFile ?? `${process.cwd()}/applause.json`; if (!existsSync(configFilePath)) { return {}; } - const fileCotents = readFileSync(configFilePath, 'utf8'); - return JSON.parse(fileCotents) as Partial; + const fileContents = readFileSync(configFilePath, 'utf8'); + return JSON.parse(fileContents) as Partial; } +/** + * Validates the configuration. + * @param config - The configuration to validate. + * @throws Error if the configuration is invalid. + */ export function validateConfig(config: ApplauseConfig) { validateAutoApiConfig(config); validatePublicApiConfig(config); } +/** + * Validates a partial configuration. + * @param config - The partial configuration to validate. + * @throws Error if the partial configuration is invalid. + */ export function validatePartialConfig(config: Partial) { if ( config.productId !== undefined && diff --git a/src/public-api/public-api.ts b/src/public-api/public-api.ts index b7637d7..87809d9 100644 --- a/src/public-api/public-api.ts +++ b/src/public-api/public-api.ts @@ -1,14 +1,17 @@ -import axios, { AxiosInstance, AxiosResponse } from 'axios'; +import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios'; import { TestRunAutoResultDto } from './dto.ts'; import { PublicApiConfig, validatePublicApiConfig, } from './public-api-config.ts'; +import * as winston from 'winston'; +import { constructDefaultLogger } from '../shared/logging.ts'; export class PublicApi { private readonly client: AxiosInstance; private callsInFlight: number; + private logger: winston.Logger; /** * tracks number of HTTP calls in progress, used by reporters that want to know when our async work is finished */ @@ -16,8 +19,12 @@ export class PublicApi { return this.callsInFlight; } - constructor(readonly options: PublicApiConfig) { + constructor( + readonly options: PublicApiConfig, + logger?: winston.Logger + ) { this.callsInFlight = 0; + this.logger = logger ?? constructDefaultLogger(); validatePublicApiConfig(options); this.client = axios.create({ baseURL: options.publicApiBaseUrl, @@ -32,16 +39,14 @@ export class PublicApi { function (response: AxiosResponse) { return response; }, - function (error) { + (error: AxiosError) => { // log and rethrow const errText = // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data !== undefined - ? // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - error.data - : // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - `error-code [${error.response.status}] with error [${error.response.statusText}]`; - console.error(`Public-Api returned ${errText}`); + error.response?.data !== undefined + ? JSON.stringify(error.response.data) + : `error-code [${error.response?.status}] with error [${error.response?.statusText}]`; + this.logger.error(`Public-Api returned ${errText}`); return Promise.reject(error); } ); diff --git a/src/shared/index.ts b/src/shared/index.ts index 6e0d833..d20d661 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -1 +1,2 @@ export * from './test-case.ts'; +export * from './logging.ts'; diff --git a/src/shared/logging.ts b/src/shared/logging.ts new file mode 100644 index 0000000..6ad57b2 --- /dev/null +++ b/src/shared/logging.ts @@ -0,0 +1,102 @@ +import * as winston from 'winston'; +import { TransformableInfo } from 'logform'; +import TransportStream from 'winston-transport'; +const MESSAGE = Symbol.for('message'); + +export const WINSTON_DEFAULT_LOG_FORMAT = winston.format.printf( + ({ level, message, label, timestamp }) => { + return `${timestamp} [${label}] ${level}: ${message}`; + } +); + +export function constructDefaultLogger(): winston.Logger { + return winston.createLogger({ + format: winston.format.combine( + winston.format.label({ label: 'Applause Tests' }), + winston.format.timestamp(), + winston.format.splat(), + WINSTON_DEFAULT_LOG_FORMAT + ), + transports: [ + new winston.transports.File({ filename: 'error.log', level: 'error' }), + new winston.transports.File({ filename: 'combined.log' }), + new ApplauseTransport(), + new winston.transports.Console({ + level: 'info', + format: winston.format.combine( + winston.format.colorize(), + WINSTON_DEFAULT_LOG_FORMAT + ), + }), + ], + }); +} + +/** + * A simple Class for storing and retrieving log messages. + */ +export class LoggingContainer { + private logs: string[] = []; + + /** + * Retrieves all logs stored in the container. + * + * @returns An array of log messages. + */ + public getLogs(): string[] { + return this.logs; + } + + /** + * Retrieves and clears all logs stored in the container. + * + * @returns An array of log messages. + */ + public drainLogs(): string[] { + const logs = this.logs; + this.clearLogs(); + return logs; + } + + /** + * Clears all logs stored in the container. + */ + public clearLogs(): void { + this.logs = []; + } + + /** + * Adds a log message to the container. + * + * @param log - The log message to add. + */ + public addLog(log: string): void { + this.logs.push(log); + } +} + +// Create a new Shared LoggingContainer to store logs +export const APPLAUSE_LOG_RECORDS: LoggingContainer = new LoggingContainer(); + +/** + * A Custom Winston Transport that sends logs to the Applause LoggingContainer + */ +export class ApplauseTransport extends TransportStream { + constructor(opts?: TransportStream.TransportStreamOptions) { + super(opts); + } + + log(info: TransformableInfo, callback: () => void): void { + setImmediate(() => { + this.emit('logged', info); + }); + + this.format?.transform(info); + APPLAUSE_LOG_RECORDS.addLog( + (info[MESSAGE] as string | undefined) ?? (info.message as string) + ); + + // Continue to the next transport + callback(); + } +} diff --git a/src/shared/test-case.ts b/src/shared/test-case.ts index b59cd80..4d03728 100644 --- a/src/shared/test-case.ts +++ b/src/shared/test-case.ts @@ -1,22 +1,31 @@ +import * as winston from 'winston'; + export const TEST_RAIL_CASE_ID_PREFIX: string = 'TestRail-'; export const APPLAUSE_CASE_ID_PREFIX: string = 'Applause-'; -export function parseTestCaseName(testCaseName: string): ParsedTestCaseName { +export function parseTestCaseName( + testCaseName: string, + logger?: winston.Logger +): ParsedTestCaseName { const matches = testCaseName.match(/(TestRail-\d+|Applause-\d+)/g); const testRailCaseIds = matches ?.filter(match => match.startsWith(TEST_RAIL_CASE_ID_PREFIX)) - .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) || []; + .map(match => match.substring(TEST_RAIL_CASE_ID_PREFIX.length)) ?? []; const applauseCaseIds = matches ?.filter(match => match.startsWith(APPLAUSE_CASE_ID_PREFIX)) - .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) || []; + .map(match => match.substring(APPLAUSE_CASE_ID_PREFIX.length)) ?? []; if (testRailCaseIds.length > 1) { - console.warn('Multiple TestRail case ids detected in testCase name'); + (logger ?? console).warn( + 'Multiple TestRail case ids detected in testCase name' + ); } if (applauseCaseIds.length > 1) { - console.warn('Multiple Applause case ids detected in testCase name'); + (logger ?? console).warn( + 'Multiple Applause case ids detected in testCase name' + ); } return { applauseTestCaseId: applauseCaseIds[0], diff --git a/test/logging.test.ts b/test/logging.test.ts new file mode 100644 index 0000000..6a0ccef --- /dev/null +++ b/test/logging.test.ts @@ -0,0 +1,128 @@ +import * as winston from 'winston'; +import { LoggingContainer, ApplauseTransport, APPLAUSE_LOG_RECORDS } from '../src/shared/logging.ts'; + +describe('LoggingContainer', () => { + let loggingContainer: LoggingContainer; + + beforeEach(() => { + loggingContainer = new LoggingContainer(); + }); + + it('should add logs', () => { + loggingContainer.addLog('Log 1'); + loggingContainer.addLog('Log 2'); + + expect(loggingContainer.getLogs()).toEqual(['Log 1', 'Log 2']); + }); + + it('should clear logs', () => { + loggingContainer.addLog('Log 1'); + loggingContainer.addLog('Log 2'); + loggingContainer.clearLogs(); + + expect(loggingContainer.getLogs()).toEqual([]); + }); +}); + +describe('ApplauseTransport', () => { + let applauseTransport: ApplauseTransport; + + beforeEach(() => { + applauseTransport = new ApplauseTransport(); + }); + + afterEach(() => { + APPLAUSE_LOG_RECORDS.clearLogs(); + }); + + it('should log information', () => { + const logs: string[] = []; + + applauseTransport.log({message: 'Log 1', level: 'info'}, () => { + logs.push('Log 1'); + }); + + applauseTransport.log({message: 'Log 2', level: 'info'}, () => { + logs.push('Log 2'); + }); + + expect(APPLAUSE_LOG_RECORDS.getLogs()).toEqual(logs); + }); +}); + +describe('ApplauseTransport - Formated', () => { + let applauseTransport: ApplauseTransport; + + beforeEach(() => { + applauseTransport = new ApplauseTransport({ + format: winston.format.printf((info) => 'Applause: ' + info.message), + }); + }); + + afterEach(() => { + APPLAUSE_LOG_RECORDS.clearLogs(); + }); + + it('should log information', () => { + const logs: string[] = []; + + applauseTransport.log({message: 'Log 1', level: 'info'}, () => { + logs.push('Applause: Log 1'); + }); + + applauseTransport.log({message: 'Log 2', level: 'info'}, () => { + logs.push('Applause: Log 2'); + }); + + expect(APPLAUSE_LOG_RECORDS.getLogs()).toEqual(logs); + }); +}); + +describe('Winston Logger Using Applause Transport', () => { + let logger: winston.Logger; + + beforeEach(() => { + logger = winston.createLogger({ + level: 'info', + format: winston.format.printf((info) => info.message), + transports: [ + new ApplauseTransport(), + ], + }); + }); + + afterEach(() => { + APPLAUSE_LOG_RECORDS.clearLogs(); + }); + + it('should log information', () => { + logger.info('Log 1'); + logger.info('Log 2'); + + expect(APPLAUSE_LOG_RECORDS.getLogs()).toEqual(['Log 1', 'Log 2']); + }); +}) +describe('Winston Logger Using Applause Transport and format', () => { + let logger: winston.Logger; + + beforeEach(() => { + logger = winston.createLogger({ + level: 'info', + format: winston.format.printf((info) => 'Applause ' + info.message), + transports: [ + new ApplauseTransport(), + ], + }); + }); + + afterEach(() => { + APPLAUSE_LOG_RECORDS.clearLogs(); + }); + + it('should log information', () => { + logger.info('Log 1'); + logger.info('Log 2'); + + expect(APPLAUSE_LOG_RECORDS.getLogs()).toEqual(['Applause Log 1', 'Applause Log 2']); + }); +}) diff --git a/tsconfig.json b/tsconfig.json index 252e790..0d6a442 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,6 +27,7 @@ "noUnusedParameters": true, "emitDeclarationOnly": true, "allowImportingTsExtensions": true, + "esModuleInterop": true, "pretty": true }, "include": [ diff --git a/yarn.lock b/yarn.lock index c65d3bd..87097ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,386 +2,332 @@ # yarn lockfile v1 -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - "@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13": - version "7.22.13" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== dependencies: - "@babel/highlight" "^7.22.13" - chalk "^2.4.2" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.24.1": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" - integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.2", "@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== dependencies: - "@babel/highlight" "^7.24.2" + "@babel/highlight" "^7.24.7" picocolors "^1.0.0" -"@babel/compat-data@^7.22.9": - version "7.22.9" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz" - integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== +"@babel/compat-data@^7.25.2": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.4.tgz#7d2a80ce229890edcf4cc259d4d696cb4dae2fcb" + integrity sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ== -"@babel/core@^7.11.6", "@babel/core@^7.12.3": - version "7.22.17" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.17.tgz" - integrity sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ== +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77" + integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.22.15" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.22.17" - "@babel/helpers" "^7.22.15" - "@babel/parser" "^7.22.16" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.22.17" - "@babel/types" "^7.22.17" - convert-source-map "^1.7.0" + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/helper-compilation-targets" "^7.25.2" + "@babel/helper-module-transforms" "^7.25.2" + "@babel/helpers" "^7.25.0" + "@babel/parser" "^7.25.0" + "@babel/template" "^7.25.0" + "@babel/traverse" "^7.25.2" + "@babel/types" "^7.25.2" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.22.15", "@babel/generator@^7.7.2": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz" - integrity sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA== +"@babel/generator@^7.25.0", "@babel/generator@^7.25.6", "@babel/generator@^7.7.2": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.6.tgz#0df1ad8cb32fe4d2b01d8bf437f153d19342a87c" + integrity sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw== dependencies: - "@babel/types" "^7.22.15" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.1.tgz#e67e06f68568a4ebf194d1c6014235344f0476d0" - integrity sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A== - dependencies: - "@babel/types" "^7.24.0" + "@babel/types" "^7.25.6" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" -"@babel/helper-compilation-targets@^7.22.15": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz" - integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== +"@babel/helper-compilation-targets@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" + integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.15" - browserslist "^4.21.9" + "@babel/compat-data" "^7.25.2" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - -"@babel/helper-environment-visitor@^7.22.5": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz" - integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== - -"@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-module-imports@^7.22.15": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== - dependencies: - "@babel/types" "^7.22.15" - -"@babel/helper-module-transforms@^7.22.17": - version "7.22.17" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz" - integrity sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.15" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - -"@babel/helper-string-parser@^7.23.4": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" - integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== - -"@babel/helper-validator-identifier@^7.22.15", "@babel/helper-validator-identifier@^7.22.5": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz" - integrity sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ== - -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== - -"@babel/helpers@^7.22.15": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz" - integrity sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/highlight@^7.22.13": - version "7.22.13" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz" - integrity sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ== - dependencies: - "@babel/helper-validator-identifier" "^7.22.5" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/highlight@^7.24.2": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" - integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" +"@babel/helper-module-imports@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-module-transforms@^7.25.2": + version "7.25.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" + integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== + dependencies: + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + "@babel/traverse" "^7.25.2" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" + integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== + +"@babel/helper-simple-access@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" + integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + +"@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== + +"@babel/helpers@^7.25.0": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.6.tgz#57ee60141829ba2e102f30711ffe3afab357cc60" + integrity sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q== + dependencies: + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.6" + +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" chalk "^2.4.2" js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.22.16": - version "7.22.16" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz" - integrity sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA== - -"@babel/parser@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.1.tgz#1e416d3627393fab1cb5b0f2f1796a100ae9133a" - integrity sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.25.0", "@babel/parser@^7.25.6": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.6.tgz#85660c5ef388cbbf6e3d2a694ee97a38f18afe2f" + integrity sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q== + dependencies: + "@babel/types" "^7.25.6" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-bigint@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-import-attributes@^7.24.7": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz#6d4c78f042db0e82fd6436cd65fec5dc78ad2bde" + integrity sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.8" + +"@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-jsx@^7.7.2": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz" - integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" + integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.8.3": +"@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.8.3": +"@babel/plugin-syntax-private-property-in-object@^7.14.5": version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.22.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/template@^7.22.15", "@babel/template@^7.3.3": - version "7.22.15" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/traverse@^7.22.15", "@babel/traverse@^7.22.17": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" - integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ== - dependencies: - "@babel/code-frame" "^7.24.1" - "@babel/generator" "^7.24.1" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.24.1" - "@babel/types" "^7.24.0" + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz#04db9ce5a9043d9c635e75ae7969a2cd50ca97ff" + integrity sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.8" + +"@babel/template@^7.25.0", "@babel/template@^7.3.3": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" + integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" + +"@babel/traverse@^7.24.7", "@babel/traverse@^7.25.2": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41" + integrity sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.6" + "@babel/parser" "^7.25.6" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.6" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.17", "@babel/types@^7.22.5", "@babel/types@^7.3.3": - version "7.22.17" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz" - integrity sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.15" - to-fast-properties "^2.0.0" - -"@babel/types@^7.23.0", "@babel/types@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" - integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.25.6", "@babel/types@^7.3.3": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.6.tgz#893942ddb858f32ae7a004ec9d3a76b3463ef8e6" + integrity sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw== dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": version "0.2.3" - resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@colors/colors@1.6.0", "@colors/colors@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0" + integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" - resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@dabh/diagnostics@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a" + integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.8.0" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz" - integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg== + version "4.11.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" + integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== -"@eslint/eslintrc@^2.1.2": - version "2.1.2" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz" - integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -393,33 +339,33 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.49.0": - version "8.49.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz" - integrity sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w== +"@eslint/js@8.57.0": + version "8.57.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" + integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== -"@humanwhocodes/config-array@^0.11.11": - version "0.11.11" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz" - integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== +"@humanwhocodes/config-array@^0.11.14": + version "0.11.14" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" minimatch "^3.0.5" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" - resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: camelcase "^5.3.1" @@ -428,32 +374,32 @@ js-yaml "^3.13.1" resolve-from "^5.0.0" -"@istanbuljs/schema@^0.1.2": +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" - resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz" - integrity sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw== +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== dependencies: "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.6.3" - jest-util "^29.6.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" slash "^3.0.0" -"@jest/core@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz" - integrity sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg== +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== dependencies: - "@jest/console" "^29.6.4" - "@jest/reporters" "^29.6.4" - "@jest/test-result" "^29.6.4" - "@jest/transform" "^29.6.4" + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" "@jest/types" "^29.6.3" "@types/node" "*" ansi-escapes "^4.2.1" @@ -461,80 +407,80 @@ ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^29.6.3" - jest-config "^29.6.4" - jest-haste-map "^29.6.4" - jest-message-util "^29.6.3" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" jest-regex-util "^29.6.3" - jest-resolve "^29.6.4" - jest-resolve-dependencies "^29.6.4" - jest-runner "^29.6.4" - jest-runtime "^29.6.4" - jest-snapshot "^29.6.4" - jest-util "^29.6.3" - jest-validate "^29.6.3" - jest-watcher "^29.6.4" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" micromatch "^4.0.4" - pretty-format "^29.6.3" + pretty-format "^29.7.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz" - integrity sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ== +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== dependencies: - "@jest/fake-timers" "^29.6.4" + "@jest/fake-timers" "^29.7.0" "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.3" + jest-mock "^29.7.0" -"@jest/expect-utils@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.4.tgz" - integrity sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg== +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== dependencies: jest-get-type "^29.6.3" -"@jest/expect@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.6.4.tgz" - integrity sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA== +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== dependencies: - expect "^29.6.4" - jest-snapshot "^29.6.4" + expect "^29.7.0" + jest-snapshot "^29.7.0" -"@jest/fake-timers@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz" - integrity sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw== +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== dependencies: "@jest/types" "^29.6.3" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.6.3" - jest-mock "^29.6.3" - jest-util "^29.6.3" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" -"@jest/globals@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.6.4.tgz" - integrity sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA== +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== dependencies: - "@jest/environment" "^29.6.4" - "@jest/expect" "^29.6.4" + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" "@jest/types" "^29.6.3" - jest-mock "^29.6.3" + jest-mock "^29.7.0" -"@jest/reporters@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz" - integrity sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g== +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.6.4" - "@jest/test-result" "^29.6.4" - "@jest/transform" "^29.6.4" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" "@jest/types" "^29.6.3" "@jridgewell/trace-mapping" "^0.3.18" "@types/node" "*" @@ -548,9 +494,9 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.6.3" - jest-util "^29.6.3" - jest-worker "^29.6.4" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" @@ -558,44 +504,44 @@ "@jest/schemas@^29.6.3": version "29.6.3" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: "@sinclair/typebox" "^0.27.8" "@jest/source-map@^29.6.3": version "29.6.3" - resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== dependencies: "@jridgewell/trace-mapping" "^0.3.18" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz" - integrity sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ== +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== dependencies: - "@jest/console" "^29.6.4" + "@jest/console" "^29.7.0" "@jest/types" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz" - integrity sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg== +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== dependencies: - "@jest/test-result" "^29.6.4" + "@jest/test-result" "^29.7.0" graceful-fs "^4.2.9" - jest-haste-map "^29.6.4" + jest-haste-map "^29.7.0" slash "^3.0.0" -"@jest/transform@^29.6.4": - version "29.6.4" - resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.6.4.tgz" - integrity sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA== +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== dependencies: "@babel/core" "^7.11.6" "@jest/types" "^29.6.3" @@ -605,9 +551,9 @@ convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.6.4" + jest-haste-map "^29.7.0" jest-regex-util "^29.6.3" - jest-util "^29.6.3" + jest-util "^29.7.0" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" @@ -615,7 +561,7 @@ "@jest/types@^29.6.3": version "29.6.3" - resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: "@jest/schemas" "^29.6.3" @@ -625,15 +571,6 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -644,14 +581,9 @@ "@jridgewell/trace-mapping" "^0.3.24" "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/set-array@^1.2.1": version "1.2.1" @@ -659,35 +591,27 @@ integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== "@jridgewell/source-map@^0.3.3": - version "0.3.5" - resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz" - integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + version "0.3.6" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== "@jridgewell/trace-mapping@0.3.9": version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.19" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -697,7 +621,7 @@ "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -705,39 +629,32 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@pkgr/utils@^2.3.1": - version "2.4.2" - resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz" - integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== - dependencies: - cross-spawn "^7.0.3" - fast-glob "^3.3.0" - is-glob "^4.0.3" - open "^9.1.0" - picocolors "^1.0.0" - tslib "^2.6.0" +"@pkgr/core@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== "@rollup/plugin-json@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.0.0.tgz" - integrity sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w== + version "6.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.1.0.tgz#fbe784e29682e9bb6dee28ea75a1a83702e7b805" + integrity sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA== dependencies: - "@rollup/pluginutils" "^5.0.1" + "@rollup/pluginutils" "^5.1.0" "@rollup/plugin-node-resolve@15.2.1": version "15.2.1" - resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz#a15b14fb7969229e26a30feff2816d39eff503f0" integrity sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w== dependencies: "@rollup/pluginutils" "^5.0.1" @@ -748,26 +665,26 @@ resolve "^1.22.1" "@rollup/plugin-terser@^0.4.3": - version "0.4.3" - resolved "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.3.tgz" - integrity sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA== + version "0.4.4" + resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz#15dffdb3f73f121aa4fbb37e7ca6be9aeea91962" + integrity sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A== dependencies: serialize-javascript "^6.0.1" smob "^1.0.0" terser "^5.17.4" "@rollup/plugin-typescript@^11.1.3": - version "11.1.3" - resolved "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz" - integrity sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA== + version "11.1.6" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz#724237d5ec12609ec01429f619d2a3e7d4d1b22b" + integrity sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA== dependencies: - "@rollup/pluginutils" "^5.0.1" + "@rollup/pluginutils" "^5.1.0" resolve "^1.22.1" -"@rollup/pluginutils@^5.0.1": - version "5.0.4" - resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz" - integrity sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g== +"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" @@ -775,7 +692,7 @@ "@selderee/plugin-htmlparser2@^0.11.0": version "0.11.0" - resolved "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz" + resolved "https://registry.yarnpkg.com/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz#d5b5e29a7ba6d3958a1972c7be16f4b2c188c517" integrity sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ== dependencies: domhandler "^5.0.3" @@ -783,52 +700,52 @@ "@sinclair/typebox@^0.27.8": version "0.27.8" - resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== "@sinonjs/commons@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz" - integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== dependencies: type-detect "4.0.8" "@sinonjs/fake-timers@^10.0.2": version "10.3.0" - resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== dependencies: "@sinonjs/commons" "^3.0.0" "@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== "@tsconfig/node12@^1.0.7": version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== "@tsconfig/node14@^1.0.0": version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": version "1.0.4" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@tsconfig/node20@^20.1.2": - version "20.1.2" - resolved "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.2.tgz" - integrity sha512-madaWq2k+LYMEhmcp0fs+OGaLFk0OenpHa4gmI4VEmCKX4PJntQ6fnnGADVFrVkBj0wIdAlQnK/MrlYTHsa1gQ== + version "20.1.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node20/-/node20-20.1.4.tgz#3457d42eddf12d3bde3976186ab0cd22b85df928" + integrity sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg== "@types/babel__core@^7.1.14": - version "7.20.1" - resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz" - integrity sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -837,126 +754,140 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.1" - resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.1" - resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz" - integrity sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg== + version "7.20.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" + integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== dependencies: "@babel/types" "^7.20.7" "@types/estree@^1.0.0": - version "1.0.1" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/graceful-fs@^4.1.3": - version "4.1.6" - resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz" - integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@^29.5.4": - version "29.5.4" - resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz" - integrity sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A== + version "29.5.12" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" + integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== dependencies: expect "^29.0.0" pretty-format "^29.0.0" "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.9": - version "7.0.12" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" - integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/mailparser@^3.4.4": version "3.4.4" - resolved "https://registry.npmjs.org/@types/mailparser/-/mailparser-3.4.4.tgz" + resolved "https://registry.yarnpkg.com/@types/mailparser/-/mailparser-3.4.4.tgz#0bd71e205573b9dd9a445e10a8b8cb0e45420998" integrity sha512-C6Znp2QVS25JqtuPyxj38Qh+QoFcLycdxsvcc6IZCGekhaMBzbdTXzwGzhGoYb3TfKu8IRCNV0sV1o3Od97cEQ== dependencies: "@types/node" "*" iconv-lite "^0.6.3" -"@types/node@*", "@types/node@^20.6.0": - version "20.6.0" - resolved "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz" - integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg== +"@types/node@*": + version "22.5.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.1.tgz#de01dce265f6b99ed32b295962045d10b5b99560" + integrity sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw== + dependencies: + undici-types "~6.19.2" + +"@types/node@^20.6.0": + version "20.16.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.2.tgz#9e388f503a5af306e8c63319334887390966a11e" + integrity sha512-91s/n4qUPV/wg8eE9KHYW1kouTfDk2FPGjXbBMfRWP/2vg1rCXNQL1OCabwGs0XSdukuK+MwCDXE30QpSeMUhQ== + dependencies: + undici-types "~6.19.2" "@types/resolve@1.20.2": version "1.20.2" - resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== "@types/semver@^7.3.12", "@types/semver@^7.5.0": - version "7.5.1" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz" - integrity sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg== + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== "@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/triple-beam@^1.3.2": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/triple-beam/-/triple-beam-1.3.5.tgz#74fef9ffbaa198eb8b588be029f38b00299caa2c" + integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== "@types/validator@^13.11.1": - version "13.11.1" - resolved "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz" - integrity sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A== + version "13.12.1" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.12.1.tgz#8835d22f7e25b261e624d02a42fe4ade2c689a3c" + integrity sha512-w0URwf7BQb0rD/EuiG12KP0bailHKHP5YVviJG9zw3ykAokL0TuxU2TUqMB7EwZ59bDHYdeTIvjI5m0S7qHfOA== "@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^17.0.8": - version "17.0.24" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz" - integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" + integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz" - integrity sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag== + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" + integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.7.0" - "@typescript-eslint/type-utils" "6.7.0" - "@typescript-eslint/utils" "6.7.0" - "@typescript-eslint/visitor-keys" "6.7.0" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/type-utils" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -965,55 +896,55 @@ ts-api-utils "^1.0.1" "@typescript-eslint/parser@^6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz" - integrity sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng== - dependencies: - "@typescript-eslint/scope-manager" "6.7.0" - "@typescript-eslint/types" "6.7.0" - "@typescript-eslint/typescript-estree" "6.7.0" - "@typescript-eslint/visitor-keys" "6.7.0" + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" + integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== + dependencies: + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" "@typescript-eslint/scope-manager@5.62.0": version "5.62.0" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/scope-manager@6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz" - integrity sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA== +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== dependencies: - "@typescript-eslint/types" "6.7.0" - "@typescript-eslint/visitor-keys" "6.7.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/type-utils@6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz" - integrity sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg== +"@typescript-eslint/type-utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" + integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== dependencies: - "@typescript-eslint/typescript-estree" "6.7.0" - "@typescript-eslint/utils" "6.7.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/utils" "6.21.0" debug "^4.3.4" ts-api-utils "^1.0.1" "@typescript-eslint/types@5.62.0": version "5.62.0" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/types@6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz" - integrity sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q== +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: "@typescript-eslint/types" "5.62.0" @@ -1024,35 +955,36 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz" - integrity sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ== +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== dependencies: - "@typescript-eslint/types" "6.7.0" - "@typescript-eslint/visitor-keys" "6.7.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" + minimatch "9.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz" - integrity sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA== +"@typescript-eslint/utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" + integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.7.0" - "@typescript-eslint/types" "6.7.0" - "@typescript-eslint/typescript-estree" "6.7.0" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" semver "^7.5.4" "@typescript-eslint/utils@^5.10.0": version "5.62.0" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" @@ -1066,38 +998,45 @@ "@typescript-eslint/visitor-keys@5.62.0": version "5.62.0" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@6.7.0": - version "6.7.0" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz" - integrity sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ== +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== dependencies: - "@typescript-eslint/types" "6.7.0" + "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + version "8.3.3" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.3.tgz#9caeac29eefaa0c41e3d4c65137de4d6f34df43e" + integrity sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw== + dependencies: + acorn "^8.11.0" -acorn@^8.4.1, acorn@^8.8.2, acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== +acorn@^8.11.0, acorn@^8.4.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== ajv@^6.12.4: version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -1107,38 +1046,38 @@ ajv@^6.12.4: ansi-escapes@^4.2.1: version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" ansi-styles@^5.0.0: version "5.2.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== anymatch@^3.0.3: version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -1146,46 +1085,51 @@ anymatch@^3.0.3: arg@^4.1.0: version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== argparse@^1.0.7: version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-union@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +async@^3.2.3: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== + asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== axios@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102" - integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg== + version "1.7.5" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.5.tgz#21eed340eb5daf47d29b6e002424b3e88c8c54b1" + integrity sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw== dependencies: - follow-redirects "^1.15.0" + follow-redirects "^1.15.6" form-data "^4.0.0" proxy-from-env "^1.1.0" -babel-jest@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz" - integrity sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw== +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== dependencies: - "@jest/transform" "^29.6.4" + "@jest/transform" "^29.7.0" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" babel-preset-jest "^29.6.3" @@ -1195,7 +1139,7 @@ babel-jest@^29.6.4: babel-plugin-istanbul@^6.1.1: version "6.1.1" - resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -1206,7 +1150,7 @@ babel-plugin-istanbul@^6.1.1: babel-plugin-jest-hoist@^29.6.3: version "29.6.3" - resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== dependencies: "@babel/template" "^7.3.3" @@ -1215,26 +1159,29 @@ babel-plugin-jest-hoist@^29.6.3: "@types/babel__traverse" "^7.0.6" babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz#9a929eafece419612ef4ae4f60b1862ebad8ef30" + integrity sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-import-attributes" "^7.24.7" + "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" babel-preset-jest@^29.6.3: version "29.6.3" - resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== dependencies: babel-plugin-jest-hoist "^29.6.3" @@ -1242,109 +1189,97 @@ babel-preset-jest@^29.6.3: balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -big-integer@^1.6.44: - version "1.6.51" - resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.2: +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" -browserslist@^4.21.9: - version "4.21.10" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz" - integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ== +browserslist@^4.23.1: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== dependencies: - caniuse-lite "^1.0.30001517" - electron-to-chromium "^1.4.477" - node-releases "^2.0.13" - update-browserslist-db "^1.0.11" + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" -bs-logger@0.x: +bs-logger@^0.2.6: version "0.2.6" - resolved "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== dependencies: fast-json-stable-stringify "2.x" bser@2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== dependencies: node-int64 "^0.4.0" buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== builtin-modules@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== - dependencies: - run-applescript "^5.0.0" - callsites@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.2.0: version "6.3.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001517: - version "1.0.30001532" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001532.tgz" - integrity sha512-FbDFnNat3nMnrROzqrsg314zhqN5LGQ1kyyMk2opcrwGbVGpHRhgCWtAgD5YJUqNAiQ+dklreil/c3Qf1dfCTw== +caniuse-lite@^1.0.30001646: + version "1.0.30001655" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz#0ce881f5a19a2dcfda2ecd927df4d5c1684b982f" + integrity sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg== chalk@^2.4.2: version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: +chalk@^4.0.0, chalk@^4.0.2: version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -1352,22 +1287,22 @@ chalk@^4.0.0: char-regex@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cjs-module-lexer@^1.0.0: - version "1.2.3" - resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz" - integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + version "1.4.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.0.tgz#677de7ed7efff67cc40c9bf1897fea79d41b5215" + integrity sha512-N1NGmowPlGBLsOZLPvm48StN04V4YvQRL0i6b7ctrVY3epjP/ct7hFLOItz6pDIvRjwpfPxi52a2UWV2ziir8g== cliui@^8.0.1: version "8.0.1" - resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" @@ -1376,73 +1311,105 @@ cliui@^8.0.1: co@^4.6.0: version "4.6.0" - resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.6.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.1.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + +colorspace@1.1.x: + version "1.1.4" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" + integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== + dependencies: + color "^3.1.3" + text-hex "1.0.x" + combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" commander@^2.20.0: version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - convert-source-map@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + create-require@^1.1.0: version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -1450,87 +1417,64 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: which "^2.0.1" debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== dependencies: ms "2.1.2" dedent@^1.0.0: - version "1.5.1" - resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz" - integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + version "1.5.3" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" + integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2, deepmerge@^4.3.1: version "4.3.1" - resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== - dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" - -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== detect-newline@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== diff-sequences@^29.6.3: version "29.6.3" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diff@^4.0.1: version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" dom-serializer@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== dependencies: domelementtype "^2.3.0" @@ -1539,100 +1483,117 @@ dom-serializer@^2.0.0: domelementtype@^2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== domhandler@^5.0.2, domhandler@^5.0.3: version "5.0.3" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== dependencies: domelementtype "^2.3.0" domutils@^3.0.1: version "3.1.0" - resolved "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== dependencies: dom-serializer "^2.0.0" domelementtype "^2.3.0" domhandler "^5.0.3" -electron-to-chromium@^1.4.477: - version "1.4.514" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.514.tgz" - integrity sha512-M8LVncPt1Xaw1XLxws6EoJCmY41RXLk87tq6PHvSHDyTYWla3CrEgGlbhC79e8LHyvQ2JTDXx//xzgSixNYcUQ== +ejs@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== + dependencies: + jake "^10.8.5" + +electron-to-chromium@^1.5.4: + version "1.5.13" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" + integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== emittery@^0.13.1: version "0.13.1" - resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + encoding-japanese@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/encoding-japanese/-/encoding-japanese-2.0.0.tgz#fa0226e5469e7b5b69a04fea7d5481bd1fa56936" integrity sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ== +encoding-japanese@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/encoding-japanese/-/encoding-japanese-2.1.0.tgz#5d3c2b652c84ca563783b86907bf5cdfe9a597e2" + integrity sha512-58XySVxUgVlBikBTbQ8WdDxBDHIdXucB16LO5PBHR8t75D54wQrNo4cg+58+R1CtJfKnsVsvt9XlteRaR8xw1w== + entities@^4.2.0, entities@^4.4.0: version "4.5.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.1, escalade@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eslint-config-prettier@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz" - integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== + version "9.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== eslint-plugin-es@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== dependencies: eslint-utils "^2.0.0" regexpp "^3.0.0" eslint-plugin-jest@^27.2.3: - version "27.2.3" - resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.3.tgz" - integrity sha512-sRLlSCpICzWuje66Gl9zvdF6mwD5X86I4u55hJyFBsxYOsBCmT5+kSUjf+fkFWVMMgpzNEupjW8WzUqi83hJAQ== + version "27.9.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz#7c98a33605e1d8b8442ace092b60e9919730000b" + integrity sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug== dependencies: "@typescript-eslint/utils" "^5.10.0" eslint-plugin-node@^11.1.0: version "11.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== dependencies: eslint-plugin-es "^3.0.0" @@ -1643,16 +1604,16 @@ eslint-plugin-node@^11.1.0: semver "^6.1.0" eslint-plugin-prettier@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz" - integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w== + version "5.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz#d1c8f972d8f60e414c25465c163d16f209411f95" + integrity sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw== dependencies: prettier-linter-helpers "^1.0.0" - synckit "^0.8.5" + synckit "^0.9.1" eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -1660,7 +1621,7 @@ eslint-scope@^5.1.1: eslint-scope@^7.2.2: version "7.2.2" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" @@ -1668,33 +1629,34 @@ eslint-scope@^7.2.2: eslint-utils@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" eslint-visitor-keys@^1.1.0: version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.49.0: - version "8.49.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz" - integrity sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ== + version "8.57.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" + integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.49.0" - "@humanwhocodes/config-array" "^0.11.11" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.57.0" + "@humanwhocodes/config-array" "^0.11.14" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -1728,7 +1690,7 @@ eslint@^8.49.0: espree@^9.6.0, espree@^9.6.1: version "9.6.1" - resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: acorn "^8.9.0" @@ -1737,46 +1699,46 @@ espree@^9.6.0, espree@^9.6.1: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== estree-walker@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== execa@^5.0.0: version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -1789,51 +1751,36 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@^7.1.1: - version "7.2.0" - resolved "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz" - integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - exit@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expect@^29.0.0, expect@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/expect/-/expect-29.6.4.tgz" - integrity sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA== +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== dependencies: - "@jest/expect-utils" "^29.6.4" + "@jest/expect-utils" "^29.7.0" jest-get-type "^29.6.3" - jest-matcher-utils "^29.6.4" - jest-message-util "^29.6.3" - jest-util "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.2: version "1.3.0" - resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.9, fast-glob@^3.3.0: - version "3.3.1" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -1843,35 +1790,47 @@ fast-glob@^3.2.9, fast-glob@^3.3.0: fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" fb-watchman@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" +fecha@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" + integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== + file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -1881,7 +1840,7 @@ fill-range@^7.1.1: find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -1889,34 +1848,39 @@ find-up@^4.0.0, find-up@^4.1.0: find-up@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.1.0" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz" - integrity sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: - flatted "^3.2.7" + flatted "^3.2.9" keyv "^4.5.3" rimraf "^3.0.2" -flatted@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -follow-redirects@^1.15.0: +follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== form-data@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" @@ -1925,56 +1889,56 @@ form-data@^4.0.0: fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.3" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" - resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-package-type@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stream@^6.0.0, get-stream@^6.0.1: +get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== glob-parent@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.2: version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" glob@^7.1.3, glob@^7.1.4: version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -1986,19 +1950,19 @@ glob@^7.1.3, glob@^7.1.4: globals@^11.1.0: version "11.12.0" - resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.19.0: - version "13.21.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz" - integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg== + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" globby@^11.1.0: version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -2010,44 +1974,44 @@ globby@^11.1.0: graceful-fs@^4.2.9: version "4.2.11" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== graphemer@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: - function-bind "^1.1.1" + function-bind "^1.1.2" he@1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== html-escaper@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== html-to-text@9.0.5: version "9.0.5" - resolved "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz" + resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-9.0.5.tgz#6149a0f618ae7a0db8085dca9bbf96d32bb8368d" integrity sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg== dependencies: "@selderee/plugin-htmlparser2" "^0.11.0" @@ -2058,7 +2022,7 @@ html-to-text@9.0.5: htmlparser2@^8.0.2: version "8.0.2" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== dependencies: domelementtype "^2.3.0" @@ -2068,163 +2032,134 @@ htmlparser2@^8.0.2: human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - iconv-lite@0.6.3, iconv-lite@^0.6.3: version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== dependencies: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" -inherits@2: +inherits@2, inherits@^2.0.3: version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-builtin-module@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== dependencies: builtin-modules "^3.3.0" is-core-module@^2.13.0: - version "2.13.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== dependencies: - has "^1.0.3" - -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + hasown "^2.0.2" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-fn@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - is-module@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== is-number@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-path-inside@^3.0.3: version "3.0.3" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - isexe@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4: version "5.2.1" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: "@babel/core" "^7.12.3" @@ -2234,19 +2169,19 @@ istanbul-lib-instrument@^5.0.4: semver "^6.3.0" istanbul-lib-instrument@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.0.tgz" - integrity sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw== + version "6.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" + "@babel/core" "^7.23.9" + "@babel/parser" "^7.23.9" + "@istanbuljs/schema" "^0.1.3" istanbul-lib-coverage "^3.2.0" semver "^7.5.4" istanbul-lib-report@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" @@ -2255,7 +2190,7 @@ istanbul-lib-report@^3.0.0: istanbul-lib-source-maps@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" @@ -2263,143 +2198,152 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.6" - resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz" - integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + version "3.1.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.6.3.tgz" - integrity sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg== +jake@^10.8.5: + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== dependencies: execa "^5.0.0" - jest-util "^29.6.3" + jest-util "^29.7.0" p-limit "^3.1.0" -jest-circus@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz" - integrity sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw== +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== dependencies: - "@jest/environment" "^29.6.4" - "@jest/expect" "^29.6.4" - "@jest/test-result" "^29.6.4" + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^1.0.0" is-generator-fn "^2.0.0" - jest-each "^29.6.3" - jest-matcher-utils "^29.6.4" - jest-message-util "^29.6.3" - jest-runtime "^29.6.4" - jest-snapshot "^29.6.4" - jest-util "^29.6.3" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" p-limit "^3.1.0" - pretty-format "^29.6.3" + pretty-format "^29.7.0" pure-rand "^6.0.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz" - integrity sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ== +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== dependencies: - "@jest/core" "^29.6.4" - "@jest/test-result" "^29.6.4" + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" "@jest/types" "^29.6.3" chalk "^4.0.0" + create-jest "^29.7.0" exit "^0.1.2" - graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.6.4" - jest-util "^29.6.3" - jest-validate "^29.6.3" - prompts "^2.0.1" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" yargs "^17.3.1" -jest-config@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz" - integrity sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A== +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.6.4" + "@jest/test-sequencer" "^29.7.0" "@jest/types" "^29.6.3" - babel-jest "^29.6.4" + babel-jest "^29.7.0" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.6.4" - jest-environment-node "^29.6.4" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" jest-get-type "^29.6.3" jest-regex-util "^29.6.3" - jest-resolve "^29.6.4" - jest-runner "^29.6.4" - jest-util "^29.6.3" - jest-validate "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.6.3" + pretty-format "^29.7.0" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.4.tgz" - integrity sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw== +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== dependencies: chalk "^4.0.0" diff-sequences "^29.6.3" jest-get-type "^29.6.3" - pretty-format "^29.6.3" + pretty-format "^29.7.0" -jest-docblock@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.6.3.tgz" - integrity sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ== +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== dependencies: detect-newline "^3.0.0" -jest-each@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-each/-/jest-each-29.6.3.tgz" - integrity sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg== +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== dependencies: "@jest/types" "^29.6.3" chalk "^4.0.0" jest-get-type "^29.6.3" - jest-util "^29.6.3" - pretty-format "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" -jest-environment-node@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz" - integrity sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ== +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== dependencies: - "@jest/environment" "^29.6.4" - "@jest/fake-timers" "^29.6.4" + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" "@jest/types" "^29.6.3" "@types/node" "*" - jest-mock "^29.6.3" - jest-util "^29.6.3" + jest-mock "^29.7.0" + jest-util "^29.7.0" jest-get-type@^29.6.3: version "29.6.3" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== -jest-haste-map@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.4.tgz" - integrity sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog== +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== dependencies: "@jest/types" "^29.6.3" "@types/graceful-fs" "^4.1.3" @@ -2408,35 +2352,35 @@ jest-haste-map@^29.6.4: fb-watchman "^2.0.0" graceful-fs "^4.2.9" jest-regex-util "^29.6.3" - jest-util "^29.6.3" - jest-worker "^29.6.4" + jest-util "^29.7.0" + jest-worker "^29.7.0" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.6.3.tgz" - integrity sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q== +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== dependencies: jest-get-type "^29.6.3" - pretty-format "^29.6.3" + pretty-format "^29.7.0" -jest-matcher-utils@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz" - integrity sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ== +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== dependencies: chalk "^4.0.0" - jest-diff "^29.6.4" + jest-diff "^29.7.0" jest-get-type "^29.6.3" - pretty-format "^29.6.3" + pretty-format "^29.7.0" -jest-message-util@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.3.tgz" - integrity sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA== +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== dependencies: "@babel/code-frame" "^7.12.13" "@jest/types" "^29.6.3" @@ -2444,90 +2388,90 @@ jest-message-util@^29.6.3: chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.6.3" + pretty-format "^29.7.0" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.3.tgz" - integrity sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg== +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== dependencies: "@jest/types" "^29.6.3" "@types/node" "*" - jest-util "^29.6.3" + jest-util "^29.7.0" jest-pnp-resolver@^1.2.2: version "1.2.3" - resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== jest-regex-util@^29.6.3: version "29.6.3" - resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== -jest-resolve-dependencies@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz" - integrity sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA== +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== dependencies: jest-regex-util "^29.6.3" - jest-snapshot "^29.6.4" + jest-snapshot "^29.7.0" -jest-resolve@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz" - integrity sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q== +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.6.4" + jest-haste-map "^29.7.0" jest-pnp-resolver "^1.2.2" - jest-util "^29.6.3" - jest-validate "^29.6.3" + jest-util "^29.7.0" + jest-validate "^29.7.0" resolve "^1.20.0" resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz" - integrity sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw== +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== dependencies: - "@jest/console" "^29.6.4" - "@jest/environment" "^29.6.4" - "@jest/test-result" "^29.6.4" - "@jest/transform" "^29.6.4" + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^29.6.3" - jest-environment-node "^29.6.4" - jest-haste-map "^29.6.4" - jest-leak-detector "^29.6.3" - jest-message-util "^29.6.3" - jest-resolve "^29.6.4" - jest-runtime "^29.6.4" - jest-util "^29.6.3" - jest-watcher "^29.6.4" - jest-worker "^29.6.4" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz" - integrity sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA== +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== dependencies: - "@jest/environment" "^29.6.4" - "@jest/fake-timers" "^29.6.4" - "@jest/globals" "^29.6.4" + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" "@jest/source-map" "^29.6.3" - "@jest/test-result" "^29.6.4" - "@jest/transform" "^29.6.4" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" "@jest/types" "^29.6.3" "@types/node" "*" chalk "^4.0.0" @@ -2535,46 +2479,46 @@ jest-runtime@^29.6.4: collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.6.4" - jest-message-util "^29.6.3" - jest-mock "^29.6.3" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" jest-regex-util "^29.6.3" - jest-resolve "^29.6.4" - jest-snapshot "^29.6.4" - jest-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.4.tgz" - integrity sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA== +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.6.4" - "@jest/transform" "^29.6.4" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" "@jest/types" "^29.6.3" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.6.4" + expect "^29.7.0" graceful-fs "^4.2.9" - jest-diff "^29.6.4" + jest-diff "^29.7.0" jest-get-type "^29.6.3" - jest-matcher-utils "^29.6.4" - jest-message-util "^29.6.3" - jest-util "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" natural-compare "^1.4.0" - pretty-format "^29.6.3" + pretty-format "^29.7.0" semver "^7.5.3" -jest-util@^29.0.0, jest-util@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz" - integrity sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA== +jest-util@^29.0.0, jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== dependencies: "@jest/types" "^29.6.3" "@types/node" "*" @@ -2583,60 +2527,60 @@ jest-util@^29.0.0, jest-util@^29.6.3: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz" - integrity sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg== +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: "@jest/types" "^29.6.3" camelcase "^6.2.0" chalk "^4.0.0" jest-get-type "^29.6.3" leven "^3.1.0" - pretty-format "^29.6.3" + pretty-format "^29.7.0" -jest-watcher@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz" - integrity sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ== +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== dependencies: - "@jest/test-result" "^29.6.4" + "@jest/test-result" "^29.7.0" "@jest/types" "^29.6.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.13.1" - jest-util "^29.6.3" + jest-util "^29.7.0" string-length "^4.0.1" -jest-worker@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.4.tgz" - integrity sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q== +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: "@types/node" "*" - jest-util "^29.6.3" + jest-util "^29.7.0" merge-stream "^2.0.0" supports-color "^8.0.0" jest@^29.6.4: - version "29.6.4" - resolved "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz" - integrity sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw== + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== dependencies: - "@jest/core" "^29.6.4" + "@jest/core" "^29.7.0" "@jest/types" "^29.6.3" import-local "^3.0.2" - jest-cli "^29.6.4" + jest-cli "^29.7.0" js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: version "3.14.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -2644,66 +2588,71 @@ js-yaml@^3.13.1: js-yaml@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" jsesc@^2.5.1: version "2.5.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== json-buffer@3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json5@^2.2.3: version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== keyv@^4.5.3: - version "4.5.3" - resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz" - integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug== + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: json-buffer "3.0.1" kleur@^3.0.3: version "3.0.3" - resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + leac@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz" + resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912" integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg== leven@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== levn@^0.4.1: version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -2711,12 +2660,17 @@ levn@^0.4.1: libbase64@1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/libbase64/-/libbase64-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/libbase64/-/libbase64-1.2.1.tgz#fb93bf4cb6d730f29b92155b6408d1bd2176a8c8" integrity sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew== +libbase64@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/libbase64/-/libbase64-1.3.0.tgz#053314755a05d2e5f08bbfc48d0290e9322f4406" + integrity sha512-GgOXd0Eo6phYgh0DJtjQ2tO8dc0IVINtZJeARPeiIJqge+HdsWSuaDTe8ztQ7j/cONByDZ3zeB325AHiv5O0dg== + libmime@5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/libmime/-/libmime-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/libmime/-/libmime-5.2.0.tgz#c4ed5cbd2d9fdd27534543a68bb8d17c658d51d8" integrity sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw== dependencies: encoding-japanese "2.0.0" @@ -2724,96 +2678,107 @@ libmime@5.2.0: libbase64 "1.2.1" libqp "2.0.1" -libmime@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/libmime/-/libmime-5.2.1.tgz" - integrity sha512-A0z9O4+5q+ZTj7QwNe/Juy1KARNb4WaviO4mYeFC4b8dBT2EEqK2pkM+GC8MVnkOjqhl5nYQxRgnPYRRTNmuSQ== +libmime@5.3.5: + version "5.3.5" + resolved "https://registry.yarnpkg.com/libmime/-/libmime-5.3.5.tgz#acd95a32f58dab55c8a9d269c5b4509e7ad6ae31" + integrity sha512-nSlR1yRZ43L3cZCiWEw7ali3jY29Hz9CQQ96Oy+sSspYnIP5N54ucOPHqooBsXzwrX1pwn13VUE05q4WmzfaLg== dependencies: - encoding-japanese "2.0.0" + encoding-japanese "2.1.0" iconv-lite "0.6.3" - libbase64 "1.2.1" - libqp "2.0.1" + libbase64 "1.3.0" + libqp "2.1.0" libqp@2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/libqp/-/libqp-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/libqp/-/libqp-2.0.1.tgz#b8fed76cc1ea6c9ceff8888169e4e0de70cd5cf2" integrity sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg== +libqp@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/libqp/-/libqp-2.1.0.tgz#ce84bffd86b76029032093bd866d316e12a3d3f5" + integrity sha512-O6O6/fsG5jiUVbvdgT7YX3xY3uIadR6wEZ7+vy9u7PKHAlSEB6blvC1o5pHBjgsi95Uo0aiBBdkyFecj6jtb7A== + lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -linkify-it@4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz" - integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== +linkify-it@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421" + integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ== dependencies: - uc.micro "^1.0.1" + uc.micro "^2.0.0" locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" -lodash.memoize@4.x: +lodash.memoize@^4.1.2: version "4.1.2" - resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +logform@^2.6.0, logform@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.6.1.tgz#71403a7d8cae04b2b734147963236205db9b3df0" + integrity sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA== + dependencies: + "@colors/colors" "1.6.0" + "@types/triple-beam" "^1.3.2" + fecha "^4.2.0" + ms "^2.1.1" + safe-stable-stringify "^2.3.1" + triple-beam "^1.3.0" + lru-cache@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -magic-string@^0.30.3: - version "0.30.3" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz" - integrity sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw== +magic-string@^0.30.10: + version "0.30.11" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954" + integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" + "@jridgewell/sourcemap-codec" "^1.5.0" mailparser@^3.6.5: - version "3.6.5" - resolved "https://registry.npmjs.org/mailparser/-/mailparser-3.6.5.tgz" - integrity sha512-nteTpF0Khm5JLOnt4sigmzNdUH/6mO7PZ4KEnvxf4mckyXYFFhrtAWZzbq/V5aQMH+049gA7ZjfLdh+QiX2Uqg== + version "3.7.1" + resolved "https://registry.yarnpkg.com/mailparser/-/mailparser-3.7.1.tgz#4d0ea2eeb50a73dd10854a71ef1d4553bdce01cb" + integrity sha512-RCnBhy5q8XtB3mXzxcAfT1huNqN93HTYYyL6XawlIKycfxM/rXPg9tXoZ7D46+SgCS1zxKzw+BayDQSvncSTTw== dependencies: - encoding-japanese "2.0.0" + encoding-japanese "2.1.0" he "1.2.0" html-to-text "9.0.5" iconv-lite "0.6.3" - libmime "5.2.1" - linkify-it "4.0.1" + libmime "5.3.5" + linkify-it "5.0.0" mailsplit "5.4.0" - nodemailer "6.9.3" - tlds "1.240.0" + nodemailer "6.9.13" + punycode.js "2.3.1" + tlds "1.252.0" mailsplit@5.4.0: version "5.4.0" - resolved "https://registry.npmjs.org/mailsplit/-/mailsplit-5.4.0.tgz" + resolved "https://registry.yarnpkg.com/mailsplit/-/mailsplit-5.4.0.tgz#9f4692fadd9013e9ce632147d996931d2abac6ba" integrity sha512-wnYxX5D5qymGIPYLwnp6h8n1+6P6vz/MJn5AzGjZ8pwICWssL+CCQjWBIToOVHASmATot4ktvlLo6CyLfOXWYA== dependencies: libbase64 "1.2.1" @@ -2822,200 +2787,197 @@ mailsplit@5.4.0: make-dir@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== dependencies: semver "^7.5.3" -make-error@1.x, make-error@^1.1.1: +make-error@^1.1.1, make-error@^1.3.6: version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== makeerror@1.0.12: version "1.0.12" - resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: tmpl "1.0.5" merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0: version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12: version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + ms@2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== node-int64@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== -nodemailer@6.9.3: - version "6.9.3" - resolved "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.3.tgz" - integrity sha512-fy9v3NgTzBngrMFkDsKEj0r02U7jm6XfC3b52eoNV+GCrGj+s8pt5OqhiJdWKuw51zCTdiNR/IUD1z33LIIGpg== +nodemailer@6.9.13: + version "6.9.13" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.13.tgz#5b292bf1e92645f4852ca872c56a6ba6c4a3d3d6" + integrity sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA== normalize-path@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - once@^1.3.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + onetime@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -open@^9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/open/-/open-9.1.0.tgz" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== - dependencies: - default-browser "^4.0.0" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - is-wsl "^2.2.0" - optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" + word-wrap "^1.2.5" p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-try@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-json@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -3025,7 +2987,7 @@ parse-json@^5.2.0: parseley@^0.12.0: version "0.12.1" - resolved "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz" + resolved "https://registry.yarnpkg.com/parseley/-/parseley-0.12.1.tgz#4afd561d50215ebe259e3e7a853e62f600683aef" integrity sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw== dependencies: leac "^0.6.0" @@ -3033,82 +2995,77 @@ parseley@^0.12.0: path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== peberminta@^0.9.0: version "0.9.0" - resolved "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz" + resolved "https://registry.yarnpkg.com/peberminta/-/peberminta-0.9.0.tgz#8ec9bc0eb84b7d368126e71ce9033501dca2a352" integrity sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +picocolors@^1.0.0, picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pirates@^4.0.4: version "4.0.6" - resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier-linter-helpers@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== dependencies: fast-diff "^1.1.2" prettier@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz" - integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== + version "3.3.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" + integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== -pretty-format@^29.0.0, pretty-format@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz" - integrity sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw== +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== dependencies: "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" @@ -3116,7 +3073,7 @@ pretty-format@^29.0.0, pretty-format@^29.6.3: prompts@^2.0.1: version "2.4.2" - resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" @@ -3124,72 +3081,86 @@ prompts@^2.0.1: proxy-from-env@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== +punycode.js@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7" + integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA== + punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== pure-rand@^6.0.0: - version "6.0.3" - resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.3.tgz" - integrity sha512-KddyFewCsO0j3+np81IQ+SweXLDnDQTs5s67BOnrYmYe/yNmUhttQyGsYzy8yUnoljGAQ9sl38YB4vH8ur7Y+w== + version "6.1.0" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +readable-stream@^3.4.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" regexpp@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== resolve-cwd@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: resolve-from "^5.0.0" resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve.exports@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.1: - version "1.22.4" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz" - integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: is-core-module "^2.13.0" path-parse "^1.0.7" @@ -3197,117 +3168,120 @@ resolve@^1.10.1, resolve@^1.20.0, resolve@^1.22.1: reusify@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" rollup-plugin-dts@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.0.2.tgz" - integrity sha512-GYCCy9DyE5csSuUObktJBpjNpW2iLZMabNDIiAqzQWBl7l/WHzjvtAXevf8Lftk8EA920tuxeB/g8dM8MVMR6A== + version "6.1.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-6.1.1.tgz#46b33f4d1d7f4e66f1171ced9b282ac11a15a254" + integrity sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA== dependencies: - magic-string "^0.30.3" + magic-string "^0.30.10" optionalDependencies: - "@babel/code-frame" "^7.22.13" + "@babel/code-frame" "^7.24.2" rollup@^3.29.4: version "3.29.4" - resolved "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== optionalDependencies: fsevents "~2.3.2" -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" - run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.1.0: +safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-stable-stringify@^2.3.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" + integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== + "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== selderee@^0.11.0: version "0.11.0" - resolved "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz" + resolved "https://registry.yarnpkg.com/selderee/-/selderee-0.11.0.tgz#6af0c7983e073ad3e35787ffe20cefd9daf0ec8a" integrity sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA== dependencies: parseley "^0.12.0" semver@^6.1.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" +semver@^7.3.7, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== serialize-javascript@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + sisteransi@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== slash@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== smob@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz" - integrity sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg== + version "1.5.0" + resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab" + integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig== source-map-support@0.5.13: version "0.5.13" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" @@ -3315,7 +3289,7 @@ source-map-support@0.5.13: source-map-support@~0.5.20: version "0.5.21" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" @@ -3323,24 +3297,29 @@ source-map-support@~0.5.20: source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + stack-utils@^2.0.3: version "2.0.6" - resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" string-length@^4.0.1: version "4.0.2" - resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" @@ -3348,78 +3327,80 @@ string-length@^4.0.1: string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-bom@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -synckit@^0.8.5: - version "0.8.5" - resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz" - integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== +synckit@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.1.tgz#febbfbb6649979450131f64735aa3f6c14575c88" + integrity sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A== dependencies: - "@pkgr/utils" "^2.3.1" - tslib "^2.5.0" + "@pkgr/core" "^0.1.0" + tslib "^2.6.2" terser@^5.17.4: - version "5.19.4" - resolved "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz" - integrity sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g== + version "5.31.6" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" + integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -3428,67 +3409,73 @@ terser@^5.17.4: test-exclude@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: "@istanbuljs/schema" "^0.1.2" glob "^7.1.4" minimatch "^3.0.4" +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + text-table@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - -tlds@1.240.0: - version "1.240.0" - resolved "https://registry.npmjs.org/tlds/-/tlds-1.240.0.tgz" - integrity sha512-1OYJQenswGZSOdRw7Bql5Qu7uf75b+F3HFBXbqnG/ifHa0fev1XcG+3pJf3pA/KC6RtHQzfKgIf1vkMlMG7mtQ== +tlds@1.252.0: + version "1.252.0" + resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.252.0.tgz#71d9617f4ef4cc7347843bee72428e71b8b0f419" + integrity sha512-GA16+8HXvqtfEnw/DTcwB0UU354QE1n3+wh08oFjr6Znl7ZLAeUgYzCcK+/CCrOyE0vnHR8/pu3XXG3vDijXpQ== tmpl@1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-fast-properties@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" +triple-beam@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" + integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== + ts-api-utils@^1.0.1: - version "1.0.3" - resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz" - integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== ts-jest@^29.1.1: - version "29.1.1" - resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz" - integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + version "29.2.5" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.2.5.tgz#591a3c108e1f5ebd013d3152142cb5472b399d63" + integrity sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA== dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" + bs-logger "^0.2.6" + ejs "^3.1.10" + fast-json-stable-stringify "^2.1.0" jest-util "^29.0.0" json5 "^2.2.3" - lodash.memoize "4.x" - make-error "1.x" - semver "^7.5.3" - yargs-parser "^21.0.1" + lodash.memoize "^4.1.2" + make-error "^1.3.6" + semver "^7.6.3" + yargs-parser "^21.1.1" ts-node@10.9.1: version "10.9.1" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== dependencies: "@cspotcode/source-map-support" "^0.8.0" @@ -3507,109 +3494,145 @@ ts-node@10.9.1: tslib@^1.8.1: version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.5.0, tslib@^2.6.0, tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.6.2: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-detect@4.0.8: version "4.0.8" - resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== typescript@^5.2.2: - version "5.2.2" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" - integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + version "5.5.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== -uc.micro@^1.0.1: - version "1.0.6" - resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== +uc.micro@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" + integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== -update-browserslist-db@^1.0.11: - version "1.0.11" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" + escalade "^3.1.2" + picocolors "^1.0.1" uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + v8-compile-cache-lib@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== v8-to-istanbul@^9.0.1: - version "9.1.0" - resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz" - integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + version "9.3.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" + convert-source-map "^2.0.0" validator@^13.11.0: - version "13.11.0" - resolved "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz" - integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + version "13.12.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.12.0.tgz#7d78e76ba85504da3fee4fd1922b385914d4b35f" + integrity sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg== walker@^1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: makeerror "1.0.12" which@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" +winston-transport@^4.7.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.7.1.tgz#52ff1bcfe452ad89991a0aaff9c3b18e7f392569" + integrity sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA== + dependencies: + logform "^2.6.1" + readable-stream "^3.6.2" + triple-beam "^1.3.0" + +winston@^3.13.0: + version "3.14.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.14.2.tgz#94ce5fd26d374f563c969d12f0cd9c641065adab" + integrity sha512-CO8cdpBB2yqzEf8v895L+GNKYJiEq8eKlHU38af3snQBQ+sdAIUepjMSguOIJC7ICbzm0ZI+Af2If4vIJrtmOg== + dependencies: + "@colors/colors" "^1.6.0" + "@dabh/diagnostics" "^2.0.2" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.6.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.7.0" + +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -3618,12 +3641,12 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^4.0.2: version "4.0.2" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: imurmurhash "^0.1.4" @@ -3631,27 +3654,22 @@ write-file-atomic@^4.0.2: y18n@^5.0.5: version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^3.0.2: version "3.1.1" - resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^21.0.1, yargs-parser@^21.1.1: +yargs-parser@^21.1.1: version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.3.1: version "17.7.2" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" @@ -3663,16 +3681,16 @@ yargs@^17.3.1: yargs-parser "^21.1.1" yarn@^1.22.19: - version "1.22.19" - resolved "https://registry.npmjs.org/yarn/-/yarn-1.22.19.tgz" - integrity sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ== + version "1.22.22" + resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.22.tgz#ac34549e6aa8e7ead463a7407e1c7390f61a6610" + integrity sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg== yn@3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From b313deefe4522fd5041c3a1bb60ade31ea26df13 Mon Sep 17 00:00:00 2001 From: rconner46 Date: Thu, 15 Aug 2024 09:53:06 -0500 Subject: [PATCH 5/6] Fix ApplauseTestCycleId Propagation --- dist/index.cjs | 1 + dist/index.cjs.map | 2 +- dist/index.d.ts | 1 - dist/index.min.js | 2 +- dist/index.min.js.map | 2 +- dist/index.mjs | 1 + dist/index.mjs.map | 2 +- src/auto-api/auto-api.ts | 2 ++ src/auto-api/dto.ts | 3 --- 9 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dist/index.cjs b/dist/index.cjs index 136114d..55fbb4b 100644 --- a/dist/index.cjs +++ b/dist/index.cjs @@ -200,6 +200,7 @@ class AutoApi { sdkVersion: `js:${API_VERSION}`, // Copy over the product id productId: this.options.productId, + applauseTestCycleId: 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 1c700af..f241618 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 // 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 // Optional: an applause test cycle id\n itwTestCycleId?: number;\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 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;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,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB;;AAGrD,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.d.ts b/dist/index.d.ts index 14be0a0..4ece446 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -17,7 +17,6 @@ type ClientConfig = { */ interface TestRunCreateDto { tests: string[]; - itwTestCycleId?: number; } /** * DTO modeling the response to a test run creation request diff --git a/dist/index.min.js b/dist/index.min.js index cb2ffab..6e9497c 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 R{logs=[];getLogs(){return this.logs}drainLogs(){const t=this.logs;return this.clearLogs(),t}clearLogs(){this.logs=[]}addLog(t){this.logs.push(t)}}const I=new R;class f extends r{constructor(t){super(t)}log(t,e){setImmediate((()=>{this.emit("logged",t)})),this.format?.transform(t),I.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,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 b="TestRail-",y="Applause-";function O(t,e){const s=t.match(/(TestRail-\d+|Applause-\d+)/g),i=s?.filter((t=>t.startsWith(b))).map((t=>t.substring(9)))??[],r=s?.filter((t=>t.startsWith(y))).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=y,t.APPLAUSE_LOG_RECORDS=I,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=R,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=b,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,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}'`)}})); //# sourceMappingURL=index.min.js.map diff --git a/dist/index.min.js.map b/dist/index.min.js.map index 400ff9a..a3580a7 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 // 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 // Optional: an applause test cycle id\n itwTestCycleId?: number;\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","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 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":"6zBAAO,MCEDA,EAAYC,EAAUC,QAYfC,EAAsD,CACjEC,eAHyB,6CA2BrB,SAAUC,EAAsBC,GACpC,IAAKC,OAAOC,UAAUF,EAAOG,YAAcH,EAAOG,WAAa,EAC7D,MAAM,IAAIC,MACR,+CAA+CJ,EAAOG,cAG1D,IACGT,EAAUW,MAAML,EAAOF,eAAgB,CACtCQ,UAAW,CAAC,OAAQ,SACpBC,aAAa,EACbC,wBAAwB,EACxBC,eAAe,EACfC,iBAAiB,EACjBC,8BAA8B,EAC9BC,oBAAoB,EACpBC,cAAc,EACdC,kBAAkB,IAGpB,MAAM,IAAIV,MACR,oDAAoDJ,EAAOF,kBAI/D,GAAIJ,EAAUqB,QAAQf,EAAOgB,QAC3B,MAAM,IAAIZ,MAAM,6BAEpB,CC/DA,MAAMa,EAAUC,OAAOC,IAAI,WAEdC,EAA6BC,EAAQC,OAAOC,QACvD,EAAGC,QAAOC,UAASC,QAAOC,eACjB,GAAGA,MAAcD,MAAUF,MAAUC,eAIhCG,IACd,OAAOP,EAAQQ,aAAa,CAC1BP,OAAQD,EAAQC,OAAOQ,QACrBT,EAAQC,OAAOI,MAAM,CAAEA,MAAO,mBAC9BL,EAAQC,OAAOK,YACfN,EAAQC,OAAOS,QACfX,GAEFY,WAAY,CACV,IAAIX,EAAQW,WAAWC,KAAK,CAAEC,SAAU,YAAaV,MAAO,UAC5D,IAAIH,EAAQW,WAAWC,KAAK,CAAEC,SAAU,iBACxC,IAAIC,EACJ,IAAId,EAAQW,WAAWI,QAAQ,CAC7BZ,MAAO,OACPF,OAAQD,EAAQC,OAAOQ,QACrBT,EAAQC,OAAOe,WACfjB,OAKV,OAKakB,EACHC,KAAiB,GAOlB,OAAAC,GACL,OAAOC,KAAKF,IACb,CAOM,SAAAG,GACL,MAAMH,EAAOE,KAAKF,KAElB,OADAE,KAAKE,YACEJ,CACR,CAKM,SAAAI,GACLF,KAAKF,KAAO,EACb,CAOM,MAAAK,CAAOC,GACZJ,KAAKF,KAAKO,KAAKD,EAChB,EAIU,MAAAE,EAAyC,IAAIT,EAKpD,MAAOH,UAA0Ba,EACrC,WAAAC,CAAYC,GACVC,MAAMD,EACP,CAED,GAAAL,CAAIO,EAAyBC,GAC3BC,cAAa,KACXb,KAAKc,KAAK,SAAUH,EAAK,IAG3BX,KAAKnB,QAAQkC,UAAUJ,GACvBL,EAAqBH,OAClBQ,EAAKnC,IAAoCmC,EAAK3B,SAIjD4B,GACD,QC7EUI,EAkBAC,QAjBMC,OAETC,OACAC,cAKR,oBAAWC,GACT,OAAOrB,KAAKoB,aACb,CAMD,WAAAZ,CACWS,EACTE,GADSnB,KAAOiB,QAAPA,EAGTjB,KAAKoB,cAAgB,EACrBpB,KAAKmB,OAASA,GAAUhC,IACxB7B,EAAsB2D,GACtBjB,KAAKkB,OAASI,EAAMC,OAAO,CACzBC,QAASP,EAAQ5D,eACjBoE,QAAS,IACTC,QAAS,CACP,YAAaT,EAAQ1C,OACrB,eAAgB,oBAElBoD,aAAc,SAGhB3B,KAAKkB,OAAOU,aAAaC,SAASC,KAChC,SAAUD,GACR,OAAOA,CACR,IACAE,IAEC,MAAMC,OAEqBC,IAAzBF,EAAMF,UAAUK,KACZC,KAAKC,UAAUL,EAAMF,SAASK,MAC9B,eAAeH,EAAMF,UAAUQ,uBAAuBN,EAAMF,UAAUS,cAE5E,OADAtC,KAAKmB,OAAOY,MAAM,qBAAqBC,KAChCO,QAAQC,OAAOT,EAAM,GAGjC,CAOD,kBAAMU,CACJ9B,GAEAX,KAAKoB,eAAiB,EACtB,IACE,aAAapB,KAAKkB,OAAOwB,KACvB,4BACA,IAEK/B,EAGHgC,WAAY,WAGZjF,UAAWsC,KAAKiB,QAAQvD,UAExBkF,oBAAqB5C,KAAKiB,QAAQ2B,oBAGlCC,8BAA2DZ,IAAjCjC,KAAKiB,QAAQ6B,gBACvCC,kBAAmB/C,KAAKiB,QAAQ6B,iBAAiBC,kBACjDC,kBAAmBhD,KAAKiB,QAAQ6B,iBAAiBG,UACjDC,gBAAiBlD,KAAKiB,QAAQ6B,iBAAiBK,QAC/CC,iBAAkBpD,KAAKiB,QAAQ6B,iBAAiBO,SAChDC,gBAAiBtD,KAAKiB,QAAQ6B,iBAAiBS,QAC/CC,kCACExD,KAAKiB,QAAQ6B,iBAAiBW,+BAGrC,CAAS,QACRzD,KAAKoB,eAAiB,CACvB,CACF,CAOD,gBAAMsC,CAAWC,GACf3D,KAAKoB,eAAiB,EACtB,IACE,aAAapB,KAAKkB,OAAO0C,OACvB,sBAAsBD,0BAEzB,CAAS,QACR3D,KAAKoB,eAAiB,CACvB,CACF,CAOD,mBAAMyC,CACJC,GAEA9D,KAAKoB,eAAiB,EACtB,IAKE,aAJkBpB,KAAKkB,OAAOwB,KAC5B,sCACAoB,EAGH,CAAS,QACR9D,KAAKoB,eAAiB,CACvB,CACF,CAOD,0BAAM2C,CAAqBD,GACzB9D,KAAKoB,eAAiB,EACtB,UACQpB,KAAKkB,OAAOwB,KAAK,wBAAyBoB,EACjD,CAAS,QACR9D,KAAKoB,eAAiB,CACvB,CACF,CAOD,6BAAM4C,CACJC,GAEAjE,KAAKoB,eAAiB,EACtB,IAEE,MAAM8C,EAAqBD,EAAUE,QAAOC,GAAMA,IAClD,aAAapE,KAAKkB,OAAOwB,KACvB,sCACAwB,EAEH,CAAS,QACRlE,KAAKoB,eAAiB,CACvB,CACF,CAOD,sBAAMiD,CAAiBV,GACrB3D,KAAKoB,eAAiB,EACtB,IAEE,aAAapB,KAAKkB,OAAOwB,KAAW,0BAA2B,CAC7DiB,UAAWA,GAEd,CAAS,QACR3D,KAAKoB,eAAiB,CACvB,CACF,CAOD,qBAAMkD,CACJC,GAEAvE,KAAKoB,eAAiB,EACtB,IAEE,aAAapB,KAAKkB,OAAOsD,IACvB,sCAAsCD,IAEzC,CAAS,QACRvE,KAAKoB,eAAiB,CACvB,CACF,CAOD,qBAAMqD,CACJC,GAEA1E,KAAKoB,eAAiB,EACtB,IAEE,aAAapB,KAAKkB,OAAOwB,KACvB,iCACAgC,EAEH,CAAS,QACR1E,KAAKoB,eAAiB,CACvB,CACF,CAWD,iBAAMuD,CACJC,EACAC,EACAC,EACAC,EACAC,GAEAhF,KAAKoB,eAAiB,EAEtB,IAEE,aAAapB,KAAKkB,OAAO+D,SACvB,yBAAyBL,WACzB,CACEC,OACAC,YACAC,sBACAC,aAGL,CAAS,QACRhF,KAAKoB,eAAiB,CACvB,CACF,EC/LH,IAAY8D,EA6CAC,EArCXC,EAAAF,sBAAA,GARWA,EAAAA,qBAAAA,EAAAA,iBAQX,CAAA,IAPC,QAAA,UACAA,EAAA,YAAA,cACAA,EAAA,OAAA,SACAA,EAAA,OAAA,SACAA,EAAA,QAAA,UACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QA0DDE,EAAAD,eAAA,GApBWA,EAAAA,EAASA,YAATA,YAoBX,CAAA,IAnBC,WAAA,aACAA,EAAA,mBAAA,qBACAA,EAAA,MAAA,QACAA,EAAA,YAAA,cACAA,EAAA,WAAA,aACAA,EAAA,YAAA,cACAA,EAAA,YAAA,cACAA,EAAA,WAAA,aACAA,EAAA,aAAA,eACAA,EAAA,kBAAA,oBACAA,EAAA,YAAA,cACAA,EAAA,cAAA,gBACAA,EAAA,MAAA,QACAA,EAAA,YAAA,cACAA,EAAA,YAAA,cACAA,EAAA,YAAA,cACAA,EAAA,gBAAA,kBACAA,EAAA,eAAA,iBACAA,EAAA,QAAA,gBC5IWE,EAOOC,aACRC,QAFV,WAAA/E,CACkB8E,EACRC,GADQvF,KAAYsF,aAAZA,EACRtF,KAAOuF,QAAPA,CACN,CAMJ,cAAMC,GACJ,MAAMC,QAAYzF,KAAKuF,QAAQd,gBAAgB,CAC7Ca,aAActF,KAAKsF,eAErB,aAAaI,EAAYA,aAACD,EAAIvD,KAC/B,QCnBUyD,EAWAhC,UACA4B,QAXHK,SAAU,EACVC,cACS1E,OAOjB,WAAAX,CACWmD,EACA4B,EACTpE,GAFSnB,KAAS2D,UAATA,EACA3D,KAAOuF,QAAPA,EAGTvF,KAAKmB,OAASA,GAAUhC,GACzB,CAMD,WAAM2G,SAEE9F,KAAK+F,MAGX/F,KAAK4F,SAAU,EACf5F,KAAKgG,uBACN,CAMM,SAAAC,GACL,OAAOjG,KAAK4F,OACb,CAEO,qBAAAI,GACDhG,KAAK4F,UAGV5F,KAAK6F,cAAgB,IAAItD,SAAQ2D,GAAWC,WAAWD,EAAS,OAAOE,MACrE,IAAMpG,KAAKqG,kBAEd,CAEO,mBAAMA,GACZrG,KAAKmB,OAAOmF,MAAM,2BACZtG,KAAKuF,QAAQlB,iBAAiBrE,KAAK2D,WACzC3D,KAAKmB,OAAOmF,MAAM,kBAClBtG,KAAKgG,uBACN,CAMD,SAAMD,QACuB9D,IAAvBjC,KAAK6F,gBACP7F,KAAK4F,SAAU,EACf5F,KAAKmB,OAAOmF,MAAM,uCACZtG,KAAK6F,cACX7F,KAAKmB,OAAOmF,MAAM,8CAEpBtG,KAAK6F,mBAAgB5D,CACtB,ECxEU,MAAAsE,EAAmC,YACnCC,EAAkC,YAE/B,SAAAC,EACdC,EACAvF,GAEA,MAAMwF,EAAUD,EAAaE,MAAM,gCAC7BC,EACJF,GACIxC,QAAOyC,GAASA,EAAME,WAAWP,KAClCQ,KAAIH,GAASA,EAAMI,UAAUT,MAAqC,GACjEU,EACJN,GACIxC,QAAOyC,GAASA,EAAME,WAAWN,KAClCO,KAAIH,GAASA,EAAMI,UAAUR,MAAoC,GAYtE,OAVIK,EAAgBK,OAAS,IAC1B/F,GAAUgG,SAASC,KAClB,wDAGAH,EAAgBC,OAAS,IAC1B/F,GAAUgG,SAASC,KAClB,wDAGG,CACLC,mBAAoBJ,EAAgB,GACpCK,mBAAoBT,EAAgB,GACpCH,aAAcA,EACXa,QAAQ,+BAAgC,IACxCA,QAAQ,OAAQ,KAChBC,OAEP,OCoJaC,EAGDlC,QAFFpE,OACR,WAAAX,CACU+E,EACRpE,GADQnB,KAAOuF,QAAPA,EAGRvF,KAAKmB,OAASA,GAAUhC,GACzB,CAQD,mBAAMuI,CAAcC,GAClB,MAAMC,EAAeD,GACjBZ,KAAIc,GAAYpB,EAAkBoB,EAAU7H,KAAKmB,UAClD4F,KAAIe,GAAUA,EAAOpB,aAAac,SAC/BO,QAA8B/H,KAAKuF,QAAQ9C,aAAa,CAC5DkF,MAAOC,GAAgB,KAEzB,GACEG,EAAsB1F,OAAS,KAC/B0F,EAAsB1F,OAAS,IAK/B,MAHArC,KAAKmB,OAAOY,MACV,2EAA2EgG,EAAsB1F,WAE7F,IAAI1E,MAAM,6BAElB,MAAMqK,EAAQD,EAAsB7F,KAAK8F,MACzChI,KAAKmB,OAAOR,KAAK,YAAYqH,iBAC7B,MAAMC,EAAmB,IAAItC,EAC3BqC,EACAhI,KAAKuF,QACLvF,KAAKmB,QAGP,aADM8G,EAAiBnC,QAChB,IAAIoC,EAAYlI,KAAKuF,QAASyC,EAAOC,EAAkBjI,KAAKmB,OACpE,QAMU+G,EAYD3C,QACQ5B,UACRsE,iBAbFE,iBAAoD,CAAA,EACpDC,oBAAuD,CAAA,EACvDjH,OAQR,WAAAX,CACU+E,EACQ5B,EACRsE,EACR9G,GAHQnB,KAAOuF,QAAPA,EACQvF,KAAS2D,UAATA,EACR3D,KAAgBiI,iBAAhBA,EAGRjI,KAAKmB,OAASA,GAAUhC,GACzB,CAUM,aAAA0E,CACLO,EACAsC,EACA5C,GAEA,IAAK4C,EAEH,MADA1G,KAAKmB,OAAOY,MAAM,4BACZ,IAAIpE,MAAM,4BAElB,MAAM0K,EAAiB5B,EAAkBC,EAAc1G,KAAKmB,QACtDmH,EAAatI,KAAKuF,QACrB1B,cAAc,CACb6C,aAAc2B,EAAe3B,aAC7B6B,WAAYF,EAAef,mBAC3BkB,cAAeH,EAAehB,mBAE9B1D,UAAW3D,KAAK2D,aAEb8E,OAAOC,YACRD,OAAOE,QAAQ7E,GAAU,CAAE,GAAEK,QAAO,EAAEyE,EAAGC,UAAa5G,IAAN4G,OAGnDzC,MAAKX,GACGA,EAAIvD,KAAK4G,eAGpB,OADA9I,KAAKmI,iBAAiB/D,GAAMkE,EACrBA,CACR,CAUM,oBAAAvE,CACLK,EACA/B,EACAyB,GAEA,MAAMwE,EAAatI,KAAKmI,iBAAiB/D,IAAKgC,MAAKxB,GACjD5E,KAAKuF,QACFxB,qBAAqB,CACpB1B,OAAQA,EACRyG,aAAclE,KACXd,IAEJsC,MAAK,IAAMxB,MAGhB,OADA5E,KAAKoI,oBAAoBhE,GAAMkE,EACxBA,CACR,CAYM,yBAAMS,CACX3E,EACAU,EACAC,EACAC,EACAgE,SAEMhJ,KAAKmI,iBAAiB/D,IAAKgC,MAAKxB,GACpC5E,KAAKuF,QAAQZ,YACXC,EACAoE,EACAlE,EACAC,EACAC,KAGL,CAMM,eAAMiE,GAEX,MAAMhF,QACG1B,QAAQ2G,IAAIT,OAAOU,OAAOnJ,KAAKmI,oBAAuB,SAGnD5F,QAAQ2G,IAAIT,OAAOU,OAAOnJ,KAAKoI,4BAG/BpI,KAAKiI,kBAAkBlC,aACvB/F,KAAKuF,QAAQ7B,WAAW1D,KAAK2D,WAGzC,MACMyF,SADapJ,KAAKuF,QAAQvB,wBAAwBC,IACjC/B,MAAQ,GAC/B,GAAIkH,EAAUlC,OAAS,EAAG,CACxBlH,KAAKmB,OAAOR,KAAKwB,KAAKC,UAAUgH,IAEhC,MAAMC,EAAa,IACnBC,EAAAA,cACEC,EAAQC,KAACH,EAAY,oBACrBlH,KAAKC,UAAUgH,EAAW,KAAM,GAEnC,CACF,ECzWH,IAAYK,EAMXrE,EAAAqE,6BAAA,GANWA,EAAAA,EAAuBA,0BAAvBA,0BAMX,CAAA,IALC,OAAA,SACAA,EAAA,OAAA,SACAA,EAAA,QAAA,UACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QCbF,MAAMxM,EAAYC,EAAUC,QAWfuM,EAA0D,CACrEC,iBAHyB,6BA6BrB,SAAUC,EAAwBrM,GACtC,IAAKC,OAAOC,UAAUF,EAAOG,YAAcH,EAAOG,WAAa,EAC7D,MAAM,IAAIC,MACR,+CAA+CJ,EAAOG,cAG1D,IACGT,EAAUW,MAAML,EAAOoM,iBAAkB,CACxC9L,UAAW,CAAC,OAAQ,SACpBC,aAAa,EACbC,wBAAwB,EACxBC,eAAe,EACfC,iBAAiB,EACjBC,8BAA8B,EAC9BC,oBAAoB,EACpBC,cAAc,EACdC,kBAAkB,IAGpB,MAAM,IAAIV,MACR,sDAAsDJ,EAAOoM,oBAIjE,GAAI1M,EAAUqB,QAAQf,EAAOgB,QAC3B,MAAM,IAAIZ,MAAM,6BAEpB,CCUgB,SAAAkM,EACdtM,EACAuM,GAEA,OAAOrB,OAAOsB,OACZ,GACAxM,EACAkL,OAAOC,YACLD,OAAOE,QAAQmB,GAAa,CAAA,GAAI3F,QAAO,EAAEyE,EAAGC,UAAa5G,IAAN4G,KAGzD,CAOM,SAAUmB,EAAWzM,GACzB,OV7EI,SACJA,GAEA,YAC4B0E,IAA1B1E,EAAOF,qBACW4E,IAAlB1E,EAAOgB,aACc0D,IAArB1E,EAAOG,SAEX,CUqESuM,CAAwB1M,ID/E3B,SACJA,GAEA,YAC8B0E,IAA5B1E,EAAOoM,uBACW1H,IAAlB1E,EAAOgB,aACc0D,IAArB1E,EAAOG,SAEX,CCuE4CwM,CAA0B3M,EACtE,CAOM,SAAU4M,EACdC,GAEA,MAAMC,EAAiBD,GAAc,GAAGE,QAAQC,sBAChD,IAAKC,EAAAA,WAAWH,GACd,MAAO,GAET,MAAMI,EAAeC,EAAAA,aAAaL,EAAgB,QAClD,OAAOlI,KAAKwI,MAAMF,EACpB,CAOM,SAAUG,EAAerN,GAC7BD,EAAsBC,GACtBqM,EAAwBrM,EAC1B,+EHvGUgI,QACAsF,YACA1J,OACA2J,SACAC,YAAsB,EACtBC,aAAuB,EAM/B,WAAAxK,CAAYjD,EAAuB4D,GACjCnB,KAAKmB,OAASA,GAAUhC,IACxBa,KAAKuF,QAAU,IAAIvE,EAAQzD,EAAQyC,KAAKmB,QACxCnB,KAAK6K,YAAc,IAAIpD,EAAezH,KAAKuF,QAASvF,KAAKmB,QACzD,MAAM6G,EAAQsC,QAAQW,IAAqB,gBAC3C,QAAchJ,IAAV+F,EAAqB,CACvB,MAAMkD,EAAI,IAAIhD,EACZlI,KAAKuF,QACL4F,SAASnD,QACT/F,EACAjC,KAAKmB,QAEPnB,KAAK8K,SAAW,IAAIvI,SAAQ2D,GAAWA,EAAQgF,KAC/ClL,KAAK+K,YAAa,CACnB,CACF,CAQM,iBAAMK,CAAYzD,GACvB,QAAsB1F,IAAlBjC,KAAK8K,SAIP,MAHA9K,KAAKmB,OAAOY,MACV,oEAEI,IAAIpE,MACR,oEAGJqC,KAAK8K,SAAW9K,KAAK6K,YAAYnD,cAAcC,GAC/C,MAAM0D,QAA4BrL,KAAK8K,SAGvC,OAFA9K,KAAK+K,YAAa,EAClBT,QAAQW,IAAqB,gBAAII,EAAoB1H,UAAU2H,WACxDD,EAAoB1H,SAC5B,CAUM,mBAAME,CACXO,EACAsC,EACA5C,GAEA,QAAsB7B,IAAlBjC,KAAK8K,SAIP,MAHA9K,KAAKmB,OAAOY,MACV,iEAEI,IAAIpE,MACR,iEAIJ,aADuBqC,KAAK8K,UACZjH,cAAcO,EAAIsC,EAAc5C,EACjD,CAUM,0BAAMC,CACXK,EACA/B,EACAyB,GAEA,QAAsB7B,IAAlBjC,KAAK8K,SAIP,MAHA9K,KAAKmB,OAAOY,MACV,uEAEI,IAAIpE,MACR,uEAIJ,aADuBqC,KAAK8K,UACZ/G,qBAAqBK,EAAI/B,EAAQyB,EAClD,CAOM,eAAMmF,GACX,QAAsBhH,IAAlBjC,KAAK8K,SAEP,MADA9K,KAAKmB,OAAOY,MAAM,+CACZ,IAAIpE,MAAM,qDAEZqC,KAAK8K,SACR1E,MAAK0E,GAAYA,EAAS7B,cAC1B7C,MAAK,IAAOpG,KAAKgL,aAAc,GACnC,CAYM,yBAAMjC,CACX3E,EACAU,EACAC,EACAC,EACAgE,GAEA,QAAsB/G,IAAlBjC,KAAK8K,SAIP,MAHA9K,KAAKmB,OAAOY,MACV,+DAEI,IAAIpE,MACR,+DAGJ,aAAaqC,KAAK8K,SAAS1E,MAAK0E,GAC9BA,EAAS/B,oBACP3E,EACAU,EACAC,EACAC,EACAgE,IAGL,CAMM,cAAAuC,GACL,QACIvL,KAAK+K,YAAe/K,KAAK+K,YAAc/K,KAAKgL,cACb,GAAjChL,KAAKuF,QAAQlE,gBAEhB,yDI5KmBkE,QAApB,WAAA/E,CAAoB+E,GAAAvF,KAAOuF,QAAPA,CAAoB,CAQxC,cAAMiG,CAASjH,GACb,MAAMkH,SACEzL,KAAKuF,QAAQjB,gBAAgBC,IACnCrC,KAAKoD,aACP,OAAO,IAAID,EAAMoG,EAAkBzL,KAAKuF,QACzC,oDCEUtE,QAZMC,OAETE,cACAD,OAIR,oBAAWE,GACT,OAAOrB,KAAKoB,aACb,CAED,WAAAZ,CACWS,EACTE,GADSnB,KAAOiB,QAAPA,EAGTjB,KAAKoB,cAAgB,EACrBpB,KAAKmB,OAASA,GAAUhC,IACxByK,EAAwB3I,GACxBjB,KAAKkB,OAASI,EAAMC,OAAO,CACzBC,QAASP,EAAQ0I,iBACjBlI,QAAS,IACTC,QAAS,CACP,YAAaT,EAAQ1C,OACrB,eAAgB,oBAElBoD,aAAc,SAEhB3B,KAAKkB,OAAOU,aAAaC,SAASC,KAChC,SAAUD,GACR,OAAOA,CACR,IACAE,IAEC,MAAMC,OAEqBC,IAAzBF,EAAMF,UAAUK,KACZC,KAAKC,UAAUL,EAAMF,SAASK,MAC9B,eAAeH,EAAMF,UAAUQ,uBAAuBN,EAAMF,UAAUS,cAE5E,OADAtC,KAAKmB,OAAOY,MAAM,uBAAuBC,KAClCO,QAAQC,OAAOT,EAAM,GAGjC,CAED,kBAAM2J,CACJnD,EACA5H,GAEAX,KAAKoB,eAAiB,EACtB,IACE,aAAapB,KAAKkB,OAAOwB,KACvB,wBAAwB6F,WACxB5H,EAEH,CAAS,QACRX,KAAKoB,eAAiB,CACvB,CACF,qLFhCG,SAAqBuK,GAEzB,IAAIpO,EAAkC,IACjCmM,KACAtM,GAmBL,GAdEG,OADkB0E,IAAhB0J,QAAwD1J,IAA3B0J,EAAYvB,WAClCP,EACPtM,EACA4M,EAAmByB,EAAKpC,KAAKc,QAAQC,MAAOoB,EAAYvB,cAIjDP,EAAetM,EAAQ4M,UAIdlI,IAAhB0J,QAAwD1J,IAA3B0J,EAAYE,aAC3CtO,EAASsM,EAAetM,EAAQoO,EAAYE,cAGzC7B,EAAWzM,GACd,MAAM,IAAII,MAAM,0BAIlB,MAAMmO,EAAcvO,EAIpB,OAFAqN,EAAekB,GAERA,CACT,6GA6DM,SAAgCvO,GACpC,QACuB0E,IAArB1E,EAAOG,aACLF,OAAOC,UAAUF,EAAOG,YAAcH,EAAOG,WAAa,GAE5D,MAAM,IAAIC,MACR,+CAA+CJ,EAAOG,aAG5D"} \ No newline at end of file diff --git a/dist/index.mjs b/dist/index.mjs index 821ff71..2cc8231 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -179,6 +179,7 @@ class AutoApi { sdkVersion: `js:${API_VERSION}`, // Copy over the product id productId: this.options.productId, + applauseTestCycleId: 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 a9d9a97..89ff64c 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 // 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 // Optional: an applause test cycle id\n itwTestCycleId?: number;\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 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 diff --git a/src/auto-api/auto-api.ts b/src/auto-api/auto-api.ts index 54481c7..7a53eaf 100644 --- a/src/auto-api/auto-api.ts +++ b/src/auto-api/auto-api.ts @@ -94,6 +94,8 @@ export class AutoApi { // Copy over the product id productId: this.options.productId, + applauseTestCycleId: this.options.applauseTestCycleId, + // Copy over test rail parameters testRailReportingEnabled: this.options.testRailOptions !== undefined, addAllTestsToPlan: this.options.testRailOptions?.addAllTestsToPlan, diff --git a/src/auto-api/dto.ts b/src/auto-api/dto.ts index ca1a1ee..7cf1946 100644 --- a/src/auto-api/dto.ts +++ b/src/auto-api/dto.ts @@ -12,9 +12,6 @@ export type ClientConfig = { export interface TestRunCreateDto { // Required: a list of test cases to pre-create tests: string[]; - - // Optional: an applause test cycle id - itwTestCycleId?: number; } /** From 3f344d74918a18ebdd62fa5c58ed9d7377a96572 Mon Sep 17 00:00:00 2001 From: rconner46 Date: Fri, 16 Aug 2024 10:27:47 -0500 Subject: [PATCH 6/6] 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,