diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8c5e61265..2cb18429c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -34,12 +34,6 @@ resources: variables: - group: Digital-Infrastructure - group: FixMyGlass-BuildBranches - - name: dockerImageName - value: 'playwright-tests' - - name: imageTag - value: '$(Build.BuildId)' - - name: totalShards - value: 2 stages: # PR's @@ -63,168 +57,6 @@ stages: npmLocation: $(Build.SourcesDirectory) testResultsFile: junit.xml summaryFileLocation: $(Build.SourcesDirectory)/coverage/cobertura-coverage.xml - - job: playwright_tests - continueOnError: true - strategy: - matrix: - shard1: - shardNumber: 1 - shard2: - shardNumber: 2 - - steps: - - task: Docker@2 - displayName: 'Build Docker Image' - inputs: - command: build - dockerfile: Dockerfile.playwright - repository: $(dockerImageName) - tags: $(imageTag) - arguments: '--no-cache --pull' - - - script: | - branch_name=$(System.PullRequest.SourceBranch) - echo "Retrieved branch name: '$branch_name'" - JIRA_CARD_NUMBER="${branch_name##*/}" - echo "Extracted JIRA Card number: '$JIRA_CARD_NUMBER'" - # Create container and run tests - container_id=$(docker create \ - --ipc=host \ - -e CCIS_API_AUTH=$(CCIS_API_AUTH) \ - -e BASE_URL=$(BASE_URL) \ - -e CCIS_API_URL=$(CCIS_API_URL) \ - -e ADMIN_SERVICE_API_URL=$(ADMIN_SERVICE_API_URL) \ - -e SHARD=$(shardNumber) \ - -e CI=true \ - -e ENABLE_MOCK_TESTING=true \ - -e ENABLE_ACCESSIBILITY_TESTING=true \ - -e NODE_ENV=$(NODE_ENV) \ - $(dockerImageName):$(imageTag) \ - npx concurrently -k -n "server,playwright"\ - "sed -i \"s|^process\.env\.VUE_APP_CONSUMER_CF_DISTRO = .*|process\.env\.VUE_APP_CONSUMER_CF_DISTRO='https://digitalapi.test.safelite.io'|\" \"./vue.config.js\" && echo \"Updated config file to use TEST APIs\" && npm run serve -- --port=8080"\ - "npx wait-on http://localhost:8080 && npm run test:playwright -- --shard=$(shardNumber)/$(totalShards) --reporter=list,blob --grep \"@$JIRA_CARD_NUMBER\"") - - # Start container and stream logs - echo "Starting tests for shard $(shardNumber)..." - docker start -a $container_id - - # Create directory for test results - echo "Creating test results directory..." - mkdir -p $(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber) - - # Copy test results from container - echo "Copying test results..." - docker cp $container_id:/app/blob-report/. $(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber)/ - - # Remove container - echo "Cleaning up container..." - docker rm $container_id - - # Check if tests failed - if [ $? -ne 0 ]; then - echo "Tests failed in shard $(shardNumber) or tests don't exist for this shard number!" - exit 0 # Suppress error. It will be visible in report. - fi - displayName: 'Run Playwright Tests - Shard $(shardNumber)' - - - task: PublishPipelineArtifact@1 - displayName: 'Publish Test Reports - Shard $(shardNumber)' - condition: always() - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/blob-reports/shard-$(shardNumber)' - artifact: 'playwright-report-shard-$(shardNumber)' - publishLocation: 'pipeline' - - - script: | - docker rmi $(dockerImageName):$(imageTag) -f - displayName: 'Cleanup Docker Image' - condition: always() - - # Add job to merge test reports and update Jira - - job: download_and_merge_reports - dependsOn: playwright_tests - timeoutInMinutes: 10 - cancelTimeoutInMinutes: 10 - steps: - - task: DownloadPipelineArtifact@2 - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/playwright-reports' - - task: Docker@2 - displayName: 'Build Docker Image' - inputs: - command: build - dockerfile: Dockerfile.playwright - repository: $(dockerImageName) - tags: $(imageTag) - arguments: '--no-cache --pull' - - bash: | - branch_name=$(System.PullRequest.SourceBranch) - echo "Retrieved branch name: '$branch_name'" - JIRA_CARD_NUMBER="${branch_name##*/}" - echo "Extracted JIRA Card number: '$JIRA_CARD_NUMBER'" - # Create container for jira writeback - container_id=$(docker create \ - --ipc=host \ - -e JIRA_SERVER=$(JIRA_SERVER) \ - -e JIRA_USERNAME=$(JIRA_USERNAME) \ - -e JIRA_API_KEY=$(JIRA_API_KEY) \ - -e JIRA_CARD_NUMBER="$JIRA_CARD_NUMBER" \ - $(dockerImageName):$(imageTag) \ - bash -c "echo \"Moving Playwright reports out of subfolders...\" && - find ./playwright-reports/ -mindepth 2 -type f -exec mv {} ./playwright-reports/ \; && - echo \"Merging reports...\" && - export NODE_OPTIONS=--max_old_space_size=4096 - PLAYWRIGHT_JUNIT_OUTPUT_DIR='/app/test-results' PLAYWRIGHT_JUNIT_OUTPUT_NAME='junit_results.xml' npx playwright merge-reports --reporter=ortoni-report,junit,\"/app/playwright-tests/impl/reporter/JiraWritebackReporter.ts\" ./playwright-reports - echo \"Contents of ortoni-report:\" && ls ./ortoni-report && - echo 'Current dir: ' && pwd - echo 'Contents of current dir: ' && ls - echo 'Contents of /app/test-results' && ls /app/test-results - echo \"Writing report to Jira card '$JIRA_CARD_NUMBER'...\" && - /app/devops/scripts/jira_writeback.sh add_comment \"$JIRA_CARD_NUMBER\" /app/ortoni-report/ortoni-report.html \"AUTOMATED TEST RUN: $(date)\" ") - - # Start container and stream logs - echo "Starting merge" - docker start -a $container_id - - # Create directory for test results - echo "Creating test results directory..." - mkdir -p $(System.DefaultWorkingDirectory)/ortoni-report - mkdir -p $(System.DefaultWorkingDirectory)/test-results - - # Copy test results from container - echo "Copying test results..." - docker cp $container_id:/app/ortoni-report/. $(System.DefaultWorkingDirectory)/ortoni-report - docker cp $container_id:/app/test-results/junit_results.xml $(System.DefaultWorkingDirectory)/test-results - - # Remove container - echo "Cleaning up container..." - docker rm $container_id - env: - JIRA_API_KEY: $(JIRA_API_KEY) - displayName: merge_and_publish_results_to_jira - - - task: PublishTestResults@2 - displayName: 'Publish test results' - inputs: - searchFolder: 'test-results' - testResultsFormat: 'JUnit' - testResultsFiles: 'junit_results.xml' - mergeTestResults: true - failTaskOnFailedTests: false - testRunTitle: 'Playwright Tests' - condition: succeededOrFailed() - - - task: PublishPipelineArtifact@1 - displayName: 'Publish Merged Report' - condition: always() - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/ortoni-report' - artifact: 'playwright-merged-report' - publishLocation: 'pipeline' - - script: | - docker rmi $(dockerImageName):$(imageTag) -f - displayName: 'Cleanup Docker Image' - condition: always() - ${{ else }}: # Dev Build/Deploy - stage: Dev diff --git a/playwright-tests/business-logic/types/JiraApi.ts b/playwright-tests/business-logic/types/JiraApi.ts deleted file mode 100644 index d5b34b081..000000000 --- a/playwright-tests/business-logic/types/JiraApi.ts +++ /dev/null @@ -1,111 +0,0 @@ -export interface PutEditIssueRequestBody { - fields: Partial -} - -export interface PostTransitionIssueRequestBody { - transition: { id: string } -} - -export interface PostCreateIssueRequestBody extends JiraIssue {} - -export interface PostCreateIssueResponse { - id: string, - key: string -} - -export interface PostBulkCreateIssueRequestBody { - issueUpdates: PostCreateIssueRequestBody[] -} - -export interface BulkTransitionInput { - selectedIssueIdsOrKeys: string[], - transitionId: string -} - -export interface PostBulkTransitionIssuesRequestBody { - bulkTransitionInputs: BulkTransitionInput[], - sendBulkNotification: false -} - -export interface PostBulkCreateIssueResponse { - issues: PostCreateIssueResponse[] -} - -export interface PostAddCommentResponse { - body: JiraContent -} - -export interface JiraIssueFields { - summary: string, - description: JiraContent, - project?: JiraProject, - issuetype?: { id: string }, - parent?: JiraParent, - fixVersions?: JiraVersion[], - subtasks?: JiraSubTask[], - customfield_14857?: JiraContent // Test Steps field -} - -export interface JiraSubTask { - id: string, - key: string -} - -export interface JiraProject { - key: string -} - -export interface JiraParent { - key: string -} - -export interface JiraContent { - type?: string, - text?: string, - version?: number - content?: JiraContent[] -} - -export interface JiraVersion { - id: string -} - -export interface JiraTransition { - id: string, - name: string -} - -export interface JiraIssueType { - id: string, - self: string, - description: string, - iconUrl: string, - name: string, - untranslatedName: string, - subtask: boolean, -} - -export interface GetIssueTransitionsResponse { - transitions: JiraTransition[] -} - -export interface GetIssueTypesResponse { - issueTypes: JiraIssueType[] -} - -export interface PostBulkFetchIssuesRequestBody { - issueIdsOrKeys: string[] -} - -export interface PostBulkFetchIssuesResponse { - issues: GetIssueResponse[]; -} - -export interface JiraIssue { - key?: string, - id?: string, - transition?: { id: string }, - fields: JiraIssueFields -} - -export interface GetIssueResponse extends JiraIssue {} \ No newline at end of file diff --git a/playwright-tests/impl/API/JiraApiUtil.ts b/playwright-tests/impl/API/JiraApiUtil.ts deleted file mode 100644 index fdb970d1e..000000000 --- a/playwright-tests/impl/API/JiraApiUtil.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { PostBulkFetchIssuesRequestBody, PostBulkFetchIssuesResponse, GetIssueResponse, GetIssueTransitionsResponse, GetIssueTypesResponse, PostAddCommentResponse, PostBulkCreateIssueRequestBody, PostBulkCreateIssueResponse, PostCreateIssueRequestBody, PostCreateIssueResponse, PostTransitionIssueRequestBody, PutEditIssueRequestBody, PostBulkTransitionIssuesRequestBody } from "@business-logic/types/JiraApi"; -import axios, { request } from "axios"; -import axiosRetry from "axios-retry"; - -const jiraUrl = process.env.JIRA_SERVER!; -const jiraUsername = process.env.JIRA_USERNAME!; -const jiraApiKey = process.env.JIRA_API_KEY!; -const encodedAuthKey = Buffer.from(`${jiraUsername}:${jiraApiKey}`).toString('base64'); - -export default class JiraApiUtil { - readonly baseUrl: string; - readonly issueUrl: string; - readonly bulkIssueCreateUrl: string; - readonly bulkIssueFetchUrl: string; - readonly bulkTransitionIssuesUrl: string; - readonly axiosClient: axios.AxiosInstance; - - constructor() { - this.baseUrl = jiraUrl; - this.issueUrl = `${this.baseUrl}/rest/api/3/issue`; - this.bulkIssueCreateUrl = `${this.issueUrl}/bulk`; - this.bulkIssueFetchUrl = `${this.issueUrl}/bulkfetch`; - this.bulkTransitionIssuesUrl = `${this.baseUrl}/rest/api/3/bulk/issues/transition` - this.axiosClient = axios.create(); - // interceptor to log error message from api - this.axiosClient.interceptors.response.use( - response => response, - error => { - console.error('Axios Error:', error?.response?.data || error.message); - return Promise.reject(error); - } - ); - // Set up retries if requests are made too quickly - axiosRetry(this.axiosClient, { - retries: 4, - retryDelay: (retryCount) => { return Math.pow(2, retryCount) * 1000; }, // Exponential backoff - retryCondition: (error) => { return error.response?.status === 429 } // If rate-limit error - }); - } - - getIssue(issueKey: string) { - const url = `${this.issueUrl}/${issueKey}`; - return this.axiosClient.get(url, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - Accept: 'application/json' - } - }); - } - - postBulkFetchIssues(requestBody: PostBulkFetchIssuesRequestBody) { - return this.axiosClient.post(this.bulkIssueFetchUrl, requestBody, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - }); - } - - getIssueTransitions(issueKey: string) { - const url = `${this.issueUrl}/${issueKey}/transitions` - return this.axiosClient.get(url, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - Accept: 'application/json' - } - }); - } - - getIssueTypes(projectKey: string) { - const url = `${this.baseUrl}/rest/api/3/issue/createmeta/${projectKey}/issuetypes`; - return this.axiosClient.get(url, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - Accept: 'application/json' - } - }); - } - - postAddComment(issueKey: string, commentBody: PostAddCommentResponse) { - const url = `${this.issueUrl}/${issueKey}/comment`; - return this.axiosClient.post(url, commentBody, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - }); - } - - postTransitionIssue(issueKey: string, requestBody: PostTransitionIssueRequestBody) { - const transitionUrl = `${this.issueUrl}/${issueKey}/transitions` - return this.axiosClient.post(transitionUrl, requestBody, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - }); - } - - putEditIssue(issueKey: string, requestBody: PutEditIssueRequestBody) { - const editIssueUrl = `${this.issueUrl}/${issueKey}` - return this.axiosClient.put(editIssueUrl, requestBody, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - } - }); - } - - postBulkTransitionIssues(requestBody: PostBulkTransitionIssuesRequestBody) { - return this.axiosClient.post(this.bulkTransitionIssuesUrl, requestBody, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - }); - } - - postCreateIssue(requestBody: PostCreateIssueRequestBody) { - return this.axiosClient.post(this.issueUrl, requestBody, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - }); - } - - postBulkCreateIssue(requestBody: PostBulkCreateIssueRequestBody) { - return this.axiosClient.post(this.bulkIssueCreateUrl, requestBody, { - headers: { - Authorization: `Basic ${encodedAuthKey}`, - 'Accept': 'application/json', - 'Content-Type': 'application/json' - }, - }); - } -} \ No newline at end of file diff --git a/playwright-tests/impl/reporter/JiraWritebackReporter.ts b/playwright-tests/impl/reporter/JiraWritebackReporter.ts deleted file mode 100644 index c1db33244..000000000 --- a/playwright-tests/impl/reporter/JiraWritebackReporter.ts +++ /dev/null @@ -1,339 +0,0 @@ -import JiraApiUtil from "@impl/API/JiraApiUtil"; -import type { FullResult, Reporter, TestCase, TestResult } from "@playwright/test/reporter"; -import { formatDate } from "@impl/utils/DateUtils"; -import { GetIssueResponse, JiraIssue, JiraIssueFields } from "@business-logic/types/JiraApi"; - -const jiraCardNumber = process.env.JIRA_CARD_NUMBER!; -const jiraProjectKey = 'INSR'; -const passTransitionId = '111'; -const failTransitionId = '101'; - -export default class JiraWritebackReporter implements Reporter { - readonly jiraApiUtil: JiraApiUtil = new JiraApiUtil(); - readonly loadIssueCalls: (() => void)[] = []; // Calls to loadIssue must be deferred because they depend on information from the API. - readonly issuesToPass: string[] = []; // Issues to transition to "Pass". - readonly issuesToFail: string[] = []; // Issues to transition to "Fail". - readonly issuesToCreate: JiraIssue[] = []; // Issues to be batch created. - existingSubtasks: JiraIssue[] = []; // Array to hold existing subtasks of the dev card. - testCaseTypeId: string|undefined = undefined; // ID of the test case subtask type in Jira. Will be filled by API call. - bugTypeId:string|undefined = undefined; // ID of the bug subtask type. - parentCard: GetIssueResponse | undefined = undefined; // Variable to hold the parent card. Will be filled by API call. - - // Will need this if we want to move ortoni report upload into this reporter. - // readonly ortoniReport = new OrtoniReport(reportConfig); - - /** - * This function loads the IDs for the Jira Issue Types we use. - * - */ - async loadJiraIssueTypes() { - console.log(`JiraWritebackReporter >> Loading Jira Issue Types for project '${jiraProjectKey}'...`); - const issueTypesRes = await this.jiraApiUtil.getIssueTypes(jiraProjectKey); - const issueTypes = issueTypesRes.data; - this.testCaseTypeId = issueTypes.issueTypes.find(issueType => { - return issueType.subtask === true && issueType.name === 'Test Case Sub-task' - })?.id; - this.bugTypeId = issueTypes.issueTypes.find(issueType => { - return issueType.subtask === true && issueType.name === 'Bug Sub-task' - })?.id; - console.log('JiraWritebackReporter >> Loaded issue types.'); - } - - /** - * This function generates a test subtask based on the test results we pass in. - * @param test TestCase from onTestEnd() - * @param result TestResult from onTestEnd() - * @returns Jira Test Subtask based on test result. - */ - getCreateTestSubtask(test: TestCase, result: TestResult) { - if (result.status === 'skipped') { - return undefined; - } - const testStepTitles = result.steps.map(step => { - return `-\t${step.title}`; - }).join('\n'); - const allErrors = result.errors.map(value => { - return value.message - }).join('\n'); - - const description = `Most recent test status: ${result.status}.\nDuration: ${result.duration/1000} seconds.\nErrors:\n${allErrors}` - const testSubtaskBody: JiraIssueFields = { - summary: test.title, - description: { - content: [ - { - "content": [ - { - "text": description, - "type": "text" - } - ], - "type": "paragraph" - } - ], - "type": "doc", - "version": 1 - }, - project: { - key: jiraProjectKey - }, - issuetype: { - id: this.testCaseTypeId! - }, - parent: { - key: jiraCardNumber - }, - customfield_14857: { - type: 'doc', - version: 1, - content: [ - { - type: 'paragraph', - content: [ - { - type: 'text', - text: testStepTitles - } - ] - } - ] - } - }; - return testSubtaskBody; - } - - /** - * This function generates a bug subtask based on the test results we pass in. - * @param test TestCase from onTestEnd() - * @param result TestResult from onTestEnd() - * @returns Jira Bug Subtask based on test result. - */ - getCreateBug(test: TestCase, result: TestResult) { - if (result.status === 'passed' || result.status === 'skipped') { - return undefined; - } - const allErrors = result.errors.map(value => { - return value.message - }).join('\n'); - - const bug: JiraIssueFields = { - summary: `TEST FAILED ${formatDate(new Date())}: ${test.title}`, - description: { - content: [ - { - "content": [ - { - "text": allErrors, - "type": "text" - } - ], - "type": "paragraph" - } - ], - "type": "doc", - "version": 1 - }, - project: { - key: jiraProjectKey - }, - issuetype: { - id: this.bugTypeId! - }, - parent: { - key: jiraCardNumber - } - }; - return bug; - } - - /** - * This function gives us the correct transition for a test subtask based on this test result. - * @param result TestResult from onTestEnd() - * @returns Correct transition to pass to the Jira API. - */ - getSubtaskTransition(result: TestResult): { id: string } | undefined { - if (result.status === 'skipped') { - return undefined; - } - - if (result.status === 'passed') { - return { - id: passTransitionId - }; - } else { - return { - id: failTransitionId - }; - } - } - - /** - * Grabs parent card and existing subtasks. - */ - async loadReporterData() { - await this.loadJiraIssueTypes(); - - console.log('JiraWritebackReporter >> Searching for parent card...'); - const parentRes = await this.jiraApiUtil.getIssue(jiraCardNumber); - const parentCard = parentRes.data; - console.log(`JiraWritebackReporter >> Retrieved parent card: ${parentCard.key}: ${parentCard.fields.summary}`); - - console.log(`JiraWritebackReporter >> Searching for all subtasks of parent card '${jiraCardNumber}'...`); - const subtaskIds = parentCard.fields.subtasks?.map(subtask => { - return subtask.id; - }); - - if (subtaskIds && subtaskIds.length > 0) { - for (let i = 0; i < subtaskIds.length; i+=50) { - const batch = subtaskIds.slice(i, i+50); - const subTasksRes = await this.jiraApiUtil.postBulkFetchIssues({ issueIdsOrKeys: batch }); - this.existingSubtasks.push(...subTasksRes.data.issues); - } - console.log('JiraWritebackReporter >> Subtasks retrieved.'); - } else { - console.log('JiraWritebackReporter >> No subtasks were found.'); - } - - } - - /** - * Bulk creates test cases and bugs in batches of up to 50. Bulk transitions existing test case subtasks. - */ - async writeResults() { - for (let i = 0; i < this.issuesToCreate.length; i+=50) { - const batch = this.issuesToCreate.slice(i, i + 50); - console.log('JiraWritebackReporter >> Creating issue batch...'); - // fire request - await this.jiraApiUtil.postBulkCreateIssue({ issueUpdates: batch }); - console.log('JiraWritebackReporter >> Issue batch created.'); - } - - if (this.issuesToPass.length > 0) { - console.log('JiraWritebackReporter >> Transitioning passed test cases to "Pass"...') - await this.jiraApiUtil.postBulkTransitionIssues( { - bulkTransitionInputs: [{ - selectedIssueIdsOrKeys: this.issuesToPass, - transitionId: passTransitionId - }], - sendBulkNotification: false - }); - console.log('JiraWritebackReporter >> Transition success.'); - } - - if (this.issuesToFail.length > 0) { - console.log('JiraWritebackReporter >> Transitioning failed test cases to "Fail"...') - await this.jiraApiUtil.postBulkTransitionIssues( { - bulkTransitionInputs: [{ - selectedIssueIdsOrKeys: this.issuesToFail, - transitionId: failTransitionId - }], - sendBulkNotification: false - }); - console.log('JiraWritebackReporter >> Transition success.') - } - } - - /** - * Builds and loads appropriate response based on test result. This can be a test subtask/bug subtask or a call to transition a test subtask. - * @param test TestCase from onTestEnd() - * @param result TestResult from onTestEnd() - * @returns Void - */ - loadIssue(test: TestCase, result: TestResult) { - if (result.status === 'skipped') return; - if (result.status !== 'passed' && result.retry < test.retries) return; // Skip if test case failed and this isn't the last retry. - - let existingTestSubtask: JiraIssue | undefined = undefined; - let existingBug: JiraIssue | undefined = undefined; - const subtaskTransition = this.getSubtaskTransition(result)!; // Get either a Pass or Fail transition depending on test results. - - console.log('JiraWritebackReporter >> Checking for existing subtasks for this test...'); - for (const card of this.existingSubtasks) { - if (card.fields.issuetype?.id === this.testCaseTypeId) { - if (card.fields.summary === test.title) { - existingTestSubtask = card; - console.log('JiraWritebackReporter >> Found existing test subtask.'); - } - } else if (card.fields.issuetype?.id === this.bugTypeId) { - if (new RegExp(`^TEST FAILED [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]: ${test.title}$`).test(card.fields.summary)) { - existingBug = card; - console.log('JiraWritebackReporter >> Found existing bug.'); - // TODO: Handle multiple matches for bug/test case. Currently picks one in that case. - } - } - } - if (!(existingTestSubtask || existingBug)) { - console.log('JiraWritebackReporter >> No existing test subtask or bug was found.') - } - - const subTask = this.getCreateTestSubtask(test, result); // Will return undefined if test status is 'skipped' - const bug = this.getCreateBug(test, result); // Will return undefined if we don't need one - if (subTask) { - // Create or Edit Subtask - if (existingTestSubtask) { - if (result.status === 'passed') { - this.issuesToPass.push(existingTestSubtask.key!); - } else { - this.issuesToFail.push(existingTestSubtask.key!); - } - } else { - this.issuesToCreate.push({ - fields: subTask, - transition: subtaskTransition - }); - } - } - - if (bug) { - // Create or Edit Bug - if (existingBug) { - // Leave it alone. This reporter should not modify existing bugs. - } else { - this.issuesToCreate.push({ - fields: bug - }); - } - } - } - - /** - * This function loads calls to loadIssue() in an array to be executed when the necessary information from the Jira API is available. - * @param test - * @param result - */ - onTestEnd(test: TestCase, result: TestResult) { - // this.ortoniReport.onTestEnd(test, result); - this.loadIssueCalls.push(() => { this.loadIssue(test, result); }); - } - - /** - * Makes calls to load and execute API calls to Jira. - * @param result - * @returns Promise to write results to Jira. - */ - onEnd(result: FullResult): Promise<{ status?: FullResult["status"]; } | undefined | void>|void { - // this.ortoniReport.onEnd(result); - return this.loadReporterData().then(async () => { - this.loadIssueCalls.map(fn => fn()); - await this.writeResults(); - console.log(`JiraWritebackReporter >> Posted necessary changes for '${jiraCardNumber}'`); - }); - } - - // These overloads will become necessary if we move the ortoni report upload into this reporter - // onBegin(config: FullConfig, suite: Suite): void { - // this.ortoniReport.onBegin(config, suite); - // } - - // onError(error: TestError): void { - // this.ortoniReport.onError(error); - // } - - // onExit(): Promise { - // return this.ortoniReport.onExit(); - // } - - // onStdOut(chunk: string | Buffer, test: void | TestCase, result: void | TestResult): void { - // this.ortoniReport.onStdOut(chunk, test, result); - // } -} \ No newline at end of file