diff --git a/.github/scripts/configure-workflow.sh b/.github/scripts/configure-workflow.sh index e85c7f9..b570040 100644 --- a/.github/scripts/configure-workflow.sh +++ b/.github/scripts/configure-workflow.sh @@ -112,6 +112,8 @@ function get-input-reason() { REASON="$INPUT_REASON" elif [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then REASON="Triggered from PR" + elif [ "$GITHUB_EVENT_NAME" = "schedule" ]; then + REASON="Scheduled run" else REASON="No reason provided" fi @@ -135,3 +137,4 @@ function configure-workflow() { set-output run-tests-args "$(get-run-tests-args $artifact_object_path)" set-output input-reason "$(get-input-reason)" } + diff --git a/.github/workflows/old-automated-idp-web-tests.yml b/.github/workflows/old-automated-idp-web-tests.yml deleted file mode 100644 index eac5fce..0000000 --- a/.github/workflows/old-automated-idp-web-tests.yml +++ /dev/null @@ -1,248 +0,0 @@ -name: Slack - Run UW IdP Web Tests - -on: - push: - branches: - # This branch override is meant to act as a way of validating - # the workflow itself, which is difficult to do well out - # of context. Feel free to push to this branch at any time. - # You may need to use `-f` when pushing. - - run-uw-idp-web-tests - pull_request: - paths-ignore: - - "*.md" # No reason to run tests when only docs change - workflow_dispatch: - inputs: - target-idp-env: - description: > - target-idp-env. Acceptable values are `eval`, `prod`. The idp environment - you want to test against. - required: true - default: eval - - target-idp-host: - description: > - target-idp-host. Optional. If provided, will add an /etc/hosts entry - targeting this host. - required: false - - reason: - description: > - reason. The reason for running this test suite; can be helpful to - provide context and distinguish different runs. - required: false - - slack-channel: - description: > - slack-channel. The channel to send a notification to, detailing the - context and outcome of the test. (`/invite @iam-github-slack-crier` - in the channel, if not already done.) - required: true - default: '#iam-bot-sandbox' - - pytest-args: - description: > - pytest-args. Any args you want to send to pytest. You do not ever need to - supply `log_cli` arguments. - required: false - - -env: - ############################################### - # Do not edit the env values below this line. # - # Other defaults are set in .github/scripts/configure-workflow.sh - SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_BOT_TOKEN }} - ARTIFACT_BUCKET: ${{ secrets.IDENTITY_ARTIFACT_BUCKET }} - ############################################### - -jobs: - run-idp-web-tests: - name: Configure and run tests, and upload test artifacts - runs-on: ubuntu-latest - env: - UPLOAD_STATUS: 'not started' - ARTIFACT_HOST: "https://identity-artifact.iamdev.s.uw.edu" - outputs: - slack-channel: ${{ steps.configure.outputs.slack-channel }} - # These outputs come from the configure-workflow.sh script - report-object-path: ${{ steps.configure.outputs.report-object-path }} - report-url: ${{ steps.configure.outputs.report-url }} - short-sha: ${{ steps.configure.outputs.short-sha }} - pr-number: ${{ steps.configure.outputs.pr-number }} - workflow-id: ${{ steps.configure.outputs.workflow-id }} - workflow-snapshot-artifact: ${{ steps.configure.outputs.workflow-snapshot-artifact }} - idp-env: ${{ steps.configure.outputs.idp-env }} - idp-host: ${{ steps.configure.outputs.idp-host }} - run-tests-args: ${{ steps.configure.outputs.run-tests-args }} - - permissions: - contents: 'read' - id-token: 'write' - pull-requests: 'write' - - steps: - - uses: actions/checkout@main - - - id: configure - env: - INPUT_TARGET_IDP_ENV: ${{ github.event.inputs.target-idp-env }} - INPUT_TARGET_IDP_HOST: ${{ github.event.inputs.target-idp-host }} - INPUT_REASON: ${{ github.event.inputs.reason }} - # INPUT_SLACK_CHANNEL: ${{ github.event.inputs.slack-channel }} - INPUT_PYTEST_ARGS: ${{ github.event.inputs.pytest-args }} - UWCA_CERT: ${{ secrets.UWCA_CERT }} - UWCA_KEY: ${{ secrets.UWCA_KEY }} - run: | - source ./.github/scripts/configure-workflow.sh - configure-workflow - - # - id: set-envs - # run: | - # echo "SLACK_CANVAS_ID=${{ steps.configure.outputs.workflow-id }}" >> $GITHUB_ENV - - - id: 'auth' - name: 'Authenticate to Google Cloud' - uses: 'google-github-actions/auth@v2' - with: - credentials_json: ${{ secrets.TEST_RUNNER_GOOGLE_TOKEN }} - - - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v2' - with: - version: '>= 363.0.0' - - # - name: Initialize slack workflow canvas - # env: - # IDP_ENV: ${{ steps.configure.outputs.idp-env }} - # with: - # command: create-canvas - # # Since your IDE may not pick up on this as JSON and help you, - # # always make sure to run this through a JSON validator. - # json: > - # { - # "channel": "${{ steps.configure.outputs.slack-channel }}", - # "canvasId": "${{ steps.configure.outputs.workflow-id }}", - # "status": "in progress", - # "description": "${{ env.IDP_ENV }} IdP Web Tests", - # "steps": [ - # { - # "description": "Configure workflow", - # "status": "succeeded", - # "stepId": "configure-workflow" - # }, - # { - # "description": "Run UW IdP tests", - # "stepId": "run-tests", - # "status": "in progress" - # }, - # { - # "description": "Upload test artifacts", - # "stepId": "upload-artifacts" - # } - # ] - # } - # channel: ${{ steps.configure.outputs.slack-channel }} - # description: ${{ env.IDP_ENV }} IdP Web Tests - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - # - name: add change information to slack canvas - # with: - # command: add-artifact - # description: ${{ steps.configure.outputs.workflow-snapshot-artifact }} - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - - env: - RUN_TESTS_ARGS: ${{ steps.configure.outputs.run-tests-args }} - IDP_ENV: ${{ steps.configure.outputs.idp-env }} - - run: | - exit_status=0 - if ./scripts/run-tests.sh ${{ steps.args.outputs.extra }} ${{ env.RUN_TESTS_ARGS }} - then - echo "All tests succeeded for ${{ env.IDP_ENV }} succeeded! " - test_status=succeeded - else - exit_status=$? - echo "Tests for ${{ env.IDP_ENV }} failed with status $exit_status" - test_status=failed - fi - - # Only upload artifacts if the test suite actually ran. - echo "test-status=$test_status" >> $GITHUB_OUTPUT - echo "upload-artifacts=true" >> $GITHUB_OUTPUT - exit $exit_status - - name: Run UW ${{ env.IDP_ENV }} IdP Web Tests - id: run-tests - - # - if: always() - # env: - # upload_step_status: > - # ${{ steps.run-tests.outputs.upload-artifacts == 'true' && 'in progress' || 'not started' }} - # test_status: ${{ steps.run-tests.outputs.test-status }} - # with: - # command: update-workflow - # step-id: run-tests, upload-artifacts - # step-status: ${{ env.test_status }}, ${{ env.upload_step_status }} - # workflow-status: ${{ env.test_status == 'succeeded' && 'in progress' || 'failed' }} - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - - if: ${{ always() && steps.run-tests.outputs.upload-artifacts == 'true' }} - id: upload-artifacts - with: - path: web-tests - destination: ${{ secrets.IDENTITY_ARTIFACT_BUCKET }} - name: upload storyboards to identity-artifacts - uses: google-github-actions/upload-cloud-storage@v2 - - # - if: ${{ always() && steps.run-tests.outputs.upload-artifacts == 'true' }} - # with: - # command: update-workflow - # step-id: upload-artifacts - # step-status: > - # ${{ steps.upload-artifacts.conclusion == 'success' && 'succeeded' || 'failed' }} - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - # - if: ${{ always() && steps.run-tests.outputs.upload-artifacts == 'true' }} - # with: - # command: add-artifact - # description: > - # *Storyboards*: ${{ steps.configure.outputs.report-url }} - # name: add storyboard link to slack canvas - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - # - if: always() - # with: - # command: update-workflow - # workflow-status: ${{ steps.run-tests.conclusion == 'success' && 'succeeded' || 'failed' }} - # name: Update workflow status - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - # - if: always() - # with: - # command: remove-step - # step-id: '*' - # step-status: succeeded - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - # - if: always() - # with: - # command: finalize-workflow - # name: clean up slack canvas metadata - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@main - - - if: ${{ always() && github.event_name == 'pull_request' }} - id: update-pull-request - uses: mshick/add-pr-comment@v1 - name: Add storyboard link to pull request - env: - REPORT_URL: ${{ steps.configure.outputs.report-url }} - SHORT_SHA: ${{ steps.configure.outputs.short-sha }} - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - repo-token-user-login: 'github-actions[bot]' # Don't change - allow-repeats: true - message: | - - Test result: ${{ steps.run-tests.outcome }} - - [Storyboards](${{ env.REPORT_URL }}) - **Commit ${{ env.SHORT_SHA }}** diff --git a/.github/workflows/old-scheduled-idp-web-tests.yml b/.github/workflows/old-scheduled-idp-web-tests.yml deleted file mode 100644 index c9f58a8..0000000 --- a/.github/workflows/old-scheduled-idp-web-tests.yml +++ /dev/null @@ -1,156 +0,0 @@ -name: Scheduled UW IdP Test Matrix - -on: - push: - branches: - # You can test this workflow by pushing to this branch - - run-scheduled-idp-web-tests - schedule: - # The cron string must be quoted! - # https://docs.github.com/en/actions/reference/events-that-trigger-workflows#schedule - # Do not change this without also changing stop-test-service-providers.yml - - cron: '0 10 * * *' # 3am PDT, 2am PST - -jobs: - run-web-tests: - strategy: - matrix: - include: - - idp_env: eval - - idp_env: prod - fail-fast: false # Don't cancel prod tests if eval fails and vice versa - runs-on: ubuntu-latest - permissions: - contents: read - id-token: write - actions: write - env: - # SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_BOT_TOKEN }} - ARTIFACT_BUCKET: ${{ secrets.IDENTITY_ARTIFACT_BUCKET }} - steps: - - uses: actions/checkout@v3 - - id: config - run: | - set -x - timestamp=$(date "+%Y.%d.%m-%H.%m.%S") - storyboard_path="idp/schedule/${{ matrix.idp_env }}/${timestamp}" - report_dir="web-tests/${storyboard_path}" - echo timestamp=${timestamp} >> $GITHUB_OUTPUT - echo storyboard_path=${storyboard_path} >> $GITHUB_OUTPUT - echo report_dir=${report_dir} >> $GITHUB_OUTPUT - echo storyboard_link=${storyboard_url}/${report_dir}/index.html >> $GITHUB_OUTPUT - echo workflow_link=${{ env.workflow_link }} >> $GITHUB_OUTPUT - env: - storyboard_url: https://identity-artifact.iamdev.s.uw.edu/ - workflow_link: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - - - - uses: UWIT-IAM/actions/configure-gcloud-docker-gcloud-v101@0.1.17 - with: - gcloud-token: ${{ secrets.TEST_RUNNER_GOOGLE_TOKEN }} - - - # - name: Initialize slack workflow canvas - # env: - # IDP_ENV: ${{ steps.configure.outputs.idp-env }} - # with: - # json: > - # { - # "channel": "#iam-bots", - # "status": "in progress", - # "description": "Scheduled ${{ matrix.idp_env }} IdP Web Tests", - # "steps": [ - # { - # "description": "Run tests", - # "stepId": "run-tests", - # "status": "in progress" - # }, - # { - # "description": "Upload test artifacts", - # "stepId": "upload-artifacts" - # } - # ] - # } - # uses: UWIT-IAM/actions/set-up-slack-notification-canvas@0.1 - # id: slack - - # - if: steps.slack.outputs.canvas-id - # name: Add workflow link to slack notification - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@0.1 - # with: - # command: add-artifact - # description: "<${{ env.workflow_link }} | View Workflow>" - # env: - # workflow_link: ${{ steps.config.outputs.workflow_link }} - - - - name: Run tests - run: ./scripts/run-tests.sh -- --env ${{ matrix.idp_env }} - id: run - - - name: Determine post-test actions - if: always() - run: | - if test -f webdriver-report/index.html - then - mkdir -pv ${{ steps.config.outputs.report_dir }} - cp -r webdriver-report/* ${{ steps.config.outputs.report_dir }} - echo upload_storyboards='true' >> $GITHUB_OUTPUT - fi - id: post-run - - - # - if: always() && steps.slack.outputs.canvas-id - # env: - # run_status: ${{ steps.run.outcome == 'success' && 'succeeded' || 'failed' }} - # upload_status: ${{ steps.post-run.outputs.upload_storyboards == 'true' && 'in progress' || 'failed'}} - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@0.1 - # with: - # step-id: run-tests, upload-artifacts - # step-status: ${{ env.run_status }}, ${{ env.upload_status }} - # command: update-workflow - - - if: always() && steps.post-run.outputs.upload_storyboards == 'true' - name: Upload storyboards to identity-artifact - id: upload-storyboards - uses: google-github-actions/upload-cloud-storage@v2 - with: - path: 'web-tests' - destination: ${{ secrets.IDENTITY_ARTIFACT_BUCKET }} - - # - if: > - # always() - # && steps.post-run.outputs.upload_storyboards =='true' - # && steps.upload-storyboards.outcome == 'success' - # && steps.slack.outputs.canvas-id - # name: Add storyboard link to slack notification - # id: add-storyboard-link-to-slack - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@0.1 - # with: - # command: add-artifact - # description: "<${{ steps.config.outputs.storyboard_link }} | View Storyboards>" - - - if: > - always() - && steps.post-run.outputs.upload_storyboards =='true' - && steps.upload-storyboards.outcome == 'success' - name: Set notices on workflow - env: - storyboard_link: ${{ steps.config.outputs.storyboard_link }} - run: echo "::notice::Storyboards located at ${{ env.storyboard_link }}" - - # - if: > - # always() - # && steps.post-run.outputs.upload_storyboards == 'true' - # uses: UWIT-IAM/actions/update-slack-workflow-canvas@0.1 - # env: - # step_status: ${{ steps.upload-storyboards.outcome == 'success' && 'succeeded' || 'failed' }} - # with: - # command: update-workflow - # step-id: upload-artifacts - # step-status: ${{ env.step_status }} - - # - if: always() && steps.slack.outputs.canvas-id - # uses: UWIT-IAM/actions/finalize-slack-notification-canvas@0.1 - # with: - # workflow-status: ${{ job.status == 'success' && 'succeeded' || 'failed' }} diff --git a/.github/workflows/scheduled-idp-web-tests.yml b/.github/workflows/scheduled-idp-web-tests.yml index 87005f5..1ef2c0f 100644 --- a/.github/workflows/scheduled-idp-web-tests.yml +++ b/.github/workflows/scheduled-idp-web-tests.yml @@ -1,4 +1,4 @@ -name: No Slack - Scheduled UW IdP Test Matrix +name: Scheduled UW IdP Test Matrix on: push: @@ -12,33 +12,19 @@ on: - cron: '0 10 * * *' # 3am PDT, 2am PST workflow_dispatch: inputs: - target-idp-env: - description: > - NOTE: Running this workflows manually via this form will allow you to test the yaml of this workflow file and it will run the same tests as found in "No Slack - Run UW IdP Web Tests." - For "normal" on demand running of the idp tests, the "No Slack - Run UW IdP Web Tests" can be used. - - target-idp-env. Acceptable values are `eval`, `prod`. The idp environment - you want to test against. - required: true - default: eval - - target-idp-host: - description: > - target-idp-host. Optional. If provided, will add an /etc/hosts entry - targeting this host. - required: false - reason: description: > - reason. The reason for running this test suite; can be helpful to - provide context and distinguish different runs. + The reason for running this test suite; can be helpful to + provide context and distinguish different runs. **Note, this form only really exists to a dev can test the workflow.** The standard way of running test on demand is with the "Run UW IdP Web Tests" workflow. required: false - pytest-args: - description: > - pytest-args. Any args you want to send to pytest. You do not ever need to - supply `log_cli` arguments. - required: false +env: + ############################################### + # Do not edit the env values below this line. # + # Other defaults are set in .github/scripts/configure-workflow.sh + TEAMS_INTEGRATIONS_DAILY_WEB_TESTS: ${{ secrets.TEAMS_INTEGRATIONS_DAILY_WEB_TESTS }} + ARTIFACT_BUCKET: ${{ secrets.IDENTITY_ARTIFACT_BUCKET }} + ############################################### jobs: run-web-tests: @@ -68,19 +54,81 @@ jobs: echo report_dir=${report_dir} >> $GITHUB_OUTPUT echo storyboard_link=${storyboard_url}/${report_dir}/index.html >> $GITHUB_OUTPUT echo workflow_link=${{ env.workflow_link }} >> $GITHUB_OUTPUT + env: storyboard_url: https://identity-artifact.iamdev.s.uw.edu/ workflow_link: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - - uses: UWIT-IAM/actions/configure-gcloud-docker-gcloud-v101@0.1.17 with: gcloud-token: ${{ secrets.TEST_RUNNER_GOOGLE_TOKEN }} + - id: configure + env: + INPUT_REASON: ${{ github.event.inputs.reason }} + run: | + source ./.github/scripts/configure-workflow.sh + configure-workflow + + - name: Notify Teams of Test Run Start + env: + IDP_ENV: ${{ matrix.idp_env }} + INPUT_REASON: ${{ steps.configure.outputs.input-reason }} + run: | + curl -H "Content-Type: application/json" \ + -d '{ + "type": "message", + "attachments": [ + { + "contentType": "application/vnd.microsoft.card.adaptive", + "content": { + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.4", + "body": [ + { + "type": "TextBlock", + "size": "Large", + "weight": "Bolder", + "text": "Scheduled UW IdP Test Matrix Run" + }, + { + "type": "TextBlock", + "text": "Starting - IDP Tests ⏳", + "wrap": true + }, + { + "type": "FactSet", + "facts": [ + {"title": "IdP Web Tests running on ", "value": "'${{ env.IDP_ENV }}'"}, + {"title": "Reason for Test Run", "value": "${{ env.INPUT_REASON }}"} + ] + } + ] + } + } + ] + }' \ + "${{ env.TEAMS_INTEGRATIONS_DAILY_WEB_TESTS }}" + - name: Run tests - run: ./scripts/run-tests.sh -- --env ${{ matrix.idp_env }} - id: run + id: run-tests + run: | + exit_status=0 + if ./scripts/run-tests.sh -- --env ${{ matrix.idp_env }} + then + echo "All tests succeeded for ${{ matrix.idp_env }}! " + test_status=succeeded + else + exit_status=$? + echo "Tests for ${{ matrix.idp_env }} failed with status $exit_status" + test_status=failed + fi + + echo "test-status=$test_status" >> $GITHUB_OUTPUT + echo "upload-artifacts=true" >> $GITHUB_OUTPUT + exit $exit_status - name: Determine post-test actions if: always() @@ -105,9 +153,64 @@ jobs: - if: > always() - && steps.post-run.outputs.upload_storyboards =='true' + && steps.post-run.outputs.upload_storyboards == 'true' && steps.upload-storyboards.outcome == 'success' name: Set notices on workflow env: storyboard_link: ${{ steps.config.outputs.storyboard_link }} run: echo "::notice::Storyboards located at ${{ env.storyboard_link }}" + + - name: Notify Teams of Test Run Completion + env: + TEST_STATUS: ${{ steps.run-tests.outputs.test-status }} + REPORT_URL: ${{ steps.config.outputs.storyboard_link }} + INPUT_REASON: ${{ steps.configure.outputs.input-reason }} + IDP_ENV: ${{ matrix.idp_env }} + if: always() + run: | + # Set the message body dynamically based on TEST_STATUS + echo "TEST_STATUS=${{ env.TEST_STATUS }}" + if [ "$TEST_STATUS" = "succeeded" ]; then + test_result="Test run for IDP passed successfully ✅" + else + test_result="Test run for IDP failed ❌" + fi + + # Notify Teams with the status of the test run + curl -H "Content-Type: application/json" \ + -d '{ + "type": "message", + "attachments": [ + { + "contentType": "application/vnd.microsoft.card.adaptive", + "content": { + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "type": "AdaptiveCard", + "version": "1.4", + "body": [ + { + "type": "TextBlock", + "size": "Large", + "weight": "Bolder", + "text": "Completed - Scheduled UW IdP Test Matrix Run" + }, + { + "type": "TextBlock", + "text": "'"$test_result"'", + "wrap": true + }, + { + "type": "FactSet", + "facts": [ + {"title": "IdP Web Tests ran on ", "value": "'${{ env.IDP_ENV }}'"}, + {"title": "Reason for Test Run", "value": "${{ env.INPUT_REASON }}"}, + {"title": "Storyboards:", "value": "['"$REPORT_URL"']('"$REPORT_URL"')"} + ] + } + ] + } + } + ] + }' \ + "${{ secrets.TEAMS_INTEGRATIONS_DAILY_WEB_TESTS }}" + diff --git a/docker-compose.yml b/docker-compose.yml index cbed1ef..6386017 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,6 +34,7 @@ services: - ${CREDENTIAL_MOUNT_POINT}:/secrets:ro - ${REPORT_MOUNT_POINT}:/tmp/webdriver-report command: pytest ${PYTEST_ARGS} --selenium-server selenium:4444 + # command: pytest ${PYTEST_ARGS} --selenium-server selenium:4444 tests/test_2fa_duo.py::test_remember_me_cookie #If you want to run one more specific tests, use this command instead of the above. # command: echo "The test would start here" #If you don't want the tests to run, and test other things like notifications, use this command instead of the above. selenium: diff --git a/docs/github-actions.md b/docs/github-actions.md index 558e4f1..f5efdb7 100644 --- a/docs/github-actions.md +++ b/docs/github-actions.md @@ -95,6 +95,10 @@ Remove the line `command: pytest ${PYTEST_ARGS} --selenium-server selenium:4444` You can replace to with `command: echo "The test would start here"`. That will not run the tests and instead, it will put an entry in the logs/terminal that says "The test would start here". You'll still see the test run and end notifications but the tests won't run. +You can also run a specific test with this command: +`command: pytest ${PYTEST_ARGS} --selenium-server selenium:4444 path/to/testfile` or +`command: pytest ${PYTEST_ARGS} --selenium-server selenium:4444 path/to/testfile::<test_name>` +`command: pytest ${PYTEST_ARGS} --selenium-server selenium:4444 tests/test_2fa_duo.py::test_remember_me_cookie` [test workflow]: https://github.com/UWIT-IAM/uw-idp-web-tests/actions/workflows/automated-idp-web-tests.yml [Github Actions UI]: https://github.com/uwit-iam/uw-idp-web-tests/actions