From 7d20b0074ccd5409d0d79918d08cabf8b710e031 Mon Sep 17 00:00:00 2001 From: maguire-arman Date: Thu, 10 Apr 2025 14:03:06 -0400 Subject: [PATCH] Removes PR gate pipeline config Removes the Playwright tests and related jobs from the Azure Pipelines configuration file. These jobs were unintentionally added to the branch and are no longer needed. --- azure-pipelines.yml | 168 --------- .../business-logic/types/JiraApi.ts | 111 ------ playwright-tests/impl/API/JiraApiUtil.ts | 143 -------- .../impl/reporter/JiraWritebackReporter.ts | 339 ------------------ 4 files changed, 761 deletions(-) delete mode 100644 playwright-tests/business-logic/types/JiraApi.ts delete mode 100644 playwright-tests/impl/API/JiraApiUtil.ts delete mode 100644 playwright-tests/impl/reporter/JiraWritebackReporter.ts 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