diff --git a/azure-pipelines-automated-testing.yml b/azure-pipelines-automated-testing.yml deleted file mode 100644 index bed6c877..00000000 --- a/azure-pipelines-automated-testing.yml +++ /dev/null @@ -1,475 +0,0 @@ -trigger: - branches: - include: [ develop, release/* ] - paths: - exclude: - - deployment/* - include: - - "*" -pr: - branches: - include: [ '*' ] - paths: - exclude: - - deployment/* - include: - - "*" - -resources: - containers: - - container: node - image: packagerepository.sagaws.net:8082/safelite/node-build:18 - - container: awscli - image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9 - repositories: - - repository: AzureDevOps - type: github - name: Safelite/AzureDevOps - endpoint: Safelite - ref: refs/tags/t5.5.40 - -variables: - - group: Digital-Infrastructure - - group: ISS-BuildBranches - - name: dockerImageName - value: 'playwright-tests' - - name: imageTag - value: '$(Build.BuildId)' - - name: totalShards - value: 40 # TODO: Temporarily changed to 40, change back to 4 - -stages: - # PR's - - ${{ if or(eq(variables['Build.Reason'], 'PullRequest'), eq(1,1)) }}: # TODO: Temporarily changed to always be true, change back - # TODO: Temporarily commented out - - stage: TestPr - displayName: Run Tests For PullRequest - jobs: - # - template: templates/digital/vue-jest-run-unit-tests.yml@AzureDevOps - # parameters: - # nodeContainer: node - # 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 - shard3: - shardNumber: 3 - shard4: - shardNumber: 4 - - steps: - - task: Docker@2 - displayName: 'Build Docker Image' - inputs: - command: build - dockerfile: Dockerfile.playwright - repository: $(dockerImageName) - tags: $(imageTag) - arguments: '--no-cache --pull' - - - script: | - # 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 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 \"@smoke | @Advanced\"") - - # 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)!" - exit 1 - 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() - - - job: download_and_merge_reports - dependsOn: playwright_tests - steps: - - task: DownloadPipelineArtifact@2 - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/playwright-reports' - # - script: | - # for dir in $(System.DefaultWorkingDirectory)/playwright-reports/*/; do - # if [ -d "$dir" ]; then - # mv "$dir"* $(System.DefaultWorkingDirectory)/playwright-reports/ - # rmdir "$dir" - # fi - # done - # ls - # displayName: move_reports - - task: Docker@2 - displayName: 'Build Docker Image' - inputs: - command: build - dockerfile: Dockerfile.playwright - repository: $(dockerImageName) - tags: $(imageTag) - arguments: '--no-cache --pull' - - bash: | - # 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) \ - $(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...\" && - npx playwright merge-reports --reporter=ortoni-report ./playwright-reports - # npx playwright merge-reports --config=playwright-tests/playwright.config.ts ./playwright-reports - # num_failures=$(sed -n 's/.*failures="\([^"]*\)".*/\1/p' /app/test-results/junit_results.xml | head -n 1) - # echo \"Number of test failures: '$num_failures'\" - # (($num_failures -eq 0)) && jira_message='Playwright tests passed!' || jira_message=\"$num_failures Playwright tests failed.\" - # TODO: Update to include test status message later - echo \"Contents of ortoni-report:\" && ls ./ortoni-report && - echo \"Writing report to Jira card '$(Build.SourceBranchName)'...\" && - ./devops/scripts/jira_writeback.sh add_comment \"$(Build.SourceBranchName)\" /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 - - # 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) - # TODO: Update to include junit results if necessary - - # Remove container - echo "Cleaning up container..." - docker rm $container_id - env: - JIRA_API_KEY: $(JIRA_API_KEY) - displayName: merge_and_publish_results_to_jira - - # TODO: Enable later when working on PR gate - # - 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 - condition: eq(variables['Build.SourceBranch'], variables['dev-branch'] ) - variables: - - group: ISS-Dev - jobs: - - deployment: devBuildDeployment - displayName: Build and Deploy ISS - Dev - environment: digitalCloud-dev - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/dev' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Dev - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistDev - awsProfile: $(devDeploymentProfile) - deployBuckets: - safelite-dev-iss-us-east-2: - clearFolder: true - deployFolder: '' - region: us-east-2 - safelite-dev-iss-us-east-1: - clearFolder: true - deployFolder: '' - region: us-east-1 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(devDeploymentProfile) - - # Test Build/Deploy - - stage: Test - condition: eq(variables['Build.SourceBranch'], variables['test-branch'] ) - variables: - - group: ISS-Test - jobs: - - deployment: testBuildDeployment - displayName: Build and Deploy ISS - Test - environment: NoApproval-All - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/test' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Test - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistTest - awsProfile: $(sysDeploymentProfile) - deployBuckets: - safelite-sys-iss-us-east-1: - clearFolder: true - deployFolder: "" - region: us-east-1 - safelite-sys-iss-us-east-2: - clearFolder: true - deployFolder: "" - region: us-east-2 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(sysDeploymentProfile) - - # QA Build/Deploy - - stage: QA - condition: eq(variables['Build.SourceBranch'], variables['qa-branch'] ) - variables: - - group: ISS-QA - jobs: - - deployment: qaBuildDeployment - displayName: Build and Deploy ISS - QA - environment: NoApproval-All - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/qa' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Qa - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistQa - awsProfile: $(qaDeploymentProfile) - deployBuckets: - safelite-qa-iss-us-east-1: - clearFolder: true - deployFolder: "" - region: us-east-1 - safelite-qa-iss-us-east-2: - clearFolder: true - deployFolder: "" - region: us-east-2 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(qaDeploymentProfile) - - # Prod Build/Deploy - - stage: Prod - condition: succeeded('QA') - variables: - - group: ISS-Prod - jobs: - - deployment: prodBuildDeployment - displayName: Build and Deploy ISS - Prod - environment: digitalCloud-prod - container: node - workspace: - clean: all - strategy: - runOnce: - deploy: - steps: - - checkout: self - clean: true - - task: CopyFiles@2 - inputs: - SourceFolder: 'public/apple-pay/prod' - Contents: '**' - TargetFolder: 'public/.well-known' - CleanTargetFolder: true - - task: DeleteFiles@1 - inputs: - SourceFolder: 'public/apple-pay' - Contents: '**' - RemoveSourceFolder: true - - template: templates/digital/step-build-vue.yml@AzureDevOps - parameters: - buildOutputDir: dist - environment: Prod - - template: templates/digital/step-deploy-vue.yml@AzureDevOps - parameters: - artifactName: vueDistProd - awsProfile: $(prodDeploymentProfile) - deployBuckets: - safelite-prod-iss-us-east-1: - clearFolder: true - deployFolder: "" - region: us-east-1 - safelite-prod-iss-us-east-2: - clearFolder: true - deployFolder: "" - region: us-east-2 - appDeployVariables: - __VUE_APP_CONSUMER_CF_DISTRO__: $(__VUE_APP_CONSUMER_CF_DISTRO__) - __VUE_APP_CURRENT_ENVIRONMENT__: $(__VUE_APP_CURRENT_ENVIRONMENT__) - __VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__) - __VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__) - __VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__) - indexDeployVariables: - __VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__) - __VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__) - __VUE_APP_GOOGLE_MAPS_API_SCRIPT__: $(__VUE_APP_GOOGLE_MAPS_API_SCRIPT__) - - template: templates/digital/invalidate-cloudfront-cache.yml@AzureDevOps - parameters: - awsCliContainer: awscli - distributionId: $(cfDistributionId) - paths: /* - awsProfile: $(prodDeploymentProfile) - - template: templates/digital/auto-tag.yml@AzureDevOps - parameters: - dependsOn: prodBuildDeployment - userName: SafeliteAzureDevops - userEmail: githubazuredevops@safelite.com - diff --git a/azure-pipelines.yml b/azure-pipelines.yml index cedebb5b..6bddeece 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -90,7 +90,6 @@ stages: "npx wait-on http://localhost:8080 && npm run test:playwright -- --shard=$(shardNumber)/$(totalShards) --reporter=list,blob --grep \"@smoke | @Advanced\"") # Start container and stream logs - echo "Starting tests for shard $(shardNumber)..." docker start -a $container_id @@ -127,26 +126,60 @@ stages: condition: always() - job: download_and_merge_reports - container: - image: mcr.microsoft.com/playwright:v1.48.0-noble dependsOn: playwright_tests steps: - - task: DownloadPipelineArtifact@2 - inputs: - targetPath: '$(System.DefaultWorkingDirectory)/playwright-reports' - - script: | - npm i ortoni-report && - for dir in $(System.DefaultWorkingDirectory)/playwright-reports/*/; do - if [ -d "$dir" ]; then - mv "$dir"* $(System.DefaultWorkingDirectory)/playwright-reports/ - rmdir "$dir" - fi - done - npx playwright merge-reports --reporter=ortoni-report,junit $(System.DefaultWorkingDirectory)/playwright-reports - ls - displayName: merge_reports - env: - PLAYWRIGHT_JUNIT_OUTPUT_FILE: "test-results/results.xml" + - 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: | + # 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) \ + $(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...\" && + npx playwright merge-reports --reporter=ortoni-report ./playwright-reports + # npx playwright merge-reports --config=playwright-tests/playwright.config.ts ./playwright-reports + # num_failures=$(sed -n 's/.*failures="\([^"]*\)".*/\1/p' /app/test-results/junit_results.xml | head -n 1) + # echo \"Number of test failures: '$num_failures'\" + # (($num_failures -eq 0)) && jira_message='Playwright tests passed!' || jira_message=\"$num_failures Playwright tests failed.\" + # TODO: Update to include test status message later + echo \"Contents of ortoni-report:\" && ls ./ortoni-report && + echo \"Writing report to Jira card '$(Build.SourceBranchName)'...\" && + ./devops/scripts/jira_writeback.sh add_comment \"$(Build.SourceBranchName)\" /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 + + # 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) + # TODO: Update to include junit results if necessary + + # Remove container + echo "Cleaning up container..." + docker rm $container_id + env: + JIRA_API_KEY: $(JIRA_API_KEY) + displayName: merge_and_publish_results_to_jira # TODO: Enable later when working on PR gate # - task: PublishTestResults@2 @@ -154,19 +187,23 @@ stages: # inputs: # searchFolder: 'test-results' # testResultsFormat: 'JUnit' - # testResultsFiles: 'results.xml' + # 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' + - 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