From f535a526aa0de2a9f286475afcf9327a8cb65bc3 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Tue, 22 Aug 2023 00:02:22 +0200 Subject: [PATCH 01/20] PMM-7 added missed refactoring --- playwright-tests/CONTRIBUTING.md | 32 ++++++++----------- playwright-tests/pages/common.page.ts | 2 +- .../pages/dashboards/base-dashboard.page.ts | 32 +++++++------------ .../nodes-overview-dashboard-panels.ts | 1 + .../page-components/dashboards/pmm-menu.ts | 18 ++--------- .../pages/page-components/toast.ts | 24 ++++---------- .../tests/inventory/pages/add-service.page.ts | 4 --- .../tests/portal/connectPmm.spec.ts | 10 ++---- 8 files changed, 39 insertions(+), 84 deletions(-) diff --git a/playwright-tests/CONTRIBUTING.md b/playwright-tests/CONTRIBUTING.md index 2f4f9d976..9ee42a27f 100644 --- a/playwright-tests/CONTRIBUTING.md +++ b/playwright-tests/CONTRIBUTING.md @@ -10,15 +10,15 @@ * **Acronyms** Whenever an acronym is included as part of a type name or method name, keep the first -letter of the acronym uppercase and use lowercase for the rest of the acronym. Otherwise, -it becomes potentially very difficult to read or reason about the element without -reading documentation (if documentation even exists). + letter of the acronym uppercase and use lowercase for the rest of the acronym. Otherwise, + it becomes potentially very difficult to read or reason about the element without + reading documentation (if documentation even exists).       Consider for example a use case needing to support an HTTP URL. Calling the method -`getHTTPURL()` is absolutely horrible in terms of usability; whereas, `getHttpUrl()` is -great in terms of usability. The same applies for types `HTTPURLProvider` vs -`HttpUrlProvider`. -| + `getHTTPURL()` is absolutely horrible in terms of usability; whereas, `getHttpUrl()` is + great in terms of usability. The same applies for types `HTTPURLProvider` vs + `HttpUrlProvider`. + | Whenever an acronym is included as part of a field name or parameter name: * If the acronym comes at the start of the field or parameter name, use lowercase for the entire acronym, ex: `url;` * Otherwise, keep the first letter of the acronym uppercase and use lowercase for the rest of the acronym, ex: `baseUrl;` @@ -40,33 +40,29 @@ great in terms of usability. The same applies for types `HTTPURLProvider` vs ### Locators * **Locators outside of a test.** - This is a bad practice to use hard coded locators inside a test. All locators should ‘live’ inside a [Page Object](https://codecept.io/pageobjects/) + This is a bad practice to use hard coded locators inside a test. All locators should ‘live’ inside a Page Object * **Try to use stable locators.** Ideally there should exist a dedicated attribute for each interactive element (“data-qa” attribute). But id, classname, text also used frequently. (try to use small xpath) -* **Locators preference: locate() > CSS > Xpath** - Try to use `locate()` builder as a first priority, and only then CSS. Use XPath as a last stand. +* **Locators preference: .getByXXX() > CSS > Xpath** + Try to use `.getByXXX()` method as a first priority, and only then CSS. Use XPath as a last stand. ### Assertions -* **coming soon...** +* **coming soon...** ### Test Files -* **One feature per spec File.** +* **One feature per spec File.** -### Scenario -* **Scenario title should contain Test Case ID.** - In order to make searching for a test much easier we could add the original Test Case ID from TMT. - -* **Scenario title template.** - {TEST_CASE_ID} Title {annotation} +* **Test title template.** + {TEST_CASE_ID} Title {annotation} ### Annotations diff --git a/playwright-tests/pages/common.page.ts b/playwright-tests/pages/common.page.ts index 3df949bca..944e8d7f0 100644 --- a/playwright-tests/pages/common.page.ts +++ b/playwright-tests/pages/common.page.ts @@ -3,7 +3,7 @@ import { LeftNavigationMenu } from '@components/left-navigation-menu'; import { Toast } from '@components/toast'; import OptionsMenu from '@components/options-menu'; import { expect } from '@helpers/test-helper'; -import grafanaHelper from "@helpers/grafana-helper"; +import grafanaHelper from '@helpers/grafana-helper'; export class CommonPage { toast = new Toast(this.page); diff --git a/playwright-tests/pages/dashboards/base-dashboard.page.ts b/playwright-tests/pages/dashboards/base-dashboard.page.ts index 9658e7988..a3814cc34 100644 --- a/playwright-tests/pages/dashboards/base-dashboard.page.ts +++ b/playwright-tests/pages/dashboards/base-dashboard.page.ts @@ -18,9 +18,7 @@ export class BaseDashboard extends CommonPage { serviceName: this.page.locator('//button[@id="var-service_name"]'), }; - labels = { - create: 'Create', - }; + labels = { create: 'Create' }; openAllPanels = async () => { await this.elements.collapsedPanel.waitFor({ state: 'visible' }); @@ -45,15 +43,12 @@ export class BaseDashboard extends CommonPage { waitForPanelToHaveData = async (panelHeader: string, panelId: number, timeout: Duration = Duration.OneMinute) => { await this.openAllPanels(); await this.elements.getPanelByName(panelHeader, panelId).scrollIntoViewIfNeeded(); - await expect(this.elements.getPanelByName(panelHeader, panelId)).not.toContainText('N/A', { - ignoreCase: true, timeout, - }); - await expect(this.elements.getPanelByName(panelHeader, panelId)).not.toContainText('No data', { - ignoreCase: true, timeout, - }); - await expect(this.elements.getPanelByName(panelHeader, panelId)).not.toContainText('Insufficient access permissions', { - ignoreCase: true, timeout, - }); + await expect(this.elements.getPanelByName(panelHeader, panelId)) + .not.toContainText('N/A', { ignoreCase: true, timeout }); + await expect(this.elements.getPanelByName(panelHeader, panelId)) + .not.toContainText('No data', { ignoreCase: true, timeout }); + await expect(this.elements.getPanelByName(panelHeader, panelId)) + .not.toContainText('Insufficient access permissions', { ignoreCase: true, timeout }); await this.page.keyboard.press('PageDown'); }; @@ -65,15 +60,10 @@ export class BaseDashboard extends CommonPage { await this.elements.panelContent.nth(index).scrollIntoViewIfNeeded(); try { - await expect(this.elements.panelContent.nth(index)).not.toContainText('N/A', { - ignoreCase: true, - }); - await expect(this.elements.panelContent.nth(index)).not.toContainText('No data', { - ignoreCase: true, - }); - await expect(this.elements.panelContent.nth(index)).not.toContainText('Insufficient access permissions', { - ignoreCase: true, - }); + await expect(this.elements.panelContent.nth(index)).not.toContainText('N/A', { ignoreCase: true }); + await expect(this.elements.panelContent.nth(index)).not.toContainText('No data', { ignoreCase: true }); + await expect(this.elements.panelContent.nth(index)) + .not.toContainText('Insufficient access permissions', { ignoreCase: true }); } catch (err) { noDataElements++; if (noDataElements > panelsWithoutData) { diff --git a/playwright-tests/pages/page-components/dashboards/nodes-overview-dashboard-panels.ts b/playwright-tests/pages/page-components/dashboards/nodes-overview-dashboard-panels.ts index fcc86ec59..d982e9d76 100644 --- a/playwright-tests/pages/page-components/dashboards/nodes-overview-dashboard-panels.ts +++ b/playwright-tests/pages/page-components/dashboards/nodes-overview-dashboard-panels.ts @@ -1,3 +1,4 @@ +/* eslint-disable object-curly-newline */ export const NodesOverviewDashboardPanels = { // Overview nodes: { panelId: 326, name: 'Nodes', error: '1' }, diff --git a/playwright-tests/pages/page-components/dashboards/pmm-menu.ts b/playwright-tests/pages/page-components/dashboards/pmm-menu.ts index 2a98bdedb..d812424e0 100644 --- a/playwright-tests/pages/page-components/dashboards/pmm-menu.ts +++ b/playwright-tests/pages/page-components/dashboards/pmm-menu.ts @@ -3,26 +3,14 @@ import { Page } from '@playwright/test'; export default class PmmMenu { constructor(readonly page: Page) { } - elements: any = { - container: this.page.getByRole('menu'), - }; - - fields = {}; - - labels = {}; - + elements: any = { container: this.page.getByRole('menu') }; buttons = { menu: this.page.locator('//span[text()="PMM"]//ancestor::button'), option: (option: string) => this.page.locator(`//a[contains(@aria-label, "${option}")]`), }; - messages: any = {}; - - links = {}; - selectOption = async (option: string) => { - await this.buttons.menu.click() + await this.buttons.menu.click(); await this.buttons.option(option).click(); - } - + }; } diff --git a/playwright-tests/pages/page-components/toast.ts b/playwright-tests/pages/page-components/toast.ts index c7de81a5e..74bb3bacd 100644 --- a/playwright-tests/pages/page-components/toast.ts +++ b/playwright-tests/pages/page-components/toast.ts @@ -29,16 +29,10 @@ export class Toast { ) => { const selectedToast: Locator = this.selectToast(options?.variant); - await selectedToast.waitFor({ - state: 'visible', timeout: options?.timeout || 30000, - }); - await expect(selectedToast).toHaveText(message, { - timeout: options?.assertionTimeout || config.expect?.timeout, - }); + await selectedToast.waitFor({ state: 'visible', timeout: options?.timeout || 30000 }); + await expect(selectedToast).toHaveText(message, { timeout: options?.assertionTimeout || config.expect?.timeout }); await this.closeButton(selectedToast).click(); - await selectedToast.waitFor({ - state: 'detached', - }); + await selectedToast.waitFor({ state: 'detached' }); }; checkToastMessageContains = async ( @@ -47,15 +41,9 @@ export class Toast { ) => { const selectedToast: Locator = this.selectToast(options?.variant); - await selectedToast.waitFor({ - state: 'visible', timeout: options?.timeout, - }); - await expect(selectedToast).toContainText(message, { - timeout: options?.assertionTimeout || config.expect?.timeout, - }); + await selectedToast.waitFor({ state: 'visible', timeout: options?.timeout }); + await expect(selectedToast).toContainText(message, { timeout: options?.assertionTimeout || config.expect?.timeout }); await this.closeButton(selectedToast).click(); - await selectedToast.waitFor({ - state: 'detached', - }); + await selectedToast.waitFor({ state: 'detached' }); }; } diff --git a/playwright-tests/tests/inventory/pages/add-service.page.ts b/playwright-tests/tests/inventory/pages/add-service.page.ts index 6b718f400..cc1b9db34 100644 --- a/playwright-tests/tests/inventory/pages/add-service.page.ts +++ b/playwright-tests/tests/inventory/pages/add-service.page.ts @@ -14,10 +14,6 @@ export class AddServicePage extends CommonPage { haProxy: this.page.getByTestId('haproxy-instance'), }; - messages: any = { - ...this.messages, - }; - verifyAllButtonsVisible = async () => { await expect(this.buttons.amazonRds).toBeVisible(); await expect(this.buttons.postgreSql).toBeVisible(); diff --git a/playwright-tests/tests/portal/connectPmm.spec.ts b/playwright-tests/tests/portal/connectPmm.spec.ts index 8bc400c08..117b803fe 100644 --- a/playwright-tests/tests/portal/connectPmm.spec.ts +++ b/playwright-tests/tests/portal/connectPmm.spec.ts @@ -30,7 +30,7 @@ test.describe('Spec file for connecting PMM to the portal', async () => { await perconaPlatformPage.open(); }); - await test.step('2. Verify all required element are displayed.', async () => { + await test.step('2. Verify all required elements are displayed.', async () => { await expect(perconaPlatformPage.elements.pmmServerIdHeader) .toHaveText(perconaPlatformPage.labels.pmmServerId, { ignoreCase: true }); await expect(perconaPlatformPage.elements.pmmServerNameHeader).toHaveText(perconaPlatformPage.labels.pmmServerName); @@ -103,9 +103,7 @@ test.describe('Spec file for connecting PMM to the portal', async () => { test( 'PMM-T1098 Verify All org users can login in connected PMM server' + ' @not-ui-pipeline @portal @pre-pmm-portal-upgrade @post-pmm-portal-upgrade', - async ({ - loginPage, homeDashboardPage, baseURL, context, - }) => { + async ({ loginPage, homeDashboardPage, baseURL, context }) => { test.skip(pmmVersion < 27, 'This test is for PMM version 2.27.0 and higher'); await test.step('1. Login as admin user that created the org.', async () => { @@ -120,9 +118,7 @@ test.describe('Spec file for connecting PMM to the portal', async () => { await test.step('1. Login as admin user that was invited to the org.', async () => { await loginPage.oktaLogin(secondAdmin.email, secondAdmin.password); - await homeDashboardPage.pmmUpgrade.containers.upgradeContainer.waitFor({ - state: 'visible', timeout: Duration.OneMinute, - }); + await homeDashboardPage.pmmUpgrade.containers.upgradeContainer.waitFor({ state: 'visible', timeout: Duration.OneMinute }); await expect(loginPage.page).toHaveURL(`${baseURL}/${loginPage.landingUrl}`); await context.clearCookies(); await loginPage.page.reload(); From 718543fad0786a6f0592ffca9f9f1aede52d065f Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 10:40:57 +0200 Subject: [PATCH 02/20] PMM-7 updated ui pipeline --- .github/workflows/pmm-ui-tests-matrix.yml | 60 ++-- .github/workflows/pmm-ui-tests.yml | 206 ------------- .github/workflows/portal-ui-tests.yml | 167 ---------- .github/workflows/ui-tests-pipeline.yml | 291 ++++++++++++++++++ playwright-tests/helpers/constants.ts | 2 +- playwright-tests/playwright.config.ts | 22 +- .../tests/portal/testUsers.setup.ts | 8 +- pr.codecept.js | 6 +- 8 files changed, 338 insertions(+), 424 deletions(-) delete mode 100644 .github/workflows/pmm-ui-tests.yml delete mode 100644 .github/workflows/portal-ui-tests.yml create mode 100644 .github/workflows/ui-tests-pipeline.yml diff --git a/.github/workflows/pmm-ui-tests-matrix.yml b/.github/workflows/pmm-ui-tests-matrix.yml index 6cc460fc4..4bef6091d 100644 --- a/.github/workflows/pmm-ui-tests-matrix.yml +++ b/.github/workflows/pmm-ui-tests-matrix.yml @@ -1,4 +1,4 @@ -name: PMM2 UI Tests-Matrix +name: PMM E2E Tests(Playwright) on: schedule: @@ -9,52 +9,54 @@ on: description: 'pmm-ui-tests repository branch' default: 'main' required: true - pmm_server_version: - description: 'PMM Server docker image' - default: 'perconalab/pmm-server:dev-latest' - required: true - pmm_client_version: - description: 'PMM Client version to test (dev-latest|pmm2-latest|pmm2-rc|x.xx.x)' - default: 'dev-latest' - required: true pmm_qa_branch: description: 'pmm-qa repository branch(for setup)' default: 'main' required: true - + pmm_server_version: + description: 'PMM Server version to upgrade (latest|dev-latest|x.xx.x|x.xx.x-rc)' + default: 'latest' + required: true + pmm_client_version: + description: 'PMM Client version to upgrade from (dev-latest|pmm2-latest|pmm2-rc|x.xx.x)' + default: 'pmm2-latest' + required: true jobs: - rbac: - name: RBAC - uses: ./.github/workflows/pmm-ui-tests.yml + inventory: + name: Inventory + uses: ./.github/workflows/ui-tests-pipeline.yml secrets: inherit with: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} - pmm_test_flag: '@rbac' - pmm_server_version: ${{ github.event.inputs.pmm_server_version || 'perconalab/pmm-server:dev-latest' }} - pmm_client_version: ${{ github.event.inputs.pmm_client_version || 'dev-latest' }} - pmm_clients: '--addclient=ps,1 --addclient=pdpgsql,1' pmm_qa_branch: ${{ github.event.inputs.pmm_qa_branch || 'main' }} + pmm_server_version: ${{ inputs.pmm_server_version || 'dev-latest' }} + client_version: ${{ .pmm_client_version || 'dev-latest' }} + tags_for_playwright: '@inventory' + client_flags: '--addclient=modb,1 --addclient=ps,1 --addclient=pdpgsql,1' + version_string: ${{ inputs.pmm_server_version || 'dev-latest' }} portal: name: Portal - uses: ./.github/workflows/pmm-ui-tests.yml + uses: ./.github/workflows/ui-tests-pipeline.yml secrets: inherit with: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} - pmm_test_flag: '@portal' - pmm_server_version: ${{ github.event.inputs.pmm_server_version || 'perconalab/pmm-server:dev-latest' }} - pmm_client_version: ${{ github.event.inputs.pmm_client_version || 'dev-latest' }} - pmm_clients: '' pmm_qa_branch: ${{ github.event.inputs.pmm_qa_branch || 'main' }} + pmm_server_version: ${{ inputs.pmm_server_version || 'dev-latest' }} + client_version: ${{ .pmm_client_version || 'dev-latest' }} + tags_for_playwright: '@portal' + client_flags: '' + version_string: ${{ inputs.pmm_server_version || 'dev-latest' }} - inventory: - name: Inventory - uses: ./.github/workflows/pmm-ui-tests.yml + rbac: + name: RBAC + uses: ./.github/workflows/ui-tests-pipeline.yml secrets: inherit with: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} - pmm_test_flag: '@inventory' - pmm_server_version: ${{ github.event.inputs.pmm_server_version || 'perconalab/pmm-server:dev-latest' }} - pmm_client_version: ${{ github.event.inputs.pmm_client_version || 'dev-latest' }} - pmm_clients: '--addclient=modb,1 --addclient=ps,1 --addclient=pdpgsql,1' pmm_qa_branch: ${{ github.event.inputs.pmm_qa_branch || 'main' }} + pmm_server_version: ${{ inputs.pmm_server_version || 'dev-latest' }} + client_version: ${{ .pmm_client_version || 'dev-latest' }} + tags_for_playwright: '@rbac' + client_flags: '--addclient=ps,1 --addclient=pdpgsql,1' + version_string: ${{ inputs.pmm_server_version || 'dev-latest' }} diff --git a/.github/workflows/pmm-ui-tests.yml b/.github/workflows/pmm-ui-tests.yml deleted file mode 100644 index 45f4bcf44..000000000 --- a/.github/workflows/pmm-ui-tests.yml +++ /dev/null @@ -1,206 +0,0 @@ ---- -name: pmm-ui-tests - -on: - workflow_call: - inputs: - pmm_ui_tests_branch: - description: 'Target branch for pmm-ui-tests repository' - type: string - default: 'main' - required: true - pmm_test_flag: - description: 'Flag to run only specific portion of the tests.' - type: string - required: false - pmm_server_version: - description: 'Version of the pmm server used for testing' - type: string - default: 'dev-latest' - required: true - pmm_client_version: - description: 'Version of the pmm client used for testing' - type: string - default: 'dev-latest' - required: true - pmm_clients: - description: 'Clients for pmm-server' - type: string - default: '--addclient=ps,1' - required: true - pmm_qa_branch: - description: 'Branch for the pmm-qa repository.' - type: string - default: 'main' - required: true - - workflow_dispatch: - inputs: - pmm_ui_tests_branch: - description: 'Target branch for pmm-ui-tests repository' - type: string - default: 'main' - required: true - pmm_test_flag: - description: 'Flag to run only specific portion of the tests.' - type: string - required: false - pmm_server_version: - description: 'Version of the pmm server used for testing' - type: string - default: 'dev-latest' - required: true - pmm_client_version: - description: 'Version of the pmm client used for testing' - type: string - default: 'dev-latest' - required: true - pmm_clients: - description: 'Clients for pmm-server' - type: string - default: '--addclient=ps,1' - required: true - pmm_qa_branch: - description: 'Branch for the pmm-qa repository.' - type: string - default: 'main' - required: true - -jobs: - tests: - name: Tests - runs-on: ubuntu-latest - timeout-minutes: 60 - env: - SHA: ${{ inputs.sha || 'null' }} - PMM_BASE_URL: https://127.0.0.1 - ADMIN_PASSWORD: admin - - UI_TESTS_BRANCH: ${{ inputs.pmm_ui_tests_branch }} - PMM_CLIENTS: ${{ inputs.pmm_clients }} - PMM_TEST_FLAG: ${{ inputs.pmm_test_flag }} - - PMM_SERVER_VERSION: ${{ inputs.pmm_server_version }} - PMM_CLIENT_VERSION: ${{ inputs.pmm_client_version }} - PMM_QA_BRANCH: ${{ inputs.pmm_qa_branch }} - - OKTA_TOKEN: ${{ secrets.OKTA_TOKEN }} - OAUTH_ISSUER_URL: 'https://id-dev.percona.com/oauth2/aus15pi5rjdtfrcH51d7' - OAUTH_CLIENT_ID: ${{ secrets.OKTA_OAUTH_CLIENT_ID }} - OAUTH_CLIENT_SECRET: ${{ secrets.OKTA_OAUTH_CLIENT_SECRET }} - OAUTH_PMM_CLIENT_ID: ${{ secrets.OKTA_OAUTH_PMM_CLIENT_ID }} - OAUTH_PMM_CLIENT_SECRET: ${{ secrets.OKTA_OAUTH_PMM_CLIENT_SECRET }} - OAUTH_DEV_HOST: ${{ secrets.OAUTH_DEV_HOST }} - OAUTH_SCOPES: percona - - # Variables for E2E tests - MAILOSAUR_API_KEY: ${{ secrets.MAILOSAUR_API_KEY }} - MAILOSAUR_UI_TESTS_SERVER_ID: ${{ secrets.MAILOSAUR_UI_TESTS_SERVER_ID }} - MAILOSAUR_API_TESTS_SERVER_ID: ${{ secrets.MAILOSAUR_API_TESTS_SERVER_ID }} - - SERVICENOW_LOGIN: percona_platform - SERVICENOW_PASSWORD: ${{ secrets.SERVICENOW_PASSWORD }} - SERVICENOW_DEV_URL: 'https://perconadev.service-now.com/api/x_pellc_percona_pl/platform/settest' - - steps: - - name: PMM server version ${{ inputs.pmm_server_version }} and UI tests for flag "${{ inputs.pmm_test_flag }}" and pmm-ui-tests branch ${{ inputs.pmm_ui_tests_branch }} - if: ${{ env.SHA != 'null' }} - uses: percona/gh-action-Sibz-github-status-action@v1 - continue-on-error: true - with: - authToken: ${{ secrets.GITHUB_TOKEN }} - context: "${{ env.PMM_TEST_FLAG }} UI tests" - description: "Test execution ${{ job.status }}" - state: "pending" - repository: ${{ github.repository }} - target_url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - sha: ${{ env.SHA }} - - - name: 'Checkout UI tests: "${{ inputs.pmm_ui_tests_branch }}"' - uses: actions/checkout@v3 - with: - ref: ${{ inputs.pmm_ui_tests_branch }} - repository: percona/pmm-ui-tests - path: ./pmm-ui-tests - - - name: 'Install playwright' - working-directory: ./pmm-ui-tests/playwright-tests - run: | - npm install - npx playwright install - - - name: 'Checkout pmm-qa: "${{ inputs.pmm_qa_branch }}"' - uses: actions/checkout@v3 - with: - # token: ${{ secrets.ROBOT_TOKEN }} - repository: percona/pmm-qa - ref: ${{ inputs.pmm_qa_branch }} - path: ./pmm-qa - - - name: 'Setup : "${{ inputs.pmm_server_version }}"' - working-directory: pmm-qa/pmm-integration - run: | - npm install - sudo npx ts-node ./integration-setup.ts --ci --setup-docker-pmm-server --rbac --pmm-server-docker-tag=${{ env.PMM_SERVER_VERSION }} --pmm-client-version=${{ env.PMM_CLIENT_VERSION }} - timeout 100 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost/ping)" != "200" ]]; do sleep 5; done' || false - - - name: 'Setup ' - run: | - sudo bash ./pmm-qa/pmm-tests/pmm2-client-setup.sh --pmm_server_ip 127.0.0.1 --client_version ${{ env.PMM_CLIENT_VERSION }} --admin_password admin --use_metrics_mode no - shell: bash - - - name: Setup Databases for the PMM-Server - working-directory: pmm-qa/pmm-integration - run: | - sudo npx ts-node ./integration-setup.ts --ci \ - ${{ env.PMM_CLIENTS }} - sleep 30 - sudo pmm-admin list - shell: bash - - - name: Execute UI tests - if: ${{ inputs.pmm_test_flag == 'null' }} - id: ui-tests-all - working-directory: pmm-ui-tests - run: | - npx playwright test --config="playwright-tests/playwright.config.ts" --quiet -# env: -# NODE_TLS_REJECT_UNAUTHORIZED: 0 - - - name: 'Run UI tests: ${{ env.PMM_TEST_FLAG }}' - if: ${{ inputs.pmm_test_flag != 'null' }} - id: ui-tests-flagged - working-directory: pmm-ui-tests - run: | - npx playwright test --config="playwright-tests/playwright.config.ts" --grep="${{ env.PMM_TEST_FLAG }}" --quiet -# env: -# NODE_TLS_REJECT_UNAUTHORIZED: 0 - - - name: 'Create report name' - if: failure() - run: | - # TODO: add job id for matrix call - job_tag=$(echo "${{ inputs.pmm_test_flag }}" | sed -e "s/-pre-upgrade//" -e "s/@//") - report_name="$job_tag"-report - echo $report_name - echo "REPORT_NAME=$report_name" >> $GITHUB_ENV - - - name: Generate and Attach the report - if: failure() - uses: actions/upload-artifact@v3 - with: - name: ${{ env.REPORT_NAME }} - path: ./pmm-ui-tests/playwright-tests/playwright-report - - - name: Create status check - uses: percona/gh-action-Sibz-github-status-action@v1 - if: ${{ env.SHA != 'null' && always() }} - continue-on-error: true - with: - authToken: ${{ secrets.GITHUB_TOKEN }} - context: "${{ env.PMM_TEST_FLAG }} UI tests" - description: "Test execution ${{ job.status }}" - state: ${{ job.status }} - repository: ${{ github.repository }} - target_url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - sha: ${{ env.SHA }} diff --git a/.github/workflows/portal-ui-tests.yml b/.github/workflows/portal-ui-tests.yml deleted file mode 100644 index bff686b5c..000000000 --- a/.github/workflows/portal-ui-tests.yml +++ /dev/null @@ -1,167 +0,0 @@ ---- -name: portal-ui-tests - -on: - workflow_call: - inputs: - pmm_ui_tests_branch: - description: 'Target branch for pmm-ui-tests repository' - type: string - default: 'main' - pmm_test_flag: - description: 'Flag to run only specific portion of the tests.' - type: string - pmm_server_version: - description: 'Version of the pmm server used for testing' - type: string - default: 'dev-latest' - required: true - pmm_client_version: - description: 'Version of the pmm client used for testing' - type: string - default: 'dev-latest' - required: true - pmm_clients: - description: 'Clients for pmm-server' - type: string - default: '--addclient=ps,1' - pmm_qa_branch: - description: 'Branch for the pmm-qa repository.' - type: string - default: 'main' - version_string_from: - description: 'start version string' - type: string - - push: - branches: - - "PMM-7-fix-portal-pipeline" - -jobs: - tests: - name: ${{ inputs.version_string_from || inputs.pmm_server_version || 'dev-latest' }} - runs-on: ubuntu-latest - timeout-minutes: 60 - env: - SHA: ${{ inputs.sha || 'null' }} - PMM_BASE_URL: https://127.0.0.1 - ADMIN_PASSWORD: admin - - UI_TESTS_BRANCH: "PMM-7-fix-portal-pipeline" - PMM_CLIENTS: ${{ inputs.pmm_clients || '' }} - PMM_TEST_FLAG: ${{ inputs.pmm_test_flag || '@portal' }} - - PMM_SERVER_VERSION: ${{ inputs.pmm_server_version || 'dev-latest' }} - PMM_CLIENT_VERSION: ${{ inputs.pmm_client_version || 'dev-latest' }} - PMM_QA_BRANCH: ${{ inputs.pmm_qa_branch || 'main' }} - - OKTA_TOKEN: ${{ secrets.OKTA_TOKEN }} - OAUTH_ISSUER_URL: 'https://id-dev.percona.com/oauth2/aus15pi5rjdtfrcH51d7' - OAUTH_CLIENT_ID: ${{ secrets.OKTA_OAUTH_CLIENT_ID }} - OAUTH_CLIENT_SECRET: ${{ secrets.OKTA_OAUTH_CLIENT_SECRET }} - OAUTH_PMM_CLIENT_ID: ${{ secrets.OKTA_OAUTH_PMM_CLIENT_ID }} - OAUTH_PMM_CLIENT_SECRET: ${{ secrets.OKTA_OAUTH_PMM_CLIENT_SECRET }} - OAUTH_DEV_HOST: ${{ secrets.OAUTH_DEV_HOST }} - OAUTH_SCOPES: percona - - # Variables for E2E tests - MAILOSAUR_API_KEY: ${{ secrets.MAILOSAUR_API_KEY }} - MAILOSAUR_UI_TESTS_SERVER_ID: ${{ secrets.MAILOSAUR_UI_TESTS_SERVER_ID }} - MAILOSAUR_API_TESTS_SERVER_ID: ${{ secrets.MAILOSAUR_API_TESTS_SERVER_ID }} - - SERVICENOW_LOGIN: percona_platform - SERVICENOW_PASSWORD: ${{ secrets.SERVICENOW_PASSWORD }} - SERVICENOW_DEV_URL: 'https://perconadev.service-now.com/api/x_pellc_percona_pl/platform/settest' - - steps: - - name: PMM server version ${{ env.PMM_SERVER_VERSION }} and UI tests for flag "${{ env.PMM_TEST_FLAG }}" and pmm-ui-tests branch ${{ env.UI_TESTS_BRANCH }} - if: ${{ env.SHA != 'null' }} - uses: percona/gh-action-Sibz-github-status-action@v1 - continue-on-error: true - with: - authToken: ${{ secrets.GITHUB_TOKEN }} - context: "${{ env.PMM_TEST_FLAG }} UI tests" - description: "Test execution ${{ job.status }}" - state: "pending" - repository: ${{ github.repository }} - target_url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - sha: ${{ env.SHA }} - - - name: 'Checkout UI tests: "${{ env.UI_TESTS_BRANCH }}"' - uses: actions/checkout@v3 - with: - ref: ${{ env.UI_TESTS_BRANCH }} - repository: percona/pmm-ui-tests - path: ./pmm-ui-tests - - - name: 'Install playwright' - working-directory: ./pmm-ui-tests/playwright-tests - run: | - npm ci - npx playwright install - - - name: 'Checkout pmm-qa: "${{ env.PMM_QA_BRANCH }}"' - uses: actions/checkout@v3 - with: - repository: percona/pmm-qa - ref: ${{ env.PMM_QA_BRANCH }} - path: ./pmm-qa - - - name: 'Setup : "${{ env.PMM_SERVER_VERSION }}"' - working-directory: pmm-qa/pmm-integration - run: | - npm install - sudo npx ts-node ./integration-setup.ts --ci --setup-docker-pmm-server --rbac --pmm-server-docker-tag=${{ format('perconalab/pmm-server:{0}', env.PMM_SERVER_VERSION) }} --pmm-client-version=${{ env.PMM_CLIENT_VERSION }} - timeout 100 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost/ping)" != "200" ]]; do sleep 5; done' || false - - - name: 'Setup ' - run: | - sudo bash ./pmm-qa/pmm-tests/pmm2-client-setup.sh --pmm_server_ip 127.0.0.1 --client_version ${{ env.PMM_CLIENT_VERSION }} --admin_password admin --use_metrics_mode no - shell: bash - - - name: Setup Databases for the PMM-Server - working-directory: pmm-qa/pmm-integration - run: | - sudo npx ts-node ./integration-setup.ts --ci \ - ${{ env.PMM_CLIENTS }} - sleep 30 - sudo pmm-admin list - shell: bash - - - name: 'Run UI tests: ${{ env.PMM_TEST_FLAG }}' - if: ${{ inputs.pmm_test_flag != 'null' }} - id: ui-tests-flagged - working-directory: pmm-ui-tests/playwright-tests - run: | - npx playwright test --config="playwright.config.ts" --grep="${{ env.PMM_TEST_FLAG }}" -# env: -# NODE_TLS_REJECT_UNAUTHORIZED: 0 - - - name: 'Create report name' - if: failure() - run: | - # TODO: add job id for matrix call - job_tag=$(echo "${{ env.PMM_TEST_FLAG }}" | sed -e "s/-pre-upgrade//" -e "s/@//") - report_name=${{ env.PMM_SERVER_VERSION }}"$job_tag"-report - echo $report_name - echo "REPORT_NAME=$report_name" >> $GITHUB_ENV - - - name: Generate and Attach the report - if: failure() - uses: actions/upload-artifact@v3 - with: - name: ${{ env.REPORT_NAME }} - path: ./pmm-ui-tests/playwright-tests/playwright-report - - - name: Create status check - uses: percona/gh-action-Sibz-github-status-action@v1 - if: ${{ env.SHA != 'null' && always() }} - continue-on-error: true - with: - authToken: ${{ secrets.GITHUB_TOKEN }} - context: "${{ env.PMM_TEST_FLAG }} UI tests" - description: "Test execution ${{ job.status }}" - state: ${{ job.status }} - repository: ${{ github.repository }} - target_url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - sha: ${{ env.SHA }} diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml new file mode 100644 index 000000000..3cd3531d2 --- /dev/null +++ b/.github/workflows/ui-tests-pipeline.yml @@ -0,0 +1,291 @@ +--- +name: ui-tests-pipeline + +on: + workflow_dispatch: + inputs: + pmm_ui_tests_branch: + description: 'pmm-ui-tests repository branch' + type: string + default: 'main' + required: true + tests_tag: + description: 'Flag to run only specific portion of the tests.' + type: string + required: false + pmm_qa_branch: + description: 'pmm-qa repository branch(for setup)' + type: string + default: 'main' + required: true + pmm_server_version: + description: 'PMM Server version to test (latest|dev-latest|x.xx.x|x.xx.x-rc)' + type: string + default: 'dev-latest' + required: true + pmm_client_version: + description: 'PMM Client version to test (dev-latest|pmm2-latest|pmm2-rc|x.xx.x)' + type: string + default: 'dev-latest' + required: true + pmm_clients: + description: 'Services to setup and connect to pmm-server' + type: string + default: '--addclient=ps,1' + required: true + + workflow_call: + inputs: + pmm_ui_tests_branch: + description: "Branch for PMM-UI tests to checkout" + required: false + type: string + pmm_qa_branch: + description: 'pmm-qa repository branch(for setup)' + required: false + type: string + sha: + description: "SHA (leave empty if running manually, default - 'null')" + required: false + type: string + pmm_server_version: + description: 'PMM Server version to test (latest|dev-latest|x.xx.x|x.xx.x-rc)' + type: string + default: 'dev-latest' + required: false + server_image: + description: "pmm-server docker image, default perconalab/pmm-server:dev-latest" + required: false + type: string + client_version: + description: "pmm2-client version Tarball or Dev-latest, default is dev-latest" + required: false + type: string + client_image: + description: "pmm2-client docker image, default perconalab/pmm-client:dev-latest" + required: false + type: string + client_flags: + description: "example: --addclient=ps,1 --ps-version=5.7" + required: false + type: string + tags_for_tests: + description: "CodeceptJS tag expression, ex: @settings-fb" + type: string + tags_for_playwright: + description: "Playwright ag expression, ex: @settings-fb" + type: string + version_string: + description: 'x.xx.x version string for josb name' + type: string + +jobs: + ui-tests-e2e: + name: ${{ inputs.version_string || inputs.pmm_server_version || 'dev-latest' }} + # runs-on: ubuntu-latest Mongo Replica setup fails in ubuntu-latest for some reason. Additional investigation needed + runs-on: ubuntu-20.04 + timeout-minutes: 60 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SHA: ${{ inputs.sha || 'null' }} + PMM_QA_BRANCH: ${{ inputs.pmm_qa_branch || 'main' }} + PMM_QA_GIT_BRANCH: ${{ inputs.pmm_qa_branch || 'main' }} + PMM_UI_BRANCH: ${{ inputs.pmm_ui_tests_branch || 'main' }} + CLIENT_FLAGS: ${{ inputs.client_flags || '' }} + TAGS_FOR_TESTS: ${{ inputs.tags_for_tests || '@settings-fb' }} + + ### Variables also used in tests + SERVER_IP: "192.168.0.1" + PMM_UI_URL: "http://192.168.0.1/" + ADMIN_PASSWORD: 'admin-password' + # PATH_TO_PMM_QA defined in job steps + DOCKER_VERSION: ${{ inputs.server_image }} + + ########################################## + ### Credentials required for tests ### + ########################################## + + # Backup tests credentials + BACKUP_LOCATION_ACCESS_KEY: ${{ secrets.BACKUP_LOCATION_ACCESS_KEY }} + BACKUP_LOCATION_SECRET_KEY: ${{ secrets.BACKUP_LOCATION_SECRET_KEY }} + + # Portal tests credentials + PORTAL_BASE_URL: 'https://portal-dev.percona.com' + OAUTH_DEV_HOST: ${{ secrets.OAUTH_DEV_HOST }} + OAUTH_ISSUER_URL: 'https://id-dev.percona.com/oauth2/aus15pi5rjdtfrcH51d7' + OKTA_TOKEN: ${{ secrets.OKTA_TOKEN }} + SERVICENOW_LOGIN: percona_platform + SERVICENOW_PASSWORD: ${{ secrets.SERVICENOW_PASSWORD }} + SERVICENOW_DEV_URL: 'https://perconadev.service-now.com/api/x_pellc_percona_pl/platform/settest' + + steps: + - name: Create status check + if: ${{ github.event_name != 'pull_request' }} + uses: percona-platform/github-status-action@v1 + continue-on-error: true + with: + authToken: ${{ secrets.GITHUB_TOKEN }} + context: "${{ env.TAGS_FOR_TESTS || inputs.tags_for_playwright }} UI tests" + description: "Test execution ${{ job.status }}" + state: "pending" + repository: ${{ github.repository }} + target_url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + sha: ${{ env.SHA }} + + - name: 'Checkout PMM UI tests: "${{ inputs.pmm_ui_tests_branch }}"' + uses: actions/checkout@v3 + with: + ref: ${{ env.PMM_UI_BRANCH }} + repository: percona/pmm-ui-tests + path: ./pmm-ui-tests + + - name: 'Checkout pmm-qa: "${{ inputs.pmm_qa_branch }}"' + uses: actions/checkout@v3 + with: + repository: percona/pmm-qa + ref: ${{ inputs.pmm_qa_branch }} + path: ./pmm-qa + + - name: 'Export "PATH_TO_PMM_QA" variable' + working-directory: ./pmm-qa + run: echo "PATH_TO_PMM_QA=$(pwd)" >> $GITHUB_ENV + + - name: Setup tools + run: | + npm install -g bats + sudo apt-get install -y apt-transport-https ca-certificates dirmngr ansible libaio1 libaio-dev libnuma-dev libncurses5 socat sysbench + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 8919F6BD2B48D754 + echo "deb https://packages.clickhouse.com/deb stable main" | sudo tee \ + /etc/apt/sources.list.d/clickhouse.list + sudo apt-get update + sudo apt-get install -y clickhouse-client + sudo curl -s https://raw.githubusercontent.com/datacharmer/dbdeployer/master/scripts/dbdeployer-install.sh | bash + ls -la + # use ${{ env.PATH_TO_PMM_QA }} instead of pushd + pushd pmm-qa + wget https://raw.githubusercontent.com/Percona-QA/percona-qa/master/get_download_link.sh + chmod +x get_download_link.sh + popd + + - name: 'Select image' + if: ${{ inputs.server_image == 'null' }} + id: get_pmm_image + shell: bash + run: | + tag=${{ inputs.pmm_server_version }} + repo=percona + if [[ "$tag" == "dev-latest" ]]; then + repo=perconalab + fi + if [[ "$tag" =~ "-rc" ]]; then + repo=perconalab + fi + echo "image=$repo/pmm-server:$tag" >> "$GITHUB_OUTPUT" + echo "DOCKER_VERSION=$repo/pmm-server:$tag" >> $GITHUB_ENV + + - name: 'Setup : "${{ inputs.server_image || steps.get_pmm_image.outputs.image }}"' + working-directory: ./pmm-ui-tests + run: | + PWD=$(pwd) PMM_SERVER_IMAGE=${{ inputs.server_image || steps.get_pmm_image.outputs.image }} docker-compose up -d + + ### wait for service to be ready + export CONTAINER_NAME="pmm-server" + export LOGS="pmm-managed entered RUNNING state" + attempt=0 + while [ $attempt -le 3 ]; do + attempt=$(( $attempt + 1 )) + echo "Waiting for ${CONTAINER_NAME} to be up (attempt: $attempt)..." + result=$(systemctl --user status ${CONTAINER_NAME}) + if grep "${LOGS}" <<< $result ; then + echo "${CONTAINER_NAME} is ready!" + break + fi + sleep 10 + done; + timeout 100 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://admin:admin@${{ env.SERVER_IP }}/ping)" != "200" ]]; do sleep 5; done' || false + + docker exec pmm-server change-admin-password ${{ env.ADMIN_PASSWORD }} + bash -x testdata/db_setup.sh + + - name: 'Setup ' + working-directory: ./pmm-qa + run: | + sudo bash -x pmm-tests/pmm2-client-setup.sh \ + --pmm_server_ip ${{ env.SERVER_IP }} --client_version ${{ env.CLIENT_VERSION }} \ + --admin_password ${{ env.ADMIN_PASSWORD }} --use_metrics_mode no + + - name: Setup Services for the PMM Server + working-directory: ./pmm-qa + run: sudo -E bash -x pmm-tests/pmm-framework.sh ${{ env.CLIENT_FLAGS }} --pmm2 + + - name: Install CodeceptJs + if: ${{ inputs.tags_for_tests != 'null' }} + working-directory: ./pmm-ui-tests + run: | + npm ci + envsubst < env.list > env.generated.list + + - name: 'Run Codecept e2e tests: ${{ inputs.tags_for_tests }}' + if: ${{ inputs.tags_for_tests != 'null' }} + working-directory: ./pmm-ui-tests + env: + PMM_URL : "http://admin:${{ env.ADMIN_PASSWORD }}@${{ env.SERVER_IP }}" + run: | + sed -i 's+http://localhost/+${PMM_UI_URL}/+g' pr.codecept.js + ./node_modules/.bin/codeceptjs run -c pr.codecept.js --grep "${{ inputs.tags_for_tests }}" + + - name: 'Install playwright' + if: ${{ inputs.tags_for_playwright != 'null' }} + working-directory: ./pmm-ui-tests/playwright-tests + run: | + npm ci + npx playwright install + + - name: 'Run Playwright e2e tests: ${{ inputs.tags_for_playwright }}' + if: ${{ inputs.tags_for_playwright != 'null' }} + working-directory: ./pmm-ui-tests/playwright-tests + run: npx playwright test --grep="${{ inputs.post_upgrade_tests }}" --pass-with-no-tests + env: + NODE_TLS_REJECT_UNAUTHORIZED: 0 + + - name: 'Create report name' + if: failure() && ${{ inputs.tags_for_playwright != 'null' }} + run: | + # TODO: add job id for matrix call + job_tag=$(echo "${{ inputs.tags_for_playwright }}" | sed -e "s/-pre-upgrade//" -e "s/@//") + report_name=${{ env.CLIENT_VERSION }}"$job_tag"-report + report_name="$job_tag"-${{ inputs.version_string_from || inputs.pmm_server_start_version }}-report + echo $report_name + echo "REPORT_NAME=$report_name" >> $GITHUB_ENV + + - name: Generate and Attach the report + if: failure() && ${{ inputs.tags_for_playwright != 'null' }} + uses: actions/upload-artifact@v3 + with: + name: ${{ env.REPORT_NAME }} + path: ./pmm-ui-tests/playwright-tests/playwright-report + + - uses: actions/github-script@v6 + if: ${{ always() }} + id: artifact_name + with: + script: | + return `artifacts_for_${process.env.TAGS_FOR_TESTS.replaceAll('|', '')}` + result-encoding: string + + - name: Create status check + if: ${{ github.event_name != 'pull_request' && always() }} + uses: percona-platform/github-status-action@v1 + continue-on-error: true + with: + authToken: ${{ secrets.GITHUB_TOKEN }} + context: "${{ env.TAGS_FOR_TESTS || inputs.tags_for_playwright }} UI tests" + description: "Test execution ${{ job.status }}" + state: ${{ job.status }} + repository: ${{ github.repository }} + target_url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + sha: ${{ env.SHA }} + +# - name: Setup tmate session on failure +# if: ${{ failure() }} +# uses: percona-platform/action-tmate@v2 diff --git a/playwright-tests/helpers/constants.ts b/playwright-tests/helpers/constants.ts index 2fc74f564..a057f3c53 100644 --- a/playwright-tests/helpers/constants.ts +++ b/playwright-tests/helpers/constants.ts @@ -10,7 +10,7 @@ const constants = { }, okta: { url: `https://${process.env.OAUTH_DEV_HOST}`, - issuerUrl: process.env.REACT_APP_OAUTH_DEV_ISSUER_URI || '', + issuerUrl: process.env.OAUTH_ISSUER_URL || '', token: `SSWS ${process.env.OKTA_TOKEN}`, }, portal: { diff --git a/playwright-tests/playwright.config.ts b/playwright-tests/playwright.config.ts index 08a74f659..fa95dcafc 100644 --- a/playwright-tests/playwright.config.ts +++ b/playwright-tests/playwright.config.ts @@ -13,9 +13,7 @@ dotenv.config({ path: '.env.local' }); const config: PlaywrightTestConfig = { testDir: './tests', timeout: Duration.FiveMinutes, - expect: { - timeout: 10_000, - }, + expect: { timeout: 10_000 }, fullyParallel: false, forbidOnly: !!process.env.CI, retries: process.env.CI ? 1 : 0, @@ -27,7 +25,7 @@ const config: PlaywrightTestConfig = { use: { navigationTimeout: 30_000, - baseURL: process.env.PMM_BASE_URL || 'https://localhost', + baseURL: process.env.PMM_UI_URL || 'https://localhost', ignoreHTTPSErrors: true, screenshot: 'only-on-failure', actionTimeout: 15_000, @@ -38,14 +36,10 @@ const config: PlaywrightTestConfig = { testDir: './tests', testIgnore: 'tests/portal/*.spec.ts', use: { - contextOptions: { - ignoreHTTPSErrors: true, - }, + contextOptions: { ignoreHTTPSErrors: true }, screenshot: 'on', ...devices['Desktop Chrome'], - viewport: { - width: 1920, height: 1080, - }, + viewport: { width: 1920, height: 1080 }, }, }, { @@ -58,14 +52,10 @@ const config: PlaywrightTestConfig = { testMatch: 'tests/portal/*.spec.ts', retries: 0, use: { - contextOptions: { - ignoreHTTPSErrors: true, - }, + contextOptions: { ignoreHTTPSErrors: true }, screenshot: 'on', ...devices['Desktop Chrome'], - viewport: { - width: 1920, height: 1080, - }, + viewport: { width: 1920, height: 1080 }, }, }, ], diff --git a/playwright-tests/tests/portal/testUsers.setup.ts b/playwright-tests/tests/portal/testUsers.setup.ts index 257a20fe3..5c26f1762 100644 --- a/playwright-tests/tests/portal/testUsers.setup.ts +++ b/playwright-tests/tests/portal/testUsers.setup.ts @@ -9,10 +9,12 @@ import constants from '@helpers/constants'; * Note that there are only 2 ways to pass any artifacts to tests: environment variables and files */ setup('Setup Portal tests', async ({ baseURL }) => { + await setup.step('Validate environment variables credentials', async () => { + // TODO: implement non empty check for constants.portal.* constants.okta.* constants.serviceNow.* + }); + await setup.step('Add pmm-server settings', async () => { - await api.pmm.settingsV1.changeSettings({ - pmm_public_address: baseURL!.replace(/(^\w+:|^)\/\//, ''), - }); + await api.pmm.settingsV1.changeSettings({ pmm_public_address: baseURL!.replace(/(^\w+:|^)\/\//, '') }); }); await setup.step('Remove old credentials file if it\'s there', async () => { if (fileHelper.fileExists(constants.portal.credentialsFile)) { diff --git a/pr.codecept.js b/pr.codecept.js index 361e4512b..6ef1b488a 100644 --- a/pr.codecept.js +++ b/pr.codecept.js @@ -2,13 +2,15 @@ const { pageObjects, getChunks } = require('./codeceptConfigHelper'); require('dotenv').config(); +const pmmUrl = 'http://127.0.0.1/'; + process.env.ADMIN_PASSWORD = process.env.ADMIN_PASSWORD || 'admin'; exports.config = { output: 'tests/output', helpers: { Playwright: { - url: process.env.PMM_UI_URL || 'http://127.0.0.1/', + url: process.env.PMM_UI_URL || pmmUrl, restart: true, browser: 'chromium', windowSize: '1920x1080', @@ -62,7 +64,7 @@ exports.config = { require: './tests/helper/browser_helper.js', }, REST: { - endpoint: process.env.PMM_UI_URL || 'http://127.0.0.1/', + endpoint: process.env.PMM_UI_URL || pmmUrl, timeout: 60000, }, Mailosaur: { From 1151608b49f41262542c08a5a776a9983c7e28f0 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 10:42:00 +0200 Subject: [PATCH 03/20] PMM-7 clean up --- .github/workflows/portal-tests-matrix.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/portal-tests-matrix.yml b/.github/workflows/portal-tests-matrix.yml index 7d0c25f36..7b9695d31 100644 --- a/.github/workflows/portal-tests-matrix.yml +++ b/.github/workflows/portal-tests-matrix.yml @@ -1,10 +1,6 @@ name: "Portal Tests Matrix" on: - push: - branches: - - "PMM-7-fix-portal-pipeline" - jobs: get_versions: name: Get versions From e61bac694ae62055e0141be901b52930a68153d5 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 10:44:05 +0200 Subject: [PATCH 04/20] PMM-7 changed defaults --- .github/workflows/pmm-ui-tests-matrix.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pmm-ui-tests-matrix.yml b/.github/workflows/pmm-ui-tests-matrix.yml index 4bef6091d..6cff7c41b 100644 --- a/.github/workflows/pmm-ui-tests-matrix.yml +++ b/.github/workflows/pmm-ui-tests-matrix.yml @@ -15,11 +15,11 @@ on: required: true pmm_server_version: description: 'PMM Server version to upgrade (latest|dev-latest|x.xx.x|x.xx.x-rc)' - default: 'latest' + default: 'dev-latest' required: true pmm_client_version: description: 'PMM Client version to upgrade from (dev-latest|pmm2-latest|pmm2-rc|x.xx.x)' - default: 'pmm2-latest' + default: 'dev-latest' required: true jobs: inventory: From 7a8d4927fa8705c01f7a1c9f522603d6e39a8161 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 10:47:53 +0200 Subject: [PATCH 05/20] PMM-7 fixed fields --- .github/workflows/ui-tests-pipeline.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index 3cd3531d2..07fe146bb 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -23,7 +23,7 @@ on: type: string default: 'dev-latest' required: true - pmm_client_version: + client_version: description: 'PMM Client version to test (dev-latest|pmm2-latest|pmm2-rc|x.xx.x)' type: string default: 'dev-latest' @@ -207,11 +207,11 @@ jobs: docker exec pmm-server change-admin-password ${{ env.ADMIN_PASSWORD }} bash -x testdata/db_setup.sh - - name: 'Setup ' + - name: 'Setup ' working-directory: ./pmm-qa run: | sudo bash -x pmm-tests/pmm2-client-setup.sh \ - --pmm_server_ip ${{ env.SERVER_IP }} --client_version ${{ env.CLIENT_VERSION }} \ + --pmm_server_ip ${{ env.SERVER_IP }} --client_version ${{ inputs.client_version }} \ --admin_password ${{ env.ADMIN_PASSWORD }} --use_metrics_mode no - name: Setup Services for the PMM Server @@ -253,7 +253,7 @@ jobs: run: | # TODO: add job id for matrix call job_tag=$(echo "${{ inputs.tags_for_playwright }}" | sed -e "s/-pre-upgrade//" -e "s/@//") - report_name=${{ env.CLIENT_VERSION }}"$job_tag"-report + report_name=${{ inputs.client_version }}"$job_tag"-report report_name="$job_tag"-${{ inputs.version_string_from || inputs.pmm_server_start_version }}-report echo $report_name echo "REPORT_NAME=$report_name" >> $GITHUB_ENV From 1430444daa7306c2b915fa4ade2f4678910e12d5 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 10:49:34 +0200 Subject: [PATCH 06/20] PMM-7 fixed syntax --- .github/workflows/pmm-ui-tests-matrix.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pmm-ui-tests-matrix.yml b/.github/workflows/pmm-ui-tests-matrix.yml index 6cff7c41b..0998773db 100644 --- a/.github/workflows/pmm-ui-tests-matrix.yml +++ b/.github/workflows/pmm-ui-tests-matrix.yml @@ -30,7 +30,7 @@ jobs: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} pmm_qa_branch: ${{ github.event.inputs.pmm_qa_branch || 'main' }} pmm_server_version: ${{ inputs.pmm_server_version || 'dev-latest' }} - client_version: ${{ .pmm_client_version || 'dev-latest' }} + client_version: ${{ inputs.pmm_client_version || 'dev-latest' }} tags_for_playwright: '@inventory' client_flags: '--addclient=modb,1 --addclient=ps,1 --addclient=pdpgsql,1' version_string: ${{ inputs.pmm_server_version || 'dev-latest' }} @@ -43,7 +43,7 @@ jobs: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} pmm_qa_branch: ${{ github.event.inputs.pmm_qa_branch || 'main' }} pmm_server_version: ${{ inputs.pmm_server_version || 'dev-latest' }} - client_version: ${{ .pmm_client_version || 'dev-latest' }} + client_version: ${{ inputs.pmm_client_version || 'dev-latest' }} tags_for_playwright: '@portal' client_flags: '' version_string: ${{ inputs.pmm_server_version || 'dev-latest' }} @@ -56,7 +56,7 @@ jobs: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} pmm_qa_branch: ${{ github.event.inputs.pmm_qa_branch || 'main' }} pmm_server_version: ${{ inputs.pmm_server_version || 'dev-latest' }} - client_version: ${{ .pmm_client_version || 'dev-latest' }} + client_version: ${{ inputs.pmm_client_version || 'dev-latest' }} tags_for_playwright: '@rbac' client_flags: '--addclient=ps,1 --addclient=pdpgsql,1' version_string: ${{ inputs.pmm_server_version || 'dev-latest' }} From 4145ebd4a9ddf18014c03c0d62206012c0b55ef6 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 12:12:50 +0200 Subject: [PATCH 07/20] PMM-7 fixed conditional --- .github/workflows/ui-tests-pipeline.yml | 2 +- .../tests/inventory/pages/components/agents-table.ts | 10 +++------- playwright-tests/tests/portal/testUsers.setup.ts | 11 ++++++++++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index 07fe146bb..d867f3385 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -168,7 +168,7 @@ jobs: popd - name: 'Select image' - if: ${{ inputs.server_image == 'null' }} + if: ${{ !inputs.server_image }} id: get_pmm_image shell: bash run: | diff --git a/playwright-tests/tests/inventory/pages/components/agents-table.ts b/playwright-tests/tests/inventory/pages/components/agents-table.ts index bd6c2ef9b..a21be0bec 100644 --- a/playwright-tests/tests/inventory/pages/components/agents-table.ts +++ b/playwright-tests/tests/inventory/pages/components/agents-table.ts @@ -35,20 +35,16 @@ export default class AgentsTable extends Table { }; verifyAllAgentsStatus = async (expectedStatus: string) => { - await this.elements.statuses.first().waitFor({ - state: 'visible', - }); + await this.elements.statuses.first().waitFor({ state: 'visible' }); const agents: ElementHandle[] = await this.elements.statuses.elementHandles(); - for await (const [, agent] of agents.entries()) { + for await (const agent of agents.values()) { expect(await agent.textContent()).toEqual(expectedStatus); } }; verifyAgentLabelPresent = async (labelName: string) => { - await this.elements.label(labelName).waitFor({ - state: 'visible', - }); + await this.elements.label(labelName).waitFor({ state: 'visible' }); }; verifyAgentLabelVisibleForAgentsExcept = async (labelName: string, exceptions: string[]) => { diff --git a/playwright-tests/tests/portal/testUsers.setup.ts b/playwright-tests/tests/portal/testUsers.setup.ts index 5c26f1762..bab283d0d 100644 --- a/playwright-tests/tests/portal/testUsers.setup.ts +++ b/playwright-tests/tests/portal/testUsers.setup.ts @@ -1,4 +1,4 @@ -import { test as setup } from '@playwright/test'; +import { expect, test as setup } from '@playwright/test'; import { api } from '@api/api'; import { portalHelper } from '@helpers/portal-helper'; import { fileHelper } from '@helpers/file-helper'; @@ -11,6 +11,15 @@ import constants from '@helpers/constants'; setup('Setup Portal tests', async ({ baseURL }) => { await setup.step('Validate environment variables credentials', async () => { // TODO: implement non empty check for constants.portal.* constants.okta.* constants.serviceNow.* + Object.entries(constants.portal).forEach(([key, val]) => { + expect(val, `Portal tests requires "portal.${key}"!`).toBeTruthy(); + }); + Object.entries(constants.okta).forEach(([key, val]) => { + expect(val, `Portal tests requires "okta.${key}"!`).toBeTruthy(); + }); + Object.entries(constants.serviceNow).forEach(([key, val]) => { + expect(val, `Portal tests requires "serviceNow.${key}"!`).toBeTruthy(); + }); }); await setup.step('Add pmm-server settings', async () => { From ec74a0b26c5cf5d08198f36500f2fbfafa3f9712 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 12:20:57 +0200 Subject: [PATCH 08/20] PMM-7 fixed waiting --- .github/workflows/ui-tests-pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index d867f3385..b5961451d 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -168,7 +168,7 @@ jobs: popd - name: 'Select image' - if: ${{ !inputs.server_image }} + if: ${{ !inputs.server_image && !!inputs.pmm_server_version }} id: get_pmm_image shell: bash run: | @@ -183,7 +183,7 @@ jobs: echo "image=$repo/pmm-server:$tag" >> "$GITHUB_OUTPUT" echo "DOCKER_VERSION=$repo/pmm-server:$tag" >> $GITHUB_ENV - - name: 'Setup : "${{ inputs.server_image || steps.get_pmm_image.outputs.image }}"' + - name: 'Setup : "${{ inputs.server_image || steps.get_pmm_image.outputs.image }}"' working-directory: ./pmm-ui-tests run: | PWD=$(pwd) PMM_SERVER_IMAGE=${{ inputs.server_image || steps.get_pmm_image.outputs.image }} docker-compose up -d @@ -195,7 +195,7 @@ jobs: while [ $attempt -le 3 ]; do attempt=$(( $attempt + 1 )) echo "Waiting for ${CONTAINER_NAME} to be up (attempt: $attempt)..." - result=$(systemctl --user status ${CONTAINER_NAME}) + result=$(docker logs ${CONTAINER_NAME} 2>&1) if grep "${LOGS}" <<< $result ; then echo "${CONTAINER_NAME} is ready!" break From d654cdafe7ee918848ec65723b3f310ca58f4b84 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 12:49:50 +0200 Subject: [PATCH 09/20] PMM-7 added portal matrix dispatch --- .github/workflows/portal-tests-matrix.yml | 28 +++++++++++++++++++---- .github/workflows/ui-tests-pipeline.yml | 15 ++++++++---- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/.github/workflows/portal-tests-matrix.yml b/.github/workflows/portal-tests-matrix.yml index 7b9695d31..cb4263060 100644 --- a/.github/workflows/portal-tests-matrix.yml +++ b/.github/workflows/portal-tests-matrix.yml @@ -1,6 +1,25 @@ name: "Portal Tests Matrix" on: + workflow_dispatch: + inputs: + pmm_ui_tests_branch: + description: 'pmm-ui-tests repository branch' + default: 'main' + required: true + pmm_qa_branch: + description: 'pmm-qa repository branch(for setup)' + default: 'main' + required: true + pmm_server_version: + description: 'PMM Server version to upgrade (latest|dev-latest|x.xx.x|x.xx.x-rc)' + default: 'dev-latest' + required: true + pmm_client_version: + description: 'PMM Client version to upgrade from (dev-latest|pmm2-latest|pmm2-rc|x.xx.x)' + default: 'dev-latest' + required: true + jobs: get_versions: name: Get versions @@ -20,10 +39,9 @@ jobs: old_version: ${{ fromJSON(needs.get_versions.outputs.version_matrix) }} with: pmm_ui_tests_branch: ${{ inputs.pmm_ui_tests_branch || 'main' }} - pmm_test_flag: '@portal' - pmm_server_version: ${{ matrix.old_version }} - pmm_client_version: ${{ matrix.old_version }} pmm_qa_branch: ${{ inputs.pmm_qa_branch || 'main' }} + pmm_server_version: ${{ matrix.old_version }} + client_version: ${{ matrix.old_version }} + tags_for_playwright: '@portal' pmm_clients: '' - version_string_from: ${{needs.get_versions.outputs.start_version}} - + version_string: ${{needs.get_versions.outputs.start_version}} diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index b5961451d..35dd8b135 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -132,6 +132,13 @@ jobs: target_url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" sha: ${{ env.SHA }} + - name: 'Prevent both Codecept and Playwright tests execution' + if: ${{ !!inputs.tags_for_tests && !!inputs.tags_for_playwright }} + run: | + echo "Both Codecept(tags_for_tests) and Playwright(tags_for_playwright) tests are forbidden in a single test run!" + echo "Please use only one tag input for job call" + exit 1 + - name: 'Checkout PMM UI tests: "${{ inputs.pmm_ui_tests_branch }}"' uses: actions/checkout@v3 with: @@ -226,7 +233,7 @@ jobs: envsubst < env.list > env.generated.list - name: 'Run Codecept e2e tests: ${{ inputs.tags_for_tests }}' - if: ${{ inputs.tags_for_tests != 'null' }} + if: ${{ !!inputs.tags_for_tests }} working-directory: ./pmm-ui-tests env: PMM_URL : "http://admin:${{ env.ADMIN_PASSWORD }}@${{ env.SERVER_IP }}" @@ -235,21 +242,21 @@ jobs: ./node_modules/.bin/codeceptjs run -c pr.codecept.js --grep "${{ inputs.tags_for_tests }}" - name: 'Install playwright' - if: ${{ inputs.tags_for_playwright != 'null' }} + if: ${{ !!inputs.tags_for_playwright }} working-directory: ./pmm-ui-tests/playwright-tests run: | npm ci npx playwright install - name: 'Run Playwright e2e tests: ${{ inputs.tags_for_playwright }}' - if: ${{ inputs.tags_for_playwright != 'null' }} + if: ${{ !!inputs.tags_for_playwright }} working-directory: ./pmm-ui-tests/playwright-tests run: npx playwright test --grep="${{ inputs.post_upgrade_tests }}" --pass-with-no-tests env: NODE_TLS_REJECT_UNAUTHORIZED: 0 - name: 'Create report name' - if: failure() && ${{ inputs.tags_for_playwright != 'null' }} + if: failure() && ${{ !!inputs.tags_for_playwright }} run: | # TODO: add job id for matrix call job_tag=$(echo "${{ inputs.tags_for_playwright }}" | sed -e "s/-pre-upgrade//" -e "s/@//") From 5457a29cf7ca9883263806e31161790b321f086e Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 12:52:48 +0200 Subject: [PATCH 10/20] PMM-7 added portal matrix dispatch --- .github/workflows/portal-tests-matrix.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/portal-tests-matrix.yml b/.github/workflows/portal-tests-matrix.yml index cb4263060..128f01c54 100644 --- a/.github/workflows/portal-tests-matrix.yml +++ b/.github/workflows/portal-tests-matrix.yml @@ -1,6 +1,9 @@ name: "Portal Tests Matrix" on: + push: + branches: + - PMM-7-update-gh workflow_dispatch: inputs: pmm_ui_tests_branch: From d250138c71e8e5ba189737385e5572118492ea9d Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 12:53:44 +0200 Subject: [PATCH 11/20] PMM-7 fixed portal matrix --- .github/workflows/portal-tests-matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/portal-tests-matrix.yml b/.github/workflows/portal-tests-matrix.yml index 128f01c54..8a47efbca 100644 --- a/.github/workflows/portal-tests-matrix.yml +++ b/.github/workflows/portal-tests-matrix.yml @@ -33,7 +33,7 @@ jobs: portal: name: 'Portal / Integration' - uses: ./.github/workflows/portal-ui-tests.yml + uses: ./.github/workflows/ui-tests-pipeline.yml secrets: inherit needs: get_versions strategy: From 5c7bfaedee7904668017b0692c7e7f712fcde727 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 12:55:47 +0200 Subject: [PATCH 12/20] PMM-7 fixed portal matrix --- .github/workflows/portal-tests-matrix.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/portal-tests-matrix.yml b/.github/workflows/portal-tests-matrix.yml index 8a47efbca..4b864f3eb 100644 --- a/.github/workflows/portal-tests-matrix.yml +++ b/.github/workflows/portal-tests-matrix.yml @@ -41,10 +41,10 @@ jobs: matrix: old_version: ${{ fromJSON(needs.get_versions.outputs.version_matrix) }} with: - pmm_ui_tests_branch: ${{ inputs.pmm_ui_tests_branch || 'main' }} + pmm_ui_tests_branch: ${{ inputs.pmm_ui_tests_branch || 'PMM-7-update-gh' }} pmm_qa_branch: ${{ inputs.pmm_qa_branch || 'main' }} pmm_server_version: ${{ matrix.old_version }} client_version: ${{ matrix.old_version }} tags_for_playwright: '@portal' - pmm_clients: '' + client_flags: '' version_string: ${{needs.get_versions.outputs.start_version}} From 3c1d6913c7408e991d32896a2a315ba1e24fe6e7 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 12:58:08 +0200 Subject: [PATCH 13/20] PMM-7 fixed portal matrix --- .github/workflows/ui-tests-pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index 35dd8b135..8f8c567ec 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -226,7 +226,7 @@ jobs: run: sudo -E bash -x pmm-tests/pmm-framework.sh ${{ env.CLIENT_FLAGS }} --pmm2 - name: Install CodeceptJs - if: ${{ inputs.tags_for_tests != 'null' }} + if: ${{ !!inputs.tags_for_tests }} working-directory: ./pmm-ui-tests run: | npm ci From 1113f4eb59a5b33178c56d2d1741a733af490277 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 13:13:33 +0200 Subject: [PATCH 14/20] PMM-7 fixed playwright tags --- .github/workflows/ui-tests-pipeline.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index 8f8c567ec..8b24ea235 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -251,7 +251,7 @@ jobs: - name: 'Run Playwright e2e tests: ${{ inputs.tags_for_playwright }}' if: ${{ !!inputs.tags_for_playwright }} working-directory: ./pmm-ui-tests/playwright-tests - run: npx playwright test --grep="${{ inputs.post_upgrade_tests }}" --pass-with-no-tests + run: npx playwright test --grep="${{ inputs.tags_for_playwright }}" --pass-with-no-tests env: NODE_TLS_REJECT_UNAUTHORIZED: 0 @@ -261,7 +261,6 @@ jobs: # TODO: add job id for matrix call job_tag=$(echo "${{ inputs.tags_for_playwright }}" | sed -e "s/-pre-upgrade//" -e "s/@//") report_name=${{ inputs.client_version }}"$job_tag"-report - report_name="$job_tag"-${{ inputs.version_string_from || inputs.pmm_server_start_version }}-report echo $report_name echo "REPORT_NAME=$report_name" >> $GITHUB_ENV From efd4083bb842e475d117e2f8821cd12e2c619b81 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 13:27:27 +0200 Subject: [PATCH 15/20] PMM-7 added dev latest to matrix --- .github/workflows/portal-tests-matrix.yml | 10 ++-------- .github/workflows/ui-tests-pipeline.yml | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/portal-tests-matrix.yml b/.github/workflows/portal-tests-matrix.yml index 4b864f3eb..890a93c0a 100644 --- a/.github/workflows/portal-tests-matrix.yml +++ b/.github/workflows/portal-tests-matrix.yml @@ -14,14 +14,6 @@ on: description: 'pmm-qa repository branch(for setup)' default: 'main' required: true - pmm_server_version: - description: 'PMM Server version to upgrade (latest|dev-latest|x.xx.x|x.xx.x-rc)' - default: 'dev-latest' - required: true - pmm_client_version: - description: 'PMM Client version to upgrade from (dev-latest|pmm2-latest|pmm2-rc|x.xx.x)' - default: 'dev-latest' - required: true jobs: get_versions: @@ -40,6 +32,8 @@ jobs: fail-fast: false matrix: old_version: ${{ fromJSON(needs.get_versions.outputs.version_matrix) }} + include: + - old_version: dev-latest with: pmm_ui_tests_branch: ${{ inputs.pmm_ui_tests_branch || 'PMM-7-update-gh' }} pmm_qa_branch: ${{ inputs.pmm_qa_branch || 'main' }} diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index 8b24ea235..94b0cd7be 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -251,7 +251,7 @@ jobs: - name: 'Run Playwright e2e tests: ${{ inputs.tags_for_playwright }}' if: ${{ !!inputs.tags_for_playwright }} working-directory: ./pmm-ui-tests/playwright-tests - run: npx playwright test --grep="${{ inputs.tags_for_playwright }}" --pass-with-no-tests + run: npx playwright test --grep "${{ inputs.tags_for_playwright }}" --pass-with-no-tests env: NODE_TLS_REJECT_UNAUTHORIZED: 0 From 403ab9e69887e0c4527a7879bda25ccc1c6b8b97 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 19:26:37 +0200 Subject: [PATCH 16/20] PMM-7 fixed projects setup and toast message methods --- .github/workflows/ui-tests-pipeline.yml | 20 ++- playwright-tests/api/server.api.ts | 4 +- playwright-tests/helpers/enums/duration.ts | 13 -- playwright-tests/helpers/enums/wait.ts | 20 +++ playwright-tests/pages/common.page.ts | 4 +- .../pages/dashboards/base-dashboard.page.ts | 4 +- playwright-tests/pages/home-dashboard.page.ts | 14 +- .../page-components/pmm-upgrade-panel.ts | 22 ++- .../page-components/toast-message-modal.ts | 45 ++++++ .../pages/page-components/toast.ts | 49 ------ .../pmm-settings/percona-platform.page.ts | 4 +- .../pages/serverAdmin/NewUser.page.ts | 11 +- playwright-tests/playwright.config.ts | 14 +- .../configuration/pages/create-role.page.ts | 9 +- .../tests/inventory/inventory.spec.ts | 72 +++------ .../tests/portal/connectPmm.spec.ts | 10 +- .../tests/portal/pmmPortalUpgrade.spec.ts | 12 +- .../tests/portal/postPmmConnect.spec.ts | 142 +++++------------- .../tests/portal/testUsers.setup.ts | 1 - playwright-tests/tests/rbac/rbac.spec.ts | 70 +++------ 20 files changed, 198 insertions(+), 342 deletions(-) delete mode 100644 playwright-tests/helpers/enums/duration.ts create mode 100644 playwright-tests/helpers/enums/wait.ts create mode 100644 playwright-tests/pages/page-components/toast-message-modal.ts delete mode 100644 playwright-tests/pages/page-components/toast.ts diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index 94b0cd7be..7e706bbe7 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -19,7 +19,7 @@ on: default: 'main' required: true pmm_server_version: - description: 'PMM Server version to test (latest|dev-latest|x.xx.x|x.xx.x-rc)' + description: 'PMM Server version to test (latest|dev-latest|x.xx.x|x.xx.x-rc|PR-xx-xxx)' type: string default: 'dev-latest' required: true @@ -49,7 +49,7 @@ on: required: false type: string pmm_server_version: - description: 'PMM Server version to test (latest|dev-latest|x.xx.x|x.xx.x-rc)' + description: 'PMM Server version to test (latest|dev-latest|x.xx.x|x.xx.x-rc|PR)' type: string default: 'dev-latest' required: false @@ -180,14 +180,17 @@ jobs: shell: bash run: | tag=${{ inputs.pmm_server_version }} - repo=percona + repo=percona/pmm-server if [[ "$tag" == "dev-latest" ]]; then - repo=perconalab + repo=perconalab/pmm-server fi if [[ "$tag" =~ "-rc" ]]; then - repo=perconalab + repo=perconalab/pmm-server fi - echo "image=$repo/pmm-server:$tag" >> "$GITHUB_OUTPUT" + if [[ "$tag" =~ "PR-" ]]; then + repo=perconalab/pmm-server-fb + fi + echo "image=$repo:$tag" >> "$GITHUB_OUTPUT" echo "DOCKER_VERSION=$repo/pmm-server:$tag" >> $GITHUB_ENV - name: 'Setup : "${{ inputs.server_image || steps.get_pmm_image.outputs.image }}"' @@ -251,7 +254,10 @@ jobs: - name: 'Run Playwright e2e tests: ${{ inputs.tags_for_playwright }}' if: ${{ !!inputs.tags_for_playwright }} working-directory: ./pmm-ui-tests/playwright-tests - run: npx playwright test --grep "${{ inputs.tags_for_playwright }}" --pass-with-no-tests + run: | + npx playwright test --pass-with-no-tests \ + --project=${{ contains(inputs.tags_for_playwright, 'portal') && 'Portal' || 'Chromium' }} \ + --grep "${{ inputs.tags_for_playwright }}" \ env: NODE_TLS_REJECT_UNAUTHORIZED: 0 diff --git a/playwright-tests/api/server.api.ts b/playwright-tests/api/server.api.ts index 322679e86..690c4e6d1 100644 --- a/playwright-tests/api/server.api.ts +++ b/playwright-tests/api/server.api.ts @@ -1,5 +1,5 @@ import apiHelper from '@api/helpers/api-helper'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import PmmVersion from '@helpers/types/pmm-version.class'; import { expect } from '@playwright/test'; @@ -9,7 +9,7 @@ export const server = { * @returns Promise */ getPmmVersion: async (): Promise => { - const response = await apiHelper.get('/v1/version', { timeout: Duration.ThreeMinutes }); + const response = await apiHelper.get('/v1/version', { timeout: Wait.ThreeMinutes }); await expect(response, `Request should be OK: "${response.status()} ${response.statusText()}" ${await response.text()}`) .toBeOK(); const version = new PmmVersion((await response.json()).version as string); diff --git a/playwright-tests/helpers/enums/duration.ts b/playwright-tests/helpers/enums/duration.ts deleted file mode 100644 index f6e6a8e61..000000000 --- a/playwright-tests/helpers/enums/duration.ts +++ /dev/null @@ -1,13 +0,0 @@ -const oneSecond = 1000; -const oneMin = 60 * oneSecond; - -enum Duration { - OneSecond = oneSecond, - OneMinute = oneMin, - ThreeMinutes = 3 * oneMin, - FiveMinutes = 5 * oneMin, - TenMinutes = 10 * oneMin, - TwentyMinutes = 20 * oneMin, -} - -export default Duration; diff --git a/playwright-tests/helpers/enums/wait.ts b/playwright-tests/helpers/enums/wait.ts new file mode 100644 index 000000000..1f9328bdd --- /dev/null +++ b/playwright-tests/helpers/enums/wait.ts @@ -0,0 +1,20 @@ +const oneSecond = 1000; +const oneMin = 60 * oneSecond; + +/** + * Global waits values collection to remove magic numbers + * and to adjust tests waits in a single place + */ +enum Wait { + OneSecond = oneSecond, + TwoSeconds = 2 * oneSecond, + TenSeconds = 10 * oneSecond, + OneMinute = oneMin, + ThreeMinutes = 3 * oneMin, + FiveMinutes = 5 * oneMin, + TenMinutes = 10 * oneMin, + TwentyMinutes = 20 * oneMin, + ToastMessage = 30 * oneSecond, +} + +export default Wait; diff --git a/playwright-tests/pages/common.page.ts b/playwright-tests/pages/common.page.ts index 944e8d7f0..07c61f6dc 100644 --- a/playwright-tests/pages/common.page.ts +++ b/playwright-tests/pages/common.page.ts @@ -1,12 +1,12 @@ import { Locator, Page } from '@playwright/test'; import { LeftNavigationMenu } from '@components/left-navigation-menu'; -import { Toast } from '@components/toast'; +import ToastMessage from '@components/toast-message-modal'; import OptionsMenu from '@components/options-menu'; import { expect } from '@helpers/test-helper'; import grafanaHelper from '@helpers/grafana-helper'; export class CommonPage { - toast = new Toast(this.page); + toastMessage = new ToastMessage(this.page); sideMenu = new LeftNavigationMenu(this.page); optionMenu = new OptionsMenu(this.page); diff --git a/playwright-tests/pages/dashboards/base-dashboard.page.ts b/playwright-tests/pages/dashboards/base-dashboard.page.ts index a3814cc34..5e7d2fac1 100644 --- a/playwright-tests/pages/dashboards/base-dashboard.page.ts +++ b/playwright-tests/pages/dashboards/base-dashboard.page.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import { CommonPage } from '@pages/common.page'; export class BaseDashboard extends CommonPage { @@ -40,7 +40,7 @@ export class BaseDashboard extends CommonPage { await this.page.waitForTimeout(1000); }; - waitForPanelToHaveData = async (panelHeader: string, panelId: number, timeout: Duration = Duration.OneMinute) => { + waitForPanelToHaveData = async (panelHeader: string, panelId: number, timeout: Wait = Wait.OneMinute) => { await this.openAllPanels(); await this.elements.getPanelByName(panelHeader, panelId).scrollIntoViewIfNeeded(); await expect(this.elements.getPanelByName(panelHeader, panelId)) diff --git a/playwright-tests/pages/home-dashboard.page.ts b/playwright-tests/pages/home-dashboard.page.ts index a5eb2e35f..5911024a6 100644 --- a/playwright-tests/pages/home-dashboard.page.ts +++ b/playwright-tests/pages/home-dashboard.page.ts @@ -1,7 +1,7 @@ import { expect } from '@playwright/test'; import PmmUpgrade from '@components/pmm-upgrade-panel'; import UpgradeModal from '@components/upgrade-modal'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import PmmMenu from '@components/dashboards/pmm-menu'; import { BaseDashboard } from './dashboards/base-dashboard.page'; @@ -11,9 +11,7 @@ export default class HomeDashboardPage extends BaseDashboard { pmmMenu = new PmmMenu(this.page); upgradePmm = async () => { - await this.pmmUpgrade.buttons.upgradeButton.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await this.pmmUpgrade.buttons.upgradeButton.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); const currentVersion = await this.pmmUpgrade.elements.currentVersion.textContent(); await this.pmmUpgrade.buttons.upgradeButton.click(); @@ -21,13 +19,11 @@ export default class HomeDashboardPage extends BaseDashboard { console.log(`Upgrading pmm server from version: ${currentVersion} to the version: ${availableVersion}`); - await this.upgradeModal.containers.modalContainer.waitFor({ - state: 'visible', timeout: Duration.OneMinute, - }); + await this.upgradeModal.containers.modalContainer.waitFor({ state: 'visible', timeout: Wait.OneMinute }); await this.upgradeModal.elements.upgradeInProgressHeader - .waitFor({ state: 'visible', timeout: Duration.OneMinute }); + .waitFor({ state: 'visible', timeout: Wait.OneMinute }); await expect(this.upgradeModal.elements.upgradeSuccess) - .toHaveText(this.upgradeModal.messages.upgradeSuccess(availableVersion) as string, { timeout: Duration.TenMinutes }); + .toHaveText(this.upgradeModal.messages.upgradeSuccess(availableVersion) as string, { timeout: Wait.TenMinutes }); await this.upgradeModal.buttons.close.click(); }; } diff --git a/playwright-tests/pages/page-components/pmm-upgrade-panel.ts b/playwright-tests/pages/page-components/pmm-upgrade-panel.ts index f11a6667b..e5f3fc614 100644 --- a/playwright-tests/pages/page-components/pmm-upgrade-panel.ts +++ b/playwright-tests/pages/page-components/pmm-upgrade-panel.ts @@ -1,12 +1,10 @@ import { expect, Page } from '@playwright/test'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; export default class PmmUpgrade { constructor(readonly page: Page) {} - containers = { - upgradeContainer: this.page.locator('//*[@aria-label="PMM Upgrade panel"]'), - }; + containers = { upgradeContainer: this.page.locator('//*[@aria-label="PMM Upgrade panel"]') }; elements: any = { currentVersion: this.containers.upgradeContainer.getByTestId('update-installed-version'), @@ -15,21 +13,21 @@ export default class PmmUpgrade { lastUpgradeCheckDate: this.containers.upgradeContainer.getByTestId('update-last-check'), }; - buttons = { - upgradeButton: this.containers.upgradeContainer.getByText('Upgrade to', { exact: false }), - }; + buttons = { upgradeButton: this.containers.upgradeContainer.getByText('Upgrade to', { exact: false }) }; fields = {}; getPMMVersion = async (versionString: string) => { const [versionMajor, versionMinor, versionPatch] = versionString.split('.'); - return { versionMajor, versionMinor, versionPatch }; + return { + versionMajor, versionMinor, versionPatch, + }; }; getCurrentPMMVersion = async () => { - await expect(this.elements.currentVersion).toContainText('2.', { timeout: Duration.ThreeMinutes }); + await expect(this.elements.currentVersion).toContainText('2.', { timeout: Wait.ThreeMinutes }); const versionString = await this.elements.currentVersion.textContent(); - const [versionMajorString, versionMinorString, versionPatchString] = versionString!.split('.'); + const [versionMajorString, versionMinorString, versionPatchString] = versionString.split('.'); const versions = { versionMajor: parseInt(versionMajorString), versionMinor: parseInt(versionMinorString), @@ -40,10 +38,10 @@ export default class PmmUpgrade { }; verifyUpgradeWidget = async () => { - await this.buttons.upgradeButton.waitFor({ state: 'visible', timeout: Duration.ThreeMinutes }); + await this.buttons.upgradeButton.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); await expect(this.elements.upToDate).toBeHidden(); await this.elements.lastUpgradeCheckDate.waitFor({ state: 'visible' }); const availableVersion = await this.elements.availableVersion.textContent(); - await expect(this.elements.currentVersion).not.toHaveText(availableVersion!); + await expect(this.elements.currentVersion).not.toHaveText(availableVersion); }; } diff --git a/playwright-tests/pages/page-components/toast-message-modal.ts b/playwright-tests/pages/page-components/toast-message-modal.ts new file mode 100644 index 000000000..60f3f51f6 --- /dev/null +++ b/playwright-tests/pages/page-components/toast-message-modal.ts @@ -0,0 +1,45 @@ +import { Page, expect } from '@playwright/test'; +import Wait from '@helpers/enums/wait'; + +export default class ToastMessage { + constructor(readonly page: Page) { } + + toast = this.page.locator('//div[contains(@data-testid, "Alert") or contains(@aria-label, "Alert")]'); + toastSuccess = this.page.locator('//div[@data-testid="data-testid Alert success" or @aria-label="Alert success"]'); + toastWarning = this.page.locator('//div[@data-testid="data-testid Alert warning" or @aria-label="Alert warning"]'); + toastError = this.page.locator('//div[@data-testid="data-testid Alert error" or @aria-label="Alert error"]'); + + messageText = this.page.locator('.page-alert-list div[data-testid^="data-testid Alert"] > div'); + closeButton = this.page.locator('.page-alert-list button'); + + // closeButton = (selectedToast: Locator) => selectedToast.locator('//*[@aria-label="Close alert" or @type="button"]'); + + private selectToast = (variant?: string) => { + switch (variant) { + case 'success': + return this.toastSuccess; + case 'warning': + return this.toastWarning; + case 'error': + return this.toastError; + default: + return this.toast; + } + }; + + waitForMessage = async (message: string, timeout?: number) => { + await this.messageText.waitFor({ state: 'visible', timeout: timeout || Wait.ToastMessage }); + await expect(this.messageText, `Waiting for Toast message with text "${message}"`) + .toHaveText(message, { timeout: Wait.OneSecond }); + await this.closeButton.click(); + await this.messageText.waitFor({ state: 'detached', timeout: Wait.TwoSeconds }); + }; + + waitForMessageContains = async (message: string, timeout?: number) => { + await this.messageText.waitFor({ state: 'visible', timeout: timeout || Wait.ToastMessage }); + await expect(this.messageText, `Waiting for Toast message containing "${message}"`) + .toContainText(message, { timeout: Wait.OneSecond }); + await this.closeButton.click(); + await this.messageText.waitFor({ state: 'detached', timeout: Wait.TwoSeconds }); + }; +} diff --git a/playwright-tests/pages/page-components/toast.ts b/playwright-tests/pages/page-components/toast.ts deleted file mode 100644 index 74bb3bacd..000000000 --- a/playwright-tests/pages/page-components/toast.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Page, expect, Locator } from '@playwright/test'; -import config from '@root/playwright.config'; - -export class Toast { - constructor(readonly page: Page) { } - - toast = this.page.locator('//div[contains(@data-testid, "Alert") or contains(@aria-label, "Alert")]'); - toastSuccess = this.page.locator('//div[@data-testid="data-testid Alert success" or @aria-label="Alert success"]'); - toastWarning = this.page.locator('//div[@data-testid="data-testid Alert warning" or @aria-label="Alert warning"]'); - toastError = this.page.locator('//div[@data-testid="data-testid Alert error" or @aria-label="Alert error"]'); - closeButton = (selectedToast: Locator) => selectedToast.locator('//*[@aria-label="Close alert" or @type="button"]'); - - private selectToast = (variant?: string) => { - switch (variant) { - case 'success': - return this.toastSuccess; - case 'warning': - return this.toastWarning; - case 'error': - return this.toastError; - default: - return this.toast; - } - }; - - checkToastMessage = async ( - message: string, - options?: { timeout?: number; variant?: 'success' | 'warning' | 'error', assertionTimeout?: number }, - ) => { - const selectedToast: Locator = this.selectToast(options?.variant); - - await selectedToast.waitFor({ state: 'visible', timeout: options?.timeout || 30000 }); - await expect(selectedToast).toHaveText(message, { timeout: options?.assertionTimeout || config.expect?.timeout }); - await this.closeButton(selectedToast).click(); - await selectedToast.waitFor({ state: 'detached' }); - }; - - checkToastMessageContains = async ( - message: string, - options?: { timeout?: number; variant?: 'success' | 'warning' | 'error', assertionTimeout?: number }, - ) => { - const selectedToast: Locator = this.selectToast(options?.variant); - - await selectedToast.waitFor({ state: 'visible', timeout: options?.timeout }); - await expect(selectedToast).toContainText(message, { timeout: options?.assertionTimeout || config.expect?.timeout }); - await this.closeButton(selectedToast).click(); - await selectedToast.waitFor({ state: 'detached' }); - }; -} diff --git a/playwright-tests/pages/pmm-settings/percona-platform.page.ts b/playwright-tests/pages/pmm-settings/percona-platform.page.ts index f0ecf693b..25c2c1eb5 100644 --- a/playwright-tests/pages/pmm-settings/percona-platform.page.ts +++ b/playwright-tests/pages/pmm-settings/percona-platform.page.ts @@ -92,9 +92,9 @@ export default class PerconaPlatformPage extends CommonPage { await this.buttons.connect.click(); if (!isIPAddressSet) { - await this.toast.checkToastMessage(this.messages.updateSuccess); + await this.toastMessage.waitForMessage(this.messages.updateSuccess); } - await this.toast.checkToastMessage(this.messages.connectedSuccess, { variant: 'success' }); + await this.toastMessage.waitForMessage(this.messages.connectedSuccess); await this.connectedContainer.waitFor({ state: 'visible' }); }; } diff --git a/playwright-tests/pages/serverAdmin/NewUser.page.ts b/playwright-tests/pages/serverAdmin/NewUser.page.ts index b26e2c61f..6c261c93b 100644 --- a/playwright-tests/pages/serverAdmin/NewUser.page.ts +++ b/playwright-tests/pages/serverAdmin/NewUser.page.ts @@ -10,14 +10,9 @@ export class NewUserPage extends CommonPage { password: this.page.locator('//*[@id="password-input"]'), }; - buttons = { - createUser: this.page.locator('//*[@type="submit"]') - }; + buttons = { createUser: this.page.locator('//*[@type="submit"]') }; - messages: any = { - ...this.messages, - userCreated: 'User created', - }; + messages = { userCreated: 'User created' }; fillUserDetails = async (name: string, email: string, username: string, password: string) => { await this.fields.name.type(name); @@ -29,6 +24,6 @@ export class NewUserPage extends CommonPage { createUser = async (name: string, email: string, username: string, password: string) => { await this.fillUserDetails(name, email, username, password); await this.buttons.createUser.click(); - await this.toast.checkToastMessage(this.messages.userCreated, { variant: 'success' }); + await this.toastMessage.waitForMessage(this.messages.userCreated); }; } diff --git a/playwright-tests/playwright.config.ts b/playwright-tests/playwright.config.ts index fa95dcafc..975d7d315 100644 --- a/playwright-tests/playwright.config.ts +++ b/playwright-tests/playwright.config.ts @@ -1,7 +1,7 @@ import type { PlaywrightTestConfig } from '@playwright/test'; import { devices } from '@playwright/test'; import * as dotenv from 'dotenv'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; /** * Read environment variables from file. @@ -12,11 +12,11 @@ dotenv.config({ path: '.env.local' }); const config: PlaywrightTestConfig = { testDir: './tests', - timeout: Duration.FiveMinutes, - expect: { timeout: 10_000 }, + timeout: Wait.FiveMinutes, + expect: { timeout: Wait.TenSeconds }, fullyParallel: false, forbidOnly: !!process.env.CI, - retries: process.env.CI ? 1 : 0, + retries: 0, workers: 1, reporter: [ ['list'], @@ -32,9 +32,9 @@ const config: PlaywrightTestConfig = { }, projects: [ { - name: 'chromium', - testDir: './tests', - testIgnore: 'tests/portal/*.spec.ts', + name: 'Chromium', + testMatch: 'tests/**/*.spec.ts', + testIgnore: 'tests/portal/*.ts', use: { contextOptions: { ignoreHTTPSErrors: true }, screenshot: 'on', diff --git a/playwright-tests/tests/configuration/pages/create-role.page.ts b/playwright-tests/tests/configuration/pages/create-role.page.ts index 53ae6bc9f..235a020ff 100644 --- a/playwright-tests/tests/configuration/pages/create-role.page.ts +++ b/playwright-tests/tests/configuration/pages/create-role.page.ts @@ -26,9 +26,7 @@ export class CreateRolePage extends CommonPage { selectValue: this.metricsAccessRowContainer.locator('//*[@id="prometheus-dimensions-filter-item-value"]'), }; - buttons = { - submit: this.page.getByTestId('add-edit-role-submit'), - }; + buttons = { submit: this.page.getByTestId('add-edit-role-submit') }; messages: any = { ...this.messages, @@ -52,8 +50,7 @@ export class CreateRolePage extends CommonPage { await this.fields.selectValue.click(); await this.elements.menuOption(options.value).click(); await this.buttons.submit.click(); - await this.toast.checkToastMessage( - `${this.messages.roleCreatedHeader(options.roleName)}${this.messages.roleCreatedDescription}`, - ); + await this.toastMessage + .waitForMessage(`${this.messages.roleCreatedHeader(options.roleName)}${this.messages.roleCreatedDescription}`); }; } diff --git a/playwright-tests/tests/inventory/inventory.spec.ts b/playwright-tests/tests/inventory/inventory.spec.ts index a92a42eb6..da8050da1 100644 --- a/playwright-tests/tests/inventory/inventory.spec.ts +++ b/playwright-tests/tests/inventory/inventory.spec.ts @@ -3,7 +3,7 @@ import apiHelper from '@api/helpers/api-helper'; import { NodeDetails } from '@tests/inventory/pages/components/nodes-table'; import { ServiceDetails } from '@tests/inventory/pages/components/services-table'; import cli from '@helpers/cli'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import grafanaHelper from '@helpers/grafana-helper'; import { api } from '@api/api'; @@ -44,9 +44,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { }); test('PMM-T1669 Verify PMM Inventory redesign : Layout & Services' - + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ - page, homeDashboardPage, servicesPage, mongoDBInstanceSummary, qanPage, - }) => { + + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ page, homeDashboardPage, servicesPage, mongoDBInstanceSummary, qanPage }) => { test.skip(pmmVersion < 37, 'Test is for versions 2.37.0+'); await test.step('1. Verify navigation to the Inventory page.', async () => { @@ -88,9 +86,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { }); test('PMM-T1226 Verify Agents has process_exec_path option on Inventory page' - + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ - page, servicesPage, - }) => { + + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ page, servicesPage }) => { test.skip(pmmVersion < 37, 'Test is for versions 2.37.0+'); await test.step('1. Navigate to the Inventory page.', async () => { @@ -112,9 +108,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { }); test('PMM-T554 Check that all agents have status "RUNNING"' - + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ - page, servicesPage, nodesPage, - }) => { + + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ page, servicesPage, nodesPage }) => { test.info().annotations.push({ type: 'Also Covers', description: 'PMM-T342 Verify pmm-server node cannot be removed from PMM Inventory page', @@ -125,9 +119,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { await test.step('1. Go to services page and and verify mysql database is present.', async () => { await page.goto(servicesPage.url); - await servicesPage.servicesTable.elements.rowByText(psLocalService.serviceName).waitFor({ - state: 'visible', - }); + await servicesPage.servicesTable.elements.rowByText(psLocalService.serviceName).waitFor({ state: 'visible' }); }); await test.step('2. Verify pagination on the services table.', async () => { @@ -167,24 +159,17 @@ test.describe('Spec file for PMM inventory tests.', async () => { await nodesPage.elements.deleteButton.click(); await nodesPage.confirmDeleteModal.buttons.force.check({ force: true }); await nodesPage.confirmDeleteModal.buttons.proceed.click(); - await nodesPage.toast.checkToastMessage( - nodesPage.messages.pmmServerCannotBeRemoved, - { variant: 'error' }, - ); + await nodesPage.toastMessage.waitForMessage(nodesPage.messages.pmmServerCannotBeRemoved); await nodesPage.page.reload(); await nodesPage.nodesTable.elements.rowByText('pmm-server').waitFor({ state: 'visible' }); }); }); test('PMM-T345 Verify removing pmm-agent on PMM Inventory page removes all associated agents' - + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ - page, servicesPage, nodesPage, - }) => { + + ' @inventory @inventory-pre-upgrade @inventory-post-upgrade', async ({ page, servicesPage, nodesPage }) => { await test.step('1. Go to services page and and verify postgres database is present.', async () => { await page.goto(servicesPage.url); - await servicesPage.servicesTable.elements.rowByText(pdpgsqlLocalService.serviceName).waitFor({ - state: 'visible', - }); + await servicesPage.servicesTable.elements.rowByText(pdpgsqlLocalService.serviceName).waitFor({ state: 'visible' }); }); await test.step('2. Navigate to the agent for the pdpgsql database.', async () => { @@ -198,7 +183,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { await servicesPage.agentsTable.buttons.delete.click(); await nodesPage.confirmDeleteModal.buttons.force.check({ force: true }); await servicesPage.confirmDeleteModal.buttons.proceed.click(); - await servicesPage.toast.checkToastMessage(servicesPage.agentsTable.messages.successfullyDeleted(1) as string); + await servicesPage.toastMessage.waitForMessage(servicesPage.agentsTable.messages.successfullyDeleted(1) as string); await expect(servicesPage.elements.noDataTable).toHaveText(servicesPage.agentsTable.messages.noAgents as string); }); @@ -225,9 +210,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { const psContainerName = containerNames.find((container: string | string[]) => container.includes('ps_integration_')) || ''; const pdpgsqlContainerName = containerNames.find((container: string | string[]) => container.includes('pdpgsql-integration-')) || ''; - await cli.pmmClientCommands.addMongoDb({ - address: process.env.CI ? '127.0.0.1' : mongoContainerName, name: mongoContainerName, - }); + await cli.pmmClientCommands.addMongoDb({ address: process.env.CI ? '127.0.0.1' : mongoContainerName, name: mongoContainerName }); await cli.pmmClientCommands.addMySql({ address: process.env.CI ? '127.0.0.1' : psContainerName, name: psContainerName, port: process.env.CI ? 43306 : 3306, }); @@ -243,9 +226,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { await test.step('1. Go to services page and and verify mysql database is present.', async () => { await page.goto(servicesPage.url); - await servicesPage.servicesTable.elements.rowByText(psLocalService.serviceName).waitFor({ - state: 'visible', - }); + await servicesPage.servicesTable.elements.rowByText(psLocalService.serviceName).waitFor({ state: 'visible' }); }); await test.step('2. Select MySql options and verify all agents are running.', async () => { @@ -258,7 +239,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { await servicesPage.agentsTable.elements.checkbox('Mysqld exporter').check({ force: true }); await servicesPage.agentsTable.buttons.delete.click(); await servicesPage.confirmDeleteModal.buttons.proceed.click(); - await servicesPage.toast.checkToastMessage(servicesPage.agentsTable.messages.successfullyDeleted(1) as string); + await servicesPage.toastMessage.waitForMessage(servicesPage.agentsTable.messages.successfullyDeleted(1) as string); await servicesPage.buttons.goBackToServices.click(); await servicesPage.servicesTable.buttons.showRowDetails(psLocalService.serviceName).click(); await expect(servicesPage.servicesTable.elements.agentStatus).toHaveText('3/3 running'); @@ -310,22 +291,15 @@ test.describe('Spec file for PMM inventory tests.', async () => { await expect(nodesPage.confirmDeleteModal.elements.modalHeader) .toHaveText(nodesPage.confirmDeleteModal.messages.confirmNodeDeleteHeader() as string); await nodesPage.confirmDeleteModal.buttons.proceed.click(); - await nodesPage.toast.checkToastMessage( - nodesPage.nodesTable.messages.hasAgents(nodeDetails.nodeId).replace('\n', '') as string, - { variant: 'error' }, - ); + await nodesPage.toastMessage + .waitForMessage(nodesPage.nodesTable.messages.hasAgents(nodeDetails.nodeId).replace('\n', '') as string); }); await test.step('4. Force delete the node.', async () => { await nodesPage.elements.deleteButton.click(); await nodesPage.confirmDeleteModal.buttons.force.check({ force: true }); await nodesPage.confirmDeleteModal.buttons.proceed.click(); - await nodesPage.toast.checkToastMessage( - nodesPage.nodesTable.messages.nodesSuccessfullyDeleted(1) as string, - { - variant: 'success', assertionTimeout: Duration.OneSecond, - }, - ); + await nodesPage.toastMessage.waitForMessage(nodesPage.nodesTable.messages.nodesSuccessfullyDeleted(1) as string, Wait.OneSecond); await nodesPage.nodesTable.verifyTableDoesNotContain(nodeDetails.nodeId as string); await nodesPage.nodesTable.verifyTableDoesNotContain(nodeDetails.nodeName as string); }); @@ -342,9 +316,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { const psContainerName = containers.find((container: string | string[]) => container.includes('ps_integration_')) || ''; const pdpgsqlContainerName = containers.find((container: string | string[]) => container.includes('pdpgsql-integration-')) || ''; - await cli.pmmClientCommands.addMongoDb({ - address: process.env.CI ? '127.0.0.1' : mongoContainerName, name: mongoContainerName, - }); + await cli.pmmClientCommands.addMongoDb({ address: process.env.CI ? '127.0.0.1' : mongoContainerName, name: mongoContainerName }); await cli.pmmClientCommands.addMySql({ address: process.env.CI ? '127.0.0.1' : psContainerName, name: psContainerName, port: process.env.CI ? 43306 : 3306, }); @@ -364,9 +336,7 @@ test.describe('Spec file for PMM inventory tests.', async () => { await test.step('1. Navigate to the Inventory page and expand Mongo service".', async () => { await page.goto(servicesPage.url); - await servicesPage.servicesTable.elements.rowByText(mongoLocalService.serviceName).waitFor({ - state: 'visible', - }); + await servicesPage.servicesTable.elements.rowByText(mongoLocalService.serviceName).waitFor({ state: 'visible' }); await servicesPage.servicesTable.verifyAllMonitoring('OK'); await servicesPage.servicesTable.buttons.showRowDetails(mongoLocalService.serviceName).click(); await expect(servicesPage.servicesTable.elements.agentStatus).toHaveText('4/4 running'); @@ -459,17 +429,15 @@ test.describe('Spec file for PMM inventory tests.', async () => { await servicesPage.servicesTable.buttons.selectService(psLocalService.serviceName).check({ force: true }); await servicesPage.elements.deleteButton.click(); await servicesPage.confirmDeleteModal.buttons.proceed.click(); - await servicesPage.toast.checkToastMessage(servicesPage.confirmDeleteModal.messages.serviceHasAgents(serviceId) as string); + await servicesPage.toastMessage.waitForMessage(servicesPage.confirmDeleteModal.messages.serviceHasAgents(serviceId) as string); }); await test.step('4. Force Delete MySql service.', async () => { await servicesPage.elements.deleteButton.click(); await servicesPage.confirmDeleteModal.buttons.force.check({ force: true }); await servicesPage.confirmDeleteModal.buttons.proceed.click(); - await servicesPage.toast.checkToastMessage(servicesPage.servicesTable.messages.successfullyDeleted(1) as string); - await servicesPage.servicesTable.elements.rowByText(psLocalService.serviceName).waitFor({ - state: 'detached', - }); + await servicesPage.toastMessage.waitForMessage(servicesPage.servicesTable.messages.successfullyDeleted(1) as string); + await servicesPage.servicesTable.elements.rowByText(psLocalService.serviceName).waitFor({ state: 'detached' }); }); }); }); diff --git a/playwright-tests/tests/portal/connectPmm.spec.ts b/playwright-tests/tests/portal/connectPmm.spec.ts index 117b803fe..f99bbb7ed 100644 --- a/playwright-tests/tests/portal/connectPmm.spec.ts +++ b/playwright-tests/tests/portal/connectPmm.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from '@helpers/test-helper'; import apiHelper from '@api/helpers/api-helper'; import { portalApi } from '@api/portal.api'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import { PortalUser } from '@helpers/types/portal-user.class'; import { api } from '@api/api'; import { portalHelper } from '@helpers/portal-helper'; @@ -76,7 +76,7 @@ test.describe('Spec file for connecting PMM to the portal', async () => { await perconaPlatformPage.fields.email.type(firstAdmin.email); await perconaPlatformPage.fields.password.type(firstAdmin.password); await perconaPlatformPage.buttons.connect.click(); - await perconaPlatformPage.toast.checkToastMessage(perconaPlatformPage.messages.oldPmmVersionError); + await perconaPlatformPage.toastMessage.waitForMessage(perconaPlatformPage.messages.oldPmmVersionError); }, ); @@ -110,7 +110,7 @@ test.describe('Spec file for connecting PMM to the portal', async () => { await loginPage.open(); await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); await homeDashboardPage.pmmUpgrade.containers.upgradeContainer - .waitFor({ state: 'visible', timeout: Duration.OneMinute }); + .waitFor({ state: 'visible', timeout: Wait.OneMinute }); await expect(loginPage.page).toHaveURL(`${baseURL}/${loginPage.landingUrl}`); await context.clearCookies(); await loginPage.page.reload(); @@ -118,7 +118,7 @@ test.describe('Spec file for connecting PMM to the portal', async () => { await test.step('1. Login as admin user that was invited to the org.', async () => { await loginPage.oktaLogin(secondAdmin.email, secondAdmin.password); - await homeDashboardPage.pmmUpgrade.containers.upgradeContainer.waitFor({ state: 'visible', timeout: Duration.OneMinute }); + await homeDashboardPage.pmmUpgrade.containers.upgradeContainer.waitFor({ state: 'visible', timeout: Wait.OneMinute }); await expect(loginPage.page).toHaveURL(`${baseURL}/${loginPage.landingUrl}`); await context.clearCookies(); await loginPage.page.reload(); @@ -127,7 +127,7 @@ test.describe('Spec file for connecting PMM to the portal', async () => { await test.step('1. Login as technical user that was invited to the org.', async () => { await loginPage.oktaLogin(technicalUser.email, technicalUser.password); await homeDashboardPage.pmmUpgrade.containers.upgradeContainer - .waitFor({ state: 'visible', timeout: Duration.OneMinute }); + .waitFor({ state: 'visible', timeout: Wait.OneMinute }); await expect(loginPage.page).toHaveURL(`${baseURL}/${loginPage.landingUrl}`); await context.clearCookies(); await loginPage.page.reload(); diff --git a/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts b/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts index f935283a0..48994bbd7 100644 --- a/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts +++ b/playwright-tests/tests/portal/pmmPortalUpgrade.spec.ts @@ -1,14 +1,12 @@ import { test } from '@playwright/test'; import apiHelper from '@api/helpers/api-helper'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import HomeDashboardPage from '@pages/home-dashboard.page'; import grafanaHelper from '@helpers/grafana-helper'; import { api } from '@api/api'; test.describe('Spec file for PMM connected the portal', async () => { - test.describe.configure({ - retries: 0, - }); + test.describe.configure({ retries: 0 }); let pmmVersion: number; test.beforeAll(async () => { @@ -23,13 +21,11 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test('Verify user is able to Upgrade PMM version @not-ui-pipeline @pmm-portal-upgrade', async ({ page }) => { - test.setTimeout(Duration.TwentyMinutes); + test.setTimeout(Wait.TwentyMinutes); const homeDashboard = new HomeDashboardPage(page); await grafanaHelper.authorize(page); - await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboard.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); const currentVersion = await homeDashboard.pmmUpgrade.elements.currentVersion.textContent(); const availableVersion = await homeDashboard.pmmUpgrade.elements.availableVersion.textContent(); diff --git a/playwright-tests/tests/portal/postPmmConnect.spec.ts b/playwright-tests/tests/portal/postPmmConnect.spec.ts index e1566dbd5..42b532539 100644 --- a/playwright-tests/tests/portal/postPmmConnect.spec.ts +++ b/playwright-tests/tests/portal/postPmmConnect.spec.ts @@ -2,7 +2,7 @@ import { expect, test } from '@helpers/test-helper'; import apiHelper from '@api/helpers/api-helper'; import { PortalUser } from '@helpers/types/portal-user.class'; import { fileHelper } from '@helpers/file-helper'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import grafanaHelper from '@helpers/grafana-helper'; import { api } from '@api/api'; import { portalHelper } from '@helpers/portal-helper'; @@ -40,15 +40,11 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test.skip('PMM-T1149 PMM-T1132 Verify PMM user logged in using SSO and member of SN account is able to see tickets' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, loginPage, homeDashboardPage, ticketsPage, context, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, loginPage, homeDashboardPage, ticketsPage, context }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); }); await test.step('2. Verify that there is a side menu for organizational tickets', async () => { @@ -56,23 +52,17 @@ test.describe('Spec file for PMM connected the portal', async () => { }); await test.step('3. Verify user can see tickets for his org.', async () => { - await ticketsPage.elements.table.waitFor({ - state: 'visible', - }); + await ticketsPage.elements.table.waitFor({ state: 'visible' }); await expect(ticketsPage.elements.rows).toHaveCount(1); const [newPage] = await Promise.all([context.waitForEvent('page'), ticketsPage.elements.row(0).click()]); - await newPage.getByRole('main').waitFor({ - state: 'visible', - }); + await newPage.getByRole('main').waitFor({ state: 'visible' }); expect(newPage.url()).toContain(ticketsPage.serviceNowUrl); await newPage.close(); }); await test.step('4. Verify user can see empty list of tickets for his org.', async () => { - await apiHelper.interceptBackEndCall(page, '**/v1/Platform/SearchOrganizationTickets', { - tickets: [], - }); + await apiHelper.interceptBackEndCall(page, '**/v1/Platform/SearchOrganizationTickets', { tickets: [] }); await page.reload(); await expect(ticketsPage.elements.noDataTable).toHaveText(ticketsPage.messages.noTicketsFound); }); @@ -85,15 +75,11 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test.skip('PMM-T1152 Verify user logged in using SSO and is a member of SN account is able to see Entitlements' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, loginPage, homeDashboardPage, entitlementsPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, loginPage, homeDashboardPage, entitlementsPage }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); }); await test.step('2. Verify that there is a side menu for Entitlements', async () => { @@ -106,9 +92,7 @@ test.describe('Spec file for PMM connected the portal', async () => { }); await test.step('4. Verify user can see empty list of entitlements for his org.', async () => { - await apiHelper.interceptBackEndCall(page, '**/v1/Platform/SearchOrganizationEntitlements', { - entitlements: [], - }); + await apiHelper.interceptBackEndCall(page, '**/v1/Platform/SearchOrganizationEntitlements', { entitlements: [] }); await page.reload(); await expect(entitlementsPage.elements.noData).toHaveText(entitlementsPage.messages.noEntitlements); }); @@ -121,28 +105,18 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test.skip('PMM-T1168 PMM-T1222 Verify user can see the contacts from Percona' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, loginPage, homeDashboardPage, environmentOverviewPage, context, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, loginPage, homeDashboardPage, environmentOverviewPage, context }) => { await context.grantPermissions(['clipboard-write', 'clipboard-read']); const userToken = await api.portal.getUserAccessToken(firstAdmin.email, firstAdmin.password); const contactsEmail = (await api.portal.getOrgDetails(userToken, firstAdmin.org!.id)).contacts.customer_success.email; if (pmmVersion >= 29) { await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); await homeDashboardPage.sideMenu.elements.environmentOverview.click(); - await environmentOverviewPage.elements.contactsHeader.waitFor({ - state: 'visible', - }); - await environmentOverviewPage.elements.contactsSubHeader.waitFor({ - state: 'visible', - }); - await environmentOverviewPage.elements.contactsName.waitFor({ - state: 'visible', - }); + await environmentOverviewPage.elements.contactsHeader.waitFor({ state: 'visible' }); + await environmentOverviewPage.elements.contactsSubHeader.waitFor({ state: 'visible' }); + await environmentOverviewPage.elements.contactsName.waitFor({ state: 'visible' }); await environmentOverviewPage.elements.emailIcon.click(); // eslint-disable-next-line @typescript-eslint/no-unsafe-return const clipboardContent = await page.evaluate(() => navigator.clipboard.readText()); @@ -157,21 +131,15 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test.skip('PMM-T1147 Verify PMM user that is not logged in with SSO can NOT see Tickets for organization' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, homeDashboardPage, ticketsPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, homeDashboardPage, ticketsPage }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { await grafanaHelper.authorize(page); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); }); await test.step('2. Verify that there is NO side menu for organizational tickets', async () => { - await homeDashboardPage.sideMenu.elements.tickets.waitFor({ - state: 'detached', - }); + await homeDashboardPage.sideMenu.elements.tickets.waitFor({ state: 'detached' }); }); await test.step('3. Verify user can NOT see tickets.', async () => { @@ -191,21 +159,15 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test.skip('PMM-T1154 Verify PMM user that is not logged in with SSO can NOT see Entitlements for organization' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, homeDashboardPage, entitlementsPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, homeDashboardPage, entitlementsPage }) => { if (pmmVersion > 27) { await test.step('1. Login to the connected pmm with local account', async () => { await grafanaHelper.authorize(page); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); }); await test.step('2. Verify that there is NO side menu for organizational Entitlements', async () => { - await homeDashboardPage.sideMenu.elements.entitlements.waitFor({ - state: 'detached', - }); + await homeDashboardPage.sideMenu.elements.entitlements.waitFor({ state: 'detached' }); }); await test.step('3. Verify user can NOT see Entitlements.', async () => { @@ -225,15 +187,11 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test.skip('PMM-T1170 Verify PMM user that is not logged in with SSO can NOT see Contacts for organization' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, homeDashboardPage, environmentOverviewPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, homeDashboardPage, environmentOverviewPage }) => { if (pmmVersion > 27) { await test.step('1. Login to the connected pmm with local account', async () => { await grafanaHelper.authorize(page); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); }); await test.step('1. Login to the connected pmm with local account', async () => { await page.goto(environmentOverviewPage.environmentOverviewUrl); @@ -249,15 +207,11 @@ test.describe('Spec file for PMM connected the portal', async () => { test.skip('PMM-T1148 Verify PMM user logged in using SSO and member of organization in Portal' + ' BUT not a SN account is NOT able to see Tickets' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - loginPage, homeDashboardPage, ticketsPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ loginPage, homeDashboardPage, ticketsPage }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { await loginPage.oktaLogin(freeUser.email, freeUser.password); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); }); await test.step('2. Verify that there is a side menu for organizational tickets', async () => { @@ -276,15 +230,11 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test.skip('PMM-T1153 Verify user logged in using SSO and is not a member of SN account is NOT able to see Entitlements' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - loginPage, homeDashboardPage, ticketsPage, entitlementsPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ loginPage, homeDashboardPage, ticketsPage, entitlementsPage }) => { if (pmmVersion > 27) { await test.step('1. Login to he connected pmm with SSO', async () => { await loginPage.oktaLogin(freeUser.email, freeUser.password); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); }); await test.step('2. Verify that there is a side menu for organizational Entitlements', async () => { await homeDashboardPage.sideMenu.elements.entitlements.click(); @@ -301,33 +251,23 @@ test.describe('Spec file for PMM connected the portal', async () => { }); test('PMM-T1204 PMM-T1112 Verify user can disconnect pmm from portal success flow' - + ' @portal @not-ui-pipeline @post-pmm-portal-upgrade', async ({ - page, loginPage, homeDashboardPage, perconaPlatformPage, - }) => { + + ' @portal @not-ui-pipeline @post-pmm-portal-upgrade', async ({ page, loginPage, homeDashboardPage, perconaPlatformPage }) => { if (pmmVersion > 27) { await loginPage.oktaLogin(firstAdmin.email, firstAdmin.password); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); await page.goto(perconaPlatformPage.PAGE_PATH); - await perconaPlatformPage.connectedContainer.waitFor({ - state: 'visible', - }); + await perconaPlatformPage.connectedContainer.waitFor({ state: 'visible' }); await perconaPlatformPage.buttons.disconnect.click(); if (pmmVersion >= 28) { await expect(perconaPlatformPage.elements.modalMessage).toHaveText(perconaPlatformPage.messages.disconnectWarning); await perconaPlatformPage.buttons.confirmDisconnect.click(); - await page.locator('//input[@name="user"]').waitFor({ - state: 'visible', - }); + await page.locator('//input[@name="user"]').waitFor({ state: 'visible' }); } else { - await perconaPlatformPage.toast.checkToastMessage(perconaPlatformPage.messages.pmmDisconnectedFromPortal); + await perconaPlatformPage.toastMessage.waitForMessage(perconaPlatformPage.messages.pmmDisconnectedFromPortal); } await grafanaHelper.authorize(page); - await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ - state: 'visible', timeout: Duration.ThreeMinutes, - }); + await homeDashboardPage.pmmUpgrade.elements.currentVersion.waitFor({ state: 'visible', timeout: Wait.ThreeMinutes }); await page.goto(perconaPlatformPage.PAGE_PATH); const adminToken = await api.portal.getUserAccessToken(firstAdmin.email, firstAdmin.password); @@ -341,17 +281,13 @@ test.describe('Spec file for PMM connected the portal', async () => { }); // Needs to be fixed in the future. test.skip('PMM-T1264 Verify that pmm admin user can force disconnect pmm from the portal' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, perconaPlatformPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, perconaPlatformPage }) => { test.skip(pmmVersion < 29, 'This test is for PMM version 2.29.0 and higher'); await test.step('1. Login into the pmm and navigate to the percona platform page.', async () => { await grafanaHelper.authorize(page); await page.goto(perconaPlatformPage.PAGE_PATH); - await perconaPlatformPage.connectedContainer.waitFor({ - state: 'visible', - }); + await perconaPlatformPage.connectedContainer.waitFor({ state: 'visible' }); }); await test.step('2. Force disconnect from the platform.', async () => { @@ -362,17 +298,13 @@ test.describe('Spec file for PMM connected the portal', async () => { }); await test.step('3. Verify that force disconnect was successful.', async () => { - await perconaPlatformPage.toast.checkToastMessage(perconaPlatformPage.messages.disconnectedSuccess); - await perconaPlatformPage.buttons.connect.waitFor({ - state: 'visible', - }); + await perconaPlatformPage.toastMessage.waitForMessage(perconaPlatformPage.messages.disconnectedSuccess); + await perconaPlatformPage.buttons.connect.waitFor({ state: 'visible' }); }); }); test.skip('PMM-T1247 Verify user cannot access platform functionality when PMM is not connected to the portal' - + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ - page, environmentOverviewPage, entitlementsPage, ticketsPage, - }) => { + + ' @not-ui-pipeline @portal @post-pmm-portal-upgrade', async ({ page, environmentOverviewPage, entitlementsPage, ticketsPage }) => { await grafanaHelper.authorize(page); await page.goto(environmentOverviewPage.environmentOverviewUrl); await expect(environmentOverviewPage.elements.notConnectedToPlatform).toHaveText( diff --git a/playwright-tests/tests/portal/testUsers.setup.ts b/playwright-tests/tests/portal/testUsers.setup.ts index bab283d0d..dc96a8136 100644 --- a/playwright-tests/tests/portal/testUsers.setup.ts +++ b/playwright-tests/tests/portal/testUsers.setup.ts @@ -21,7 +21,6 @@ setup('Setup Portal tests', async ({ baseURL }) => { expect(val, `Portal tests requires "serviceNow.${key}"!`).toBeTruthy(); }); }); - await setup.step('Add pmm-server settings', async () => { await api.pmm.settingsV1.changeSettings({ pmm_public_address: baseURL!.replace(/(^\w+:|^)\/\//, '') }); }); diff --git a/playwright-tests/tests/rbac/rbac.spec.ts b/playwright-tests/tests/rbac/rbac.spec.ts index 121c9161f..fcccb3e89 100644 --- a/playwright-tests/tests/rbac/rbac.spec.ts +++ b/playwright-tests/tests/rbac/rbac.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from '@helpers//test-helper'; import apiHelper from '@api/helpers/api-helper'; import grafanaHelper from '@helpers/grafana-helper'; -import Duration from '@helpers/enums/duration'; +import Wait from '@helpers/enums/wait'; import { api } from '@api/api'; import { ListRoles } from '@api/management.api'; import PmmVersion from '@helpers/types/pmm-version.class'; @@ -53,9 +53,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { await grafanaHelper.authorize(page); }); - test('PMM-T1573 Verify Access Roles tab on Configuration page @rbac @rbac-pre-upgrade', async ({ - homeDashboardPage, rbacPage, - }) => { + test('PMM-T1573 Verify Access Roles tab on Configuration page @rbac @rbac-pre-upgrade', async ({ homeDashboardPage, rbacPage }) => { test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); test.info().annotations.push({ type: 'Also Covers', @@ -79,9 +77,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); }); - test('PMM-T1580 Verify creating Access Role @rbac @rbac-pre-upgrade @rbac-post-upgrade', async ({ - page, rbacPage, createRolePage, - }) => { + test('PMM-T1580 Verify creating Access Role @rbac @rbac-pre-upgrade @rbac-post-upgrade', async ({ page, rbacPage, createRolePage }) => { test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); test.info().annotations.push({ type: 'Also Covers', @@ -145,7 +141,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { await usersConfigurationPage.usersTable.fields.accessRole('testUserRBAC@localhost').click(); await usersConfigurationPage.optionMenu.selectOption(roleName); await page.goto(mySqlDashboard.url); - await mySqlDashboard.waitForPanelToHaveData('Top MySQL Used Connections', 444, Duration.TenMinutes); + await mySqlDashboard.waitForPanelToHaveData('Top MySQL Used Connections', 444, Wait.TenMinutes); }); await test.step('3. Login as new user and verify that Node Dashboard does NOT show data.', async () => { @@ -161,9 +157,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); }); - test('PMM-T1599 Verify assigned role after upgrade @rbac @rbac-post-upgrade', async ({ - page, usersConfigurationPage, postgresqlInstancesOverviewDashboard, - }) => { + test('PMM-T1599 Verify assigned role after upgrade @rbac @rbac-post-upgrade', async ({ page, usersConfigurationPage, postgresqlInstancesOverviewDashboard }) => { test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); await test.step('1. Verify user role is assigned after upgrade.', async () => { @@ -179,9 +173,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); }); - test('PMM-T1585 Verify deleting Access role @rbac @rbac-post-upgrade', async ({ - page, rbacPage, usersConfigurationPage, - }) => { + test('PMM-T1585 Verify deleting Access role @rbac @rbac-post-upgrade', async ({ page, rbacPage, usersConfigurationPage }) => { test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); test.info().annotations.push({ type: 'Also Covers', @@ -203,12 +195,8 @@ test.describe('Spec file for Access Control (RBAC)', async () => { await page.goto(usersConfigurationPage.url); await usersConfigurationPage.usersTable.fields.accessRole(newUser.username).click(); await usersConfigurationPage.usersTable.fields.assignRole('Full access').click(); - await usersConfigurationPage.usersTable.fields.removeRole(newUser.username, roleName).click({ - force: true, - }); - await usersConfigurationPage.usersTable.fields.removeRole(newUser.username, roleName).click({ - force: true, - }); + await usersConfigurationPage.usersTable.fields.removeRole(newUser.username, roleName).click({ force: true }); + await usersConfigurationPage.usersTable.fields.removeRole(newUser.username, roleName).click({ force: true }); }); await test.step('3. Delete role and verify that role was successfully deleted.', async () => { @@ -216,17 +204,12 @@ test.describe('Spec file for Access Control (RBAC)', async () => { await rbacPage.rbacTable.elements.rowOptions(roleName).click(); await rbacPage.rbacTable.elements.delete.click(); await rbacPage.rbacTable.buttons.confirmAndDeleteRole.click(); - await rbacPage.toast.checkToastMessageContains( - rbacPage.rbacTable.messages.roleDeleted(roleName) as string, - { variant: 'success' }, - ); + await rbacPage.toastMessage.waitForMessageContains(rbacPage.rbacTable.messages.roleDeleted(roleName) as string); await expect(rbacPage.rbacTable.elements.body).not.toContainText(roleName); }); }); - test('PMM-T1652 Verify replacing the role while removing it @rbac @rbac-post-upgrade', async ({ - page, rbacPage, createRolePage, newUserPage, usersConfigurationPage, - }) => { + test('PMM-T1652 Verify replacing the role while removing it @rbac @rbac-post-upgrade', async ({ page, rbacPage, createRolePage, newUserPage, usersConfigurationPage }) => { test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); const newRoleName = `Replace Role Test Role ${Date.now()}`; @@ -270,9 +253,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { }); }); - test('PMM-T1668 Verify removing Access role for deleted user. @rbac @rbac-post-upgrade', async ({ - page, rbacPage, createRolePage, newUserPage, usersConfigurationPage, - }) => { + test('PMM-T1668 Verify removing Access role for deleted user. @rbac @rbac-post-upgrade', async ({ page, rbacPage, createRolePage, newUserPage, usersConfigurationPage }) => { test.info().annotations.push({ type: 'Also Covers', description: 'PMM-T1601 Verify Grafana Does not crash when filtering users from the admin page.', @@ -309,9 +290,7 @@ test.describe('Spec file for Access Control (RBAC)', async () => { await test.step('3. Search for non existing user, and verify page does not crash.', async () => { await usersConfigurationPage.elements.searchUserInput.type('NonExistingUser'); - await usersConfigurationPage.elements.deleteUserButton(deleteUser.email).waitFor({ - state: 'hidden', - }); + await usersConfigurationPage.elements.deleteUserButton(deleteUser.email).waitFor({ state: 'hidden' }); await expect(usersConfigurationPage.elements.usersTable).toBeVisible(); await usersConfigurationPage.elements.searchUserInput.clear(); }); @@ -330,50 +309,37 @@ test.describe('Spec file for Access Control (RBAC)', async () => { await expect(rbacPage.rbacTable.elements.confirmDeleteRoleBody) .toContainText(rbacPage.rbacTable.messages.deleteRoleBody as string); await rbacPage.rbacTable.buttons.confirmAndDeleteRole.click(); - await rbacPage.toast.checkToastMessageContains( - rbacPage.rbacTable.messages.roleDeleted(deleteUserRole) as string, - { variant: 'success' }, - ); + await rbacPage.toastMessage.waitForMessageContains(rbacPage.rbacTable.messages.roleDeleted(deleteUserRole) as string); }); }); - test('PMM-T1629 Verify re-enabling of the Access Control @rbac @rbac-post-upgrade', async ({ - page, homeDashboardPage, rbacPage, advancedSettingsPage, - }) => { + test('PMM-T1629 Verify re-enabling of the Access Control @rbac @rbac-post-upgrade', async ({ page, homeDashboardPage, rbacPage, advancedSettingsPage }) => { test.skip(await getPmmVersion() < 35, 'Test is for versions 2.35.0+'); await test.step('1.Navigate to the advanced settings and disable Access Control.', async () => { await page.goto(advancedSettingsPage.url); - await advancedSettingsPage.fields.accessControl.click({ - force: true, - }); + await advancedSettingsPage.fields.accessControl.click({ force: true }); await expect(advancedSettingsPage.fields.accessControl).not.toBeChecked(); await advancedSettingsPage.buttons.applyChanges.click(); }); await test.step('2. Verify Access Control is disabled.', async () => { await homeDashboardPage.sideMenu.elements.configuration.hover(); - await homeDashboardPage.sideMenu.configuration.buttons.rbac.waitFor({ - state: 'detached', - }); + await homeDashboardPage.sideMenu.configuration.buttons.rbac.waitFor({ state: 'detached' }); await page.goto(rbacPage.url); await expect(rbacPage.elements.emptyBlock).toHaveText(rbacPage.messages.featureDisabled); }); await test.step('3. Re-enable Access Control.', async () => { await page.goto(advancedSettingsPage.url); - await advancedSettingsPage.fields.accessControl.check({ - force: true, - }); + await advancedSettingsPage.fields.accessControl.check({ force: true }); await expect(advancedSettingsPage.fields.accessControl).toBeChecked(); await advancedSettingsPage.buttons.applyChanges.click(); }); await test.step('2. Verify Access Control is enabled.', async () => { await homeDashboardPage.sideMenu.elements.configuration.hover(); - await homeDashboardPage.sideMenu.configuration.buttons.rbac.waitFor({ - state: 'visible', - }); + await homeDashboardPage.sideMenu.configuration.buttons.rbac.waitFor({ state: 'visible' }); }); }); }); From 269b8101293d8c88633e4c396c0cf0a0693bc8f7 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Wed, 23 Aug 2023 23:22:51 +0200 Subject: [PATCH 17/20] PMM-7 fixed reports --- .github/workflows/pmm-ui-tests-matrix.yml | 2 +- .github/workflows/ui-tests-pipeline.yml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pmm-ui-tests-matrix.yml b/.github/workflows/pmm-ui-tests-matrix.yml index 0998773db..e2b7c7f9a 100644 --- a/.github/workflows/pmm-ui-tests-matrix.yml +++ b/.github/workflows/pmm-ui-tests-matrix.yml @@ -1,4 +1,4 @@ -name: PMM E2E Tests(Playwright) +name: PMM e2e Tests(Playwright) on: schedule: diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index 7e706bbe7..cf09e7444 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -120,7 +120,7 @@ jobs: steps: - name: Create status check - if: ${{ github.event_name != 'pull_request' }} + if: ${{ env.SHA != 'null' }} uses: percona-platform/github-status-action@v1 continue-on-error: true with: @@ -262,7 +262,7 @@ jobs: NODE_TLS_REJECT_UNAUTHORIZED: 0 - name: 'Create report name' - if: failure() && ${{ !!inputs.tags_for_playwright }} + if: ${{ failure() && !!inputs.tags_for_playwright }} run: | # TODO: add job id for matrix call job_tag=$(echo "${{ inputs.tags_for_playwright }}" | sed -e "s/-pre-upgrade//" -e "s/@//") @@ -271,7 +271,7 @@ jobs: echo "REPORT_NAME=$report_name" >> $GITHUB_ENV - name: Generate and Attach the report - if: failure() && ${{ inputs.tags_for_playwright != 'null' }} + if: ${{ failure() && !!inputs.tags_for_playwright }} uses: actions/upload-artifact@v3 with: name: ${{ env.REPORT_NAME }} @@ -286,7 +286,7 @@ jobs: result-encoding: string - name: Create status check - if: ${{ github.event_name != 'pull_request' && always() }} + if: ${{ always() && env.SHA != 'null' }} uses: percona-platform/github-status-action@v1 continue-on-error: true with: From 80b815063f9ff8b62eda8eb9593587f1d935ecf8 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Thu, 24 Aug 2023 00:00:58 +0200 Subject: [PATCH 18/20] PMM-7 fixed report name --- .github/workflows/ui-tests-pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/ui-tests-pipeline.yml index cf09e7444..f1cadea86 100644 --- a/.github/workflows/ui-tests-pipeline.yml +++ b/.github/workflows/ui-tests-pipeline.yml @@ -266,7 +266,7 @@ jobs: run: | # TODO: add job id for matrix call job_tag=$(echo "${{ inputs.tags_for_playwright }}" | sed -e "s/-pre-upgrade//" -e "s/@//") - report_name=${{ inputs.client_version }}"$job_tag"-report + report_name=${{ inputs.version_string || inputs.client_version }}-"$job_tag"-report echo $report_name echo "REPORT_NAME=$report_name" >> $GITHUB_ENV From 7cb195ea9f95257622890071de51b7b05900e9e2 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Thu, 24 Aug 2023 12:50:13 +0200 Subject: [PATCH 19/20] PMM-7 revert renaming --- .github/workflows/pmm-ui-tests-matrix.yml | 6 +++--- .../workflows/{ui-tests-pipeline.yml => pmm-ui-tests.yml} | 0 .github/workflows/portal-tests-matrix.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename .github/workflows/{ui-tests-pipeline.yml => pmm-ui-tests.yml} (100%) diff --git a/.github/workflows/pmm-ui-tests-matrix.yml b/.github/workflows/pmm-ui-tests-matrix.yml index e2b7c7f9a..201b3cd28 100644 --- a/.github/workflows/pmm-ui-tests-matrix.yml +++ b/.github/workflows/pmm-ui-tests-matrix.yml @@ -24,7 +24,7 @@ on: jobs: inventory: name: Inventory - uses: ./.github/workflows/ui-tests-pipeline.yml + uses: ./.github/workflows/pmm-ui-tests.yml secrets: inherit with: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} @@ -37,7 +37,7 @@ jobs: portal: name: Portal - uses: ./.github/workflows/ui-tests-pipeline.yml + uses: ./.github/workflows/pmm-ui-tests.yml secrets: inherit with: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} @@ -50,7 +50,7 @@ jobs: rbac: name: RBAC - uses: ./.github/workflows/ui-tests-pipeline.yml + uses: ./.github/workflows/pmm-ui-tests.yml secrets: inherit with: pmm_ui_tests_branch: ${{ github.event.inputs.pmm_ui_tests_branch || github.head_ref || 'main '}} diff --git a/.github/workflows/ui-tests-pipeline.yml b/.github/workflows/pmm-ui-tests.yml similarity index 100% rename from .github/workflows/ui-tests-pipeline.yml rename to .github/workflows/pmm-ui-tests.yml diff --git a/.github/workflows/portal-tests-matrix.yml b/.github/workflows/portal-tests-matrix.yml index 890a93c0a..3fa1c0b03 100644 --- a/.github/workflows/portal-tests-matrix.yml +++ b/.github/workflows/portal-tests-matrix.yml @@ -25,7 +25,7 @@ jobs: portal: name: 'Portal / Integration' - uses: ./.github/workflows/ui-tests-pipeline.yml + uses: ./.github/workflows/pmm-ui-tests.yml secrets: inherit needs: get_versions strategy: From caf11ffd643c94c9d544ef1ab5e1331bc63fc4a7 Mon Sep 17 00:00:00 2001 From: Vadym Yarosh Date: Thu, 24 Aug 2023 14:44:50 +0200 Subject: [PATCH 20/20] PMM-7 fixed toast message locator --- .../page-components/toast-message-modal.ts | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/playwright-tests/pages/page-components/toast-message-modal.ts b/playwright-tests/pages/page-components/toast-message-modal.ts index 60f3f51f6..cd31b59aa 100644 --- a/playwright-tests/pages/page-components/toast-message-modal.ts +++ b/playwright-tests/pages/page-components/toast-message-modal.ts @@ -4,29 +4,12 @@ import Wait from '@helpers/enums/wait'; export default class ToastMessage { constructor(readonly page: Page) { } - toast = this.page.locator('//div[contains(@data-testid, "Alert") or contains(@aria-label, "Alert")]'); toastSuccess = this.page.locator('//div[@data-testid="data-testid Alert success" or @aria-label="Alert success"]'); toastWarning = this.page.locator('//div[@data-testid="data-testid Alert warning" or @aria-label="Alert warning"]'); toastError = this.page.locator('//div[@data-testid="data-testid Alert error" or @aria-label="Alert error"]'); - - messageText = this.page.locator('.page-alert-list div[data-testid^="data-testid Alert"] > div'); + messageText = this.page.locator('.page-alert-list div[data-testid^="data-testid Alert"] div[id]'); closeButton = this.page.locator('.page-alert-list button'); - // closeButton = (selectedToast: Locator) => selectedToast.locator('//*[@aria-label="Close alert" or @type="button"]'); - - private selectToast = (variant?: string) => { - switch (variant) { - case 'success': - return this.toastSuccess; - case 'warning': - return this.toastWarning; - case 'error': - return this.toastError; - default: - return this.toast; - } - }; - waitForMessage = async (message: string, timeout?: number) => { await this.messageText.waitFor({ state: 'visible', timeout: timeout || Wait.ToastMessage }); await expect(this.messageText, `Waiting for Toast message with text "${message}"`)