From 2394477ef9b64f74746d3d19d21fa40237fb8f26 Mon Sep 17 00:00:00 2001 From: Phillip Rak Date: Mon, 4 Mar 2024 09:55:44 -0700 Subject: [PATCH 01/41] Target UMD runtime for extensions This explicitly targets `node_modules/vue/dist/vue.js` to ensure that Dashboard is always exposing the UMD builds of Vue to the `window` object (`shell/core/plugins-loader.js`). For more information on different builds that are available to us, see the vue documentation for explanation of different builds [^1] [^1]: https://v2.vuejs.org/v2/guide/installation#Explanation-of-Different-Builds Signed-off-by: Phillip Rak --- shell/vue.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/vue.config.js b/shell/vue.config.js index e02bfbe0e81..a049a7c1f14 100644 --- a/shell/vue.config.js +++ b/shell/vue.config.js @@ -378,7 +378,7 @@ module.exports = function(dir, _appConfig) { config.resolve.alias['@pkg'] = path.join(dir, 'pkg'); config.resolve.alias['./node_modules'] = path.join(dir, 'node_modules'); config.resolve.alias['@components'] = COMPONENTS_DIR; - config.resolve.alias['vue$'] = dev ? path.resolve(process.cwd(), 'node_modules', 'vue') : 'vue'; + config.resolve.alias['vue$'] = path.resolve(process.cwd(), 'node_modules', 'vue', 'dist', dev ? 'vue.js' : 'vue.min.js'); config.resolve.modules.push(__dirname); config.plugins.push(virtualModules); config.plugins.push(autoImport); From a67304d8e99229d1ea59505ceabf6239d448c0a6 Mon Sep 17 00:00:00 2001 From: Phillip Rak Date: Fri, 1 Mar 2024 12:59:41 -0700 Subject: [PATCH 02/41] Bump `UI_PLUGIN_API_VERSION` This bumps the `UI_PLUGIN_API_VERSION` to signal that upcoming changes to UI extensions will be incompatible with older versions of Dashboard. A version of 1.2.0 or higher will be required for extensions that utilize backported Vue 3 features that are available in Vue 2.7. Signed-off-by: Phillip Rak --- shell/config/uiplugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/config/uiplugins.js b/shell/config/uiplugins.js index e93351a6dda..adb7e5ceaf5 100644 --- a/shell/config/uiplugins.js +++ b/shell/config/uiplugins.js @@ -1,7 +1,7 @@ import semver from 'semver'; // Version of the plugin API supported -export const UI_PLUGIN_API_VERSION = '1.1.0'; +export const UI_PLUGIN_API_VERSION = '1.2.0'; export const UI_PLUGIN_HOST_APP = 'rancher-manager'; export const UI_PLUGIN_BASE_URL = '/api/v1/namespaces/cattle-ui-plugin-system/services/http:ui-plugin-operator:80/proxy'; From fa03653c2115af106b42119aa8696d9fe4585cc6 Mon Sep 17 00:00:00 2001 From: yonasberhe23 Date: Wed, 3 Apr 2024 10:03:22 -0700 Subject: [PATCH 03/41] automation: Backport e2e tests to 2.8 (#10552) * backport e2e tests to 2.8 --------- Co-authored-by: Yonas Berhe Co-authored-by: Giuseppe Leo Co-authored-by: Neil MacDougall --- .github/workflows/test.yaml | 80 ++++---- cypress.config.ts | 115 +++++------- .../agent-configuration-rke2-data.ts | 0 .../agent-configuration-rke2-payload.ts | 0 .../machine-deployments-edit.yml | 52 ++++++ .../machine-deployments.yml | 65 +++++++ .../cluster_management/machine-sets-edit.yml | 44 +++++ .../cluster_management/machine-sets.yml | 58 ++++++ .../cluster_management/machines-edit.yml | 33 ++++ .../cluster_management/machines.yml | 32 ++++ .../pod-security-admissions-payload.ts | 37 ++++ .../ResourceList/resource-list-masthead.po.ts | 4 + cypress/e2e/po/components/cru-resource.po.ts | 19 ++ .../po/components/ember/ember-accordion.po.ts | 1 - .../ember/ember-checkbox-input.po.ts | 19 ++ .../ember-form-pod-security-template.po.ts | 29 +++ .../ember/ember-form-rke-templates.po.ts | 16 ++ .../ember-modal-add-edit-cluster-driver.po.ts | 20 ++ .../ember-modal-add-edit-node-driver.po.ts | 20 ++ .../ember/ember-modal-add-node-template.po.ts | 33 ++++ .../e2e/po/components/ember/ember-modal.po.ts | 8 + .../po/components/ember/ember-select.po.ts | 25 +++ .../ember/ember-sortable-table.po.ts | 70 +++++++ cypress/e2e/po/components/labeled-input.po.ts | 9 +- cypress/e2e/po/components/loading.po.ts | 5 + cypress/e2e/po/components/resource-yaml.po.ts | 5 + cypress/e2e/po/components/shell.po.ts | 8 + .../e2e/po/components/sortable-table.po.ts | 8 + .../cluster-detail-rke2-amazon.po.ts | 11 ++ .../cluster-detail-rke2-azure.po.ts | 11 ++ .../cluster-detail.po.ts | 21 ++- .../e2e/po/edit/base-cloud-credentials.po.ts | 32 ++++ .../po/edit/cloud-credentials-amazon.po.ts | 16 ++ .../e2e/po/edit/cloud-credentials-azure.po.ts | 21 +++ cypress/e2e/po/edit/machine-deployments.po.ts | 21 +++ cypress/e2e/po/edit/machine-sets.po.ts | 21 +++ cypress/e2e/po/edit/machines.po.ts | 22 +++ .../e2e/po/edit/pod-security-admissions.po.ts | 49 +++++ .../cluster-create-rke1-amazonec2.po.ts | 53 ++++++ .../create/cluster-create-rke1-custom.po.ts | 27 ++- .../create/cluster-create-rke1.po.ts | 9 +- .../create/cluster-create-rke2-amazon.po.ts | 34 ++++ .../create/cluster-create-rke2-azure.po.ts | 34 ++++ .../create/cluster-create-rke2-custom.po.ts | 17 +- .../create/cluster-create.po.ts | 26 ++- .../edit/cluster-edit-generic.po.ts | 12 +- .../edit/cluster-edit-rke2-custom.po.ts | 12 +- .../import/cluster-import.po.ts | 2 +- .../tabs/basics-tab-rke2.po.ts | 17 ++ .../tabs/machine-pools-tab-rke2.po.ts | 17 ++ cypress/e2e/po/edit/resource-detail.po.ts | 4 + .../lists/catalog.cattle.io.clusterrepo.po.ts | 10 - .../e2e/po/lists/cloud-credentials-list.po.ts | 7 + .../po/lists/machine-deployments-list.po.ts | 15 ++ cypress/e2e/po/lists/machine-pools-list.po.ts | 7 + cypress/e2e/po/lists/machine-set-list.po.ts | 15 ++ cypress/e2e/po/lists/machines-list.po.ts | 7 + .../lists/pod-security-admissions-list.po.ts | 7 + .../provisioning.cattle.io.cluster.po.ts | 16 ++ .../cluster-manager/cloud-credentials.po.ts | 39 ++++ .../cluster-manager-list.po.ts | 9 +- .../cluster-manager/machine-deployments.po.ts | 44 +++++ .../pages/cluster-manager/machine-sets.po.ts | 45 +++++ .../po/pages/cluster-manager/machines.po.ts | 45 +++++ .../cluster-manager/node-templates.po.ts | 39 ++++ .../pod-security-admissions.po.ts | 39 ++++ .../pod-security-policy-templates.po.ts | 54 ++++++ .../pages/cluster-manager/rke-drivers.po.ts | 64 +++++++ .../pages/cluster-manager/rke-templates.po.ts | 48 +++++ cypress/e2e/po/pages/explorer/events.po.ts | 20 ++ cypress/e2e/po/pages/explorer/nodes.po.ts | 20 ++ cypress/e2e/po/pages/extensions.po.ts | 17 +- cypress/e2e/po/pages/get-support.po.ts | 63 +++++++ cypress/e2e/po/pages/home.po.ts | 2 +- cypress/e2e/po/pages/repositories.po.ts | 43 ----- .../e2e/po/side-bars/burger-side-menu.po.ts | 8 + .../e2e/tests/navigation/page-actions.spec.ts | 2 +- .../side-nav/main-side-menu.spec.ts | 12 +- .../side-nav/product-side-nav.spec.ts | 2 +- cypress/e2e/tests/pages/charts/istio.spec.ts | 2 +- .../tests/pages/charts/opa-gatekeeper.spec.ts | 2 +- .../e2e/tests/pages/charts/prometheus.spec.ts | 2 +- .../pages/explorer/api/api-services.spec.ts | 2 +- .../explorer/cluster-project-members.spec.ts | 2 +- .../{ => explorer}/project-namespace.spec.ts | 2 +- .../pages/explorer/storage/configmap.spec.ts | 2 +- .../explorer/workloads/deployments.spec.ts | 2 +- .../pages/explorer/workloads/jobs.spec.ts | 2 +- .../pages/explorer/workloads/pods.spec.ts | 4 +- .../explorer/workloads/workloads.spec.ts | 2 +- .../pages/{ => extensions}/extensions.spec.ts | 8 +- .../tests/pages/extensions/kubewarden.spec.ts | 6 +- .../e2e/tests/pages/fleet/dashboard.spec.ts | 2 +- .../tests/pages/fleet/fleet-clusters.spec.ts | 4 +- cypress/e2e/tests/pages/fleet/gitrepo.spec.ts | 2 +- .../tests/pages/{ => generic}/about.spec.ts | 2 +- .../pages/{ => generic}/diagnostic.spec.ts | 2 +- .../generic}/favicons.spec.ts | 2 +- .../tests/pages/generic/get-support.spec.ts | 83 +++++++++ .../tests/pages/{ => generic}/home.spec.ts | 33 ++-- .../index.spec.ts => generic/loading.spec.ts} | 2 +- .../tests/pages/{ => generic}/login.spec.ts | 2 +- .../generic}/not-found-page.spec.ts | 2 +- .../pages/global-settings/branding.spec.ts | 8 +- .../pages/global-settings/peformance.spec.ts | 2 +- .../agent-configuration-rke2.spec.ts | 8 +- .../pages/manager/cloud-credentials.spec.ts | 119 ++++++++++++ .../{ => manager}/cluster-manager.spec.ts | 129 ++++++++++++- ...uster-provisioning-amazon-ec2-rke2.spec.ts | 142 +++++++++++++++ .../cluster-provisioning-azure-rke2.spec.ts | 125 +++++++++++++ .../e2e/tests/pages/manager/drivers.spec.ts | 156 ++++++++++++++++ .../pages/manager/machine-deployments.spec.ts | 161 ++++++++++++++++ .../tests/pages/manager/machine-sets.spec.ts | 158 ++++++++++++++++ .../e2e/tests/pages/manager/machines.spec.ts | 119 ++++++++++++ .../pages/manager/node-templates.spec.ts | 150 +++++++++++++++ .../manager/pod-security-admissions.spec.ts | 142 +++++++++++++++ .../pod-security-policy-templates.spec.ts | 63 +++++++ .../pages/{ => manager}/registries.spec.ts | 2 +- .../tests/pages/manager/repositories.spec.ts | 123 ++++++++++++- .../tests/pages/manager/rke-templates.spec.ts | 107 +++++++++++ .../account-api-keys.spec.ts | 2 +- .../{user_menu => user-menu}/logout.spec.ts | 2 +- .../preferences.spec.ts | 34 ++-- .../tests/pages/users-and-auth/roles.spec.ts | 2 +- .../tests/pages/users-and-auth/users.spec.ts | 6 +- cypress/e2e/tests/setup/rancher-setup.spec.ts | 4 +- cypress/globals.d.ts | 98 +++++----- cypress/jenkins/Jenkinsfile | 102 ++++++----- cypress/jenkins/init.sh | 3 + cypress/support/commands/commands.ts | 3 + .../support/commands/rancher-api-commands.ts | 172 +++++++++++++++++- cypress/support/e2e.ts | 2 + docusaurus/docs/testing/e2e-test.md | 81 +++++++-- env.template | 2 +- package.json | 1 + scripts/__tests__/cypress.test.ts | 77 ++++++++ scripts/cypress.ts | 25 +++ shell/components/SortableTable/index.vue | 2 +- .../provisioning.cattle.io.cluster/Basics.vue | 1 + shell/machine-config/amazonec2.vue | 1 + yarn.lock | 5 + 141 files changed, 4096 insertions(+), 420 deletions(-) rename cypress/e2e/{tests/pages/data => blueprints/agent-configuration}/agent-configuration-rke2-data.ts (100%) rename cypress/e2e/{tests/pages/data => blueprints/agent-configuration}/agent-configuration-rke2-payload.ts (100%) create mode 100644 cypress/e2e/blueprints/cluster_management/machine-deployments-edit.yml create mode 100644 cypress/e2e/blueprints/cluster_management/machine-deployments.yml create mode 100644 cypress/e2e/blueprints/cluster_management/machine-sets-edit.yml create mode 100644 cypress/e2e/blueprints/cluster_management/machine-sets.yml create mode 100644 cypress/e2e/blueprints/cluster_management/machines-edit.yml create mode 100644 cypress/e2e/blueprints/cluster_management/machines.yml create mode 100644 cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts create mode 100644 cypress/e2e/po/components/ember/ember-checkbox-input.po.ts create mode 100644 cypress/e2e/po/components/ember/ember-form-pod-security-template.po.ts create mode 100644 cypress/e2e/po/components/ember/ember-form-rke-templates.po.ts create mode 100644 cypress/e2e/po/components/ember/ember-modal-add-edit-cluster-driver.po.ts create mode 100644 cypress/e2e/po/components/ember/ember-modal-add-edit-node-driver.po.ts create mode 100644 cypress/e2e/po/components/ember/ember-modal-add-node-template.po.ts create mode 100644 cypress/e2e/po/components/ember/ember-select.po.ts create mode 100644 cypress/e2e/po/components/ember/ember-sortable-table.po.ts create mode 100644 cypress/e2e/po/components/loading.po.ts create mode 100644 cypress/e2e/po/detail/provisioning.cattle.io.cluster/cluster-detail-rke2-amazon.po.ts create mode 100644 cypress/e2e/po/detail/provisioning.cattle.io.cluster/cluster-detail-rke2-azure.po.ts create mode 100644 cypress/e2e/po/edit/base-cloud-credentials.po.ts create mode 100644 cypress/e2e/po/edit/cloud-credentials-amazon.po.ts create mode 100644 cypress/e2e/po/edit/cloud-credentials-azure.po.ts create mode 100644 cypress/e2e/po/edit/machine-deployments.po.ts create mode 100644 cypress/e2e/po/edit/machine-sets.po.ts create mode 100644 cypress/e2e/po/edit/machines.po.ts create mode 100644 cypress/e2e/po/edit/pod-security-admissions.po.ts create mode 100644 cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke1-amazonec2.po.ts create mode 100644 cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke2-amazon.po.ts create mode 100644 cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke2-azure.po.ts create mode 100644 cypress/e2e/po/edit/provisioning.cattle.io.cluster/tabs/basics-tab-rke2.po.ts create mode 100644 cypress/e2e/po/edit/provisioning.cattle.io.cluster/tabs/machine-pools-tab-rke2.po.ts delete mode 100644 cypress/e2e/po/lists/catalog.cattle.io.clusterrepo.po.ts create mode 100644 cypress/e2e/po/lists/cloud-credentials-list.po.ts create mode 100644 cypress/e2e/po/lists/machine-deployments-list.po.ts create mode 100644 cypress/e2e/po/lists/machine-pools-list.po.ts create mode 100644 cypress/e2e/po/lists/machine-set-list.po.ts create mode 100644 cypress/e2e/po/lists/machines-list.po.ts create mode 100644 cypress/e2e/po/lists/pod-security-admissions-list.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/cloud-credentials.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/machine-deployments.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/machine-sets.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/machines.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/node-templates.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/pod-security-admissions.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/pod-security-policy-templates.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/rke-drivers.po.ts create mode 100644 cypress/e2e/po/pages/cluster-manager/rke-templates.po.ts create mode 100644 cypress/e2e/po/pages/explorer/events.po.ts create mode 100644 cypress/e2e/po/pages/explorer/nodes.po.ts create mode 100644 cypress/e2e/po/pages/get-support.po.ts delete mode 100644 cypress/e2e/po/pages/repositories.po.ts rename cypress/e2e/tests/pages/{ => explorer}/project-namespace.spec.ts (89%) rename cypress/e2e/tests/pages/{ => extensions}/extensions.spec.ts (96%) rename cypress/e2e/tests/pages/{ => generic}/about.spec.ts (98%) rename cypress/e2e/tests/pages/{ => generic}/diagnostic.spec.ts (91%) rename cypress/e2e/tests/{global-ui => pages/generic}/favicons.spec.ts (91%) create mode 100644 cypress/e2e/tests/pages/generic/get-support.spec.ts rename cypress/e2e/tests/pages/{ => generic}/home.spec.ts (88%) rename cypress/e2e/tests/pages/{loading_indicator/index.spec.ts => generic/loading.spec.ts} (81%) rename cypress/e2e/tests/pages/{ => generic}/login.spec.ts (94%) rename cypress/e2e/tests/{navigation => pages/generic}/not-found-page.spec.ts (97%) rename cypress/e2e/tests/pages/{ => manager}/agent-configuration-rke2.spec.ts (91%) create mode 100644 cypress/e2e/tests/pages/manager/cloud-credentials.spec.ts rename cypress/e2e/tests/pages/{ => manager}/cluster-manager.spec.ts (68%) create mode 100644 cypress/e2e/tests/pages/manager/cluster-provisioning-amazon-ec2-rke2.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/cluster-provisioning-azure-rke2.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/drivers.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/machine-deployments.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/machine-sets.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/machines.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/node-templates.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/pod-security-admissions.spec.ts create mode 100644 cypress/e2e/tests/pages/manager/pod-security-policy-templates.spec.ts rename cypress/e2e/tests/pages/{ => manager}/registries.spec.ts (98%) create mode 100644 cypress/e2e/tests/pages/manager/rke-templates.spec.ts rename cypress/e2e/tests/pages/{user_menu => user-menu}/account-api-keys.spec.ts (96%) rename cypress/e2e/tests/pages/{user_menu => user-menu}/logout.spec.ts (89%) rename cypress/e2e/tests/pages/{user_menu => user-menu}/preferences.spec.ts (91%) create mode 100644 scripts/__tests__/cypress.test.ts create mode 100644 scripts/cypress.ts diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 66ae843de52..0a7b5509c6a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -23,11 +23,28 @@ env: TEST_PROJECT_ID: rancher-dashboard CYPRESS_API_URL: http://139.59.134.103:1234/ TEST_RUN_ID: ${{github.run_number}}-${{github.run_attempt}}-${{github.event.pull_request.title || github.event.head_commit.message}} - CYPRESS_coverage: true + # Build the dashboard to use in tests. When set to false it will grab `latest` from CDN (useful for running e2e tests quickly) + BUILD_DASHBOARD: true jobs: e2e-test: if: "!contains( github.event.pull_request.labels.*.name, 'ci/skip-e2e')" + strategy: + fail-fast: false + matrix: + role: [ + { username: 'admin', tag: '@adminUser' }, + { username: 'standard_user', tag: '@standardUser' } + ] + features: [ + ['@navigation', '@extensions'], + ['@charts'], + ['@explorer'], + ['@fleet'], + ['@generic', '@globalSettings'], + ['@manager'], + ['@userMenu', '@usersAndAuths'] + ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -37,13 +54,15 @@ jobs: with: node-version: '14.x' - - name: Install Chrome 116 - run: | - sudo apt-get install -y wget - cd /tmp - wget -q http://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/google-chrome-stable_116.0.5845.187-1_amd64.deb - sudo apt-get install -y --allow-downgrades ./google-chrome-stable_116.0.5845.187-1_amd64.deb - google-chrome --version + # Installing fixed version of Chrome since latest version does not work (117-118 didn't work) + # Leaving this here again in case we need to pin to a specific Chrome version in the future + # - name: Install Chrome 116 + # run: | + # sudo apt-get install -y wget + # cd /tmp + # wget -q http://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/google-chrome-stable_116.0.5845.187-1_amd64.deb + # sudo apt-get install -y --allow-downgrades ./google-chrome-stable_116.0.5845.187-1_amd64.deb + # google-chrome --version - name: Install packages run: yarn install:ci @@ -51,39 +70,28 @@ jobs: - name: Prepare build run: yarn e2e:pre-prod - - name: Run admin user tests + - name: Setup Rancher and user run: | yarn e2e:prod - mkdir -p coverage-artifacts/coverage - cp coverage/e2e/coverage-final.json coverage-artifacts/coverage/coverage-e2e.json - cp -r coverage/e2e/ coverage-artifacts/coverage/e2e/ env: - GREP_TAGS: '@adminUser' + GREP_TAGS: ${{ matrix.role.tag }}Setup+${{ matrix.features[0] }} --@jenkins ${{ matrix.role.tag }}Setup+${{ matrix.features[1] || matrix.features[0] }} --@jenkins TEST_USERNAME: admin - - - - name: Run standard user tests - if: ${{ success() || failure() }} + TEST_ONLY: setup + + - name: Run user tests run: | yarn e2e:prod - yarn docker:local:stop - mkdir -p coverage-artifacts/coverage - cp coverage/e2e/coverage-final.json coverage-artifacts/coverage/coverage-e2e.json + [ "$BUILD_DASHBOARD" != "false" ] || exit 0 env: - GREP_TAGS: '@standardUser' - TEST_USERNAME: standard_user - - - name: Upload coverage - uses: actions/upload-artifact@v3 - with: - name: ${{github.run_number}}-${{github.run_attempt}}-coverage - path: coverage-artifacts/**/* + TEST_SKIP: setup + GREP_TAGS: ${{ matrix.role.tag }}+${{ matrix.features[0] }} --@jenkins ${{ matrix.role.tag }}+${{ matrix.features[1] || matrix.features[0] }} --@jenkins + TEST_USERNAME: ${{ matrix.role.username }} - name: Upload screenshots uses: actions/upload-artifact@v3 if: ${{ failure() }} with: - name: ${{github.run_number}}-${{github.run_attempt}}-screenshots + name: ${{github.run_number}}-${{github.run_attempt}}-screenshots-${{ matrix.role.tag }}+${{ matrix.features[0] }} path: cypress/screenshots unit-test: @@ -145,11 +153,9 @@ jobs: run: yarn lint coverage: - if: "!contains( github.event.pull_request.labels.*.name, 'ci/skip-e2e')" runs-on: ubuntu-latest needs: - unit-test - - e2e-test steps: - uses: actions/checkout@v3 with: @@ -164,16 +170,10 @@ jobs: with: name: ${{github.run_number}}-${{github.run_attempt}}-coverage - - name: Merge coverage files - run: | - ls - yarn coverage - ls coverage - - - name: Upload merged coverage to Codecov + - name: Upload unit test coverage to Codecov uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} - flags: merged - files: ./coverage/coverage.json + flags: unit + files: ./coverage/coverage-unit.json fail_ci_if_error: false diff --git a/cypress.config.ts b/cypress.config.ts index d46e59f87cc..433bb3cb2e0 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -1,82 +1,50 @@ +/* eslint-disable no-console */ import { defineConfig } from 'cypress'; +import { removeDirectory } from 'cypress-delete-downloads-folder'; +import { getSpecPattern } from '@/scripts/cypress'; // Required for env vars to be available in cypress require('dotenv').config(); -const skipSetup = process.env.TEST_SKIP_SETUP === 'true'; -const hasCoverage = (process.env.TEST_INSTRUMENT === 'true') || false; // Add coverage if instrumented - /** - * Filter test spec paths based on env var configuration - * @returns + * VARIABLES */ -const getSpecPattern = (): string[] => { - const optionalPaths = [ - { - path: 'cypress/e2e/tests/setup/**/*.spec.ts', - active: !skipSetup - } - ]; - const activePaths = optionalPaths.filter(({ active }) => Boolean(active)).map(({ path }) => path); - - // List the test directories to be included - const testDirs = ['pages', 'navigation', 'global-ui'].map((dir) => `cypress/e2e/tests/${ dir }/**/*.spec.ts`); - - return [ - ...activePaths, - ...testDirs - ]; -}; +const hasCoverage = (process.env.TEST_INSTRUMENT === 'true') || false; // Add coverage if instrumented +const testDirs = ['setup', 'pages', 'navigation', 'global-ui']; +const skipSetup = process.env.TEST_SKIP?.includes('setup'); const baseUrl = (process.env.TEST_BASE_URL || 'https://localhost:8005').replace(/\/$/, ''); - -// Default user name, if TEST_USERNAME is not provided const DEFAULT_USERNAME = 'admin'; +const username = process.env.TEST_USERNAME || DEFAULT_USERNAME; +const apiUrl = process.env.API || (baseUrl.endsWith('/dashboard') ? baseUrl.split('/').slice(0, -1).join('/') : baseUrl); -// Log summary of the environment variables that we have detected (or are going ot use) - we won't show any passwords -console.log('E2E Test Configuration'); // eslint-disable-line no-console -console.log(''); // eslint-disable-line no-console +/** + * LOGS: + * Summary of the environment variables that we have detected (or are going ot use) + * We won't show any passwords + */ +console.log('E2E Test Configuration'); +console.log(''); +console.log(` Username: ${ username }`); -if (process.env.TEST_USERNAME) { - console.log(` Username: ${ process.env.TEST_USERNAME }`); // eslint-disable-line no-console -} else { - console.log(` Username: ${ DEFAULT_USERNAME } (TEST_USERNAME not set, using default)`); // eslint-disable-line no-console +if (!process.env.CATTLE_BOOTSTRAP_PASSWORD && !process.env.TEST_PASSWORD) { + console.log(' ❌ You must provide either CATTLE_BOOTSTRAP_PASSWORD or TEST_PASSWORD'); } - if (process.env.CATTLE_BOOTSTRAP_PASSWORD && process.env.TEST_PASSWORD) { - console.log(' ❌ You should not set both CATTLE_BOOTSTRAP_PASSWORD and TEST_PASSWORD - CATTLE_BOOTSTRAP_PASSWORD will be used'); // eslint-disable-line no-console + console.log(' ❗ If both CATTLE_BOOTSTRAP_PASSWORD and TEST_PASSWORD are provided, the first will be used'); } - if (!skipSetup && !process.env.CATTLE_BOOTSTRAP_PASSWORD) { - console.log(' ❌ You must provide CATTLE_BOOTSTRAP_PASSWORD when running setup tests'); // eslint-disable-line no-console -} - -if (!process.env.CATTLE_BOOTSTRAP_PASSWORD && !process.env.TEST_PASSWORD) { - console.log(' ❌ You must provide one of CATTLE_BOOTSTRAP_PASSWORD or TEST_PASSWORD'); // eslint-disable-line no-console + console.log(' ❌ You must provide CATTLE_BOOTSTRAP_PASSWORD when running setup tests'); } - if (skipSetup && !process.env.TEST_PASSWORD) { - console.log(' ❌ You should provide TEST_PASSWORD when running the tests without the setup tests'); // eslint-disable-line no-console + console.log(' ❌ You must provide TEST_PASSWORD when running the tests without the setup tests'); } -if (skipSetup) { - console.log(` Setup tests will NOT be run`); // eslint-disable-line no-console -} else { - console.log(` Setup tests will be run`); // eslint-disable-line no-console -} - -console.log(` Dashboard URL: ${ baseUrl }`); // eslint-disable-line no-console - -const apiUrl = process.env.API || (baseUrl.endsWith('/dashboard') ? baseUrl.split('/').slice(0, -1).join('/') : baseUrl); - -console.log(` Rancher API URL: ${ apiUrl }`); // eslint-disable-line no-console - -// Check API - sometimes in dev, you might have API set to a different system to the base url - this won't work -// as the login cookie will be for the base url and any API requests will fail as not authenticated -if (apiUrl && !baseUrl.startsWith(apiUrl)) { - console.log('\n ❗ API variable is different to TEST_BASE_URL - tests may fail due to authentication issues'); // eslint-disable-line no-console -} - -console.log(''); // eslint-disable-line no-console +console.log(` Setup tests will ${ skipSetup ? 'NOT' : '' } be run`); +console.log(` Dashboard URL: ${ baseUrl }`); +console.log(` Rancher API URL: ${ apiUrl }`); +/** + * CONFIGURATION + */ export default defineConfig({ projectId: process.env.TEST_PROJECT_ID, defaultCommandTimeout: process.env.TEST_TIMEOUT ? +process.env.TEST_TIMEOUT : 60000, @@ -87,10 +55,11 @@ export default defineConfig({ openMode: 0 }, env: { - grepFilterSpecs: true, + grepFilterSpecs: true, + grepOmitFiltered: true, baseUrl, - coverage: hasCoverage, - codeCoverage: { + coverage: hasCoverage, + codeCoverage: { exclude: [ 'cypress/**/*.*', '**/__tests__/**/*.*', @@ -107,11 +76,17 @@ export default defineConfig({ 'pkg/rancher-components/src/components/**/*.{vue,ts,js}', ] }, - api: apiUrl, - username: process.env.TEST_USERNAME || DEFAULT_USERNAME, - password: process.env.CATTLE_BOOTSTRAP_PASSWORD || process.env.TEST_PASSWORD, - bootstrapPassword: process.env.CATTLE_BOOTSTRAP_PASSWORD, - grepTags: process.env.GREP_TAGS + api: apiUrl, + username: process.env.TEST_USERNAME || DEFAULT_USERNAME, + password: process.env.CATTLE_BOOTSTRAP_PASSWORD || process.env.TEST_PASSWORD, + bootstrapPassword: process.env.CATTLE_BOOTSTRAP_PASSWORD, + grepTags: process.env.GREP_TAGS, + // the below env vars are only available to tests that run in Jenkins + awsAccessKey: process.env.AWS_ACCESS_KEY_ID, + awsSecretKey: process.env.AWS_SECRET_ACCESS_KEY, + azureSubscriptionId: process.env.AZURE_AKS_SUBSCRIPTION_ID, + azureClientId: process.env.AZURE_CLIENT_ID, + azureClientSecret: process.env.AZURE_CLIENT_SECRET }, e2e: { fixturesFolder: 'cypress/e2e/blueprints', @@ -119,11 +94,13 @@ export default defineConfig({ // For more info: https://docs.cypress.io/guides/tooling/code-coverage require('@cypress/code-coverage/task')(on, config); require('@cypress/grep/src/plugin')(config); + // For more info: https://www.npmjs.com/package/cypress-delete-downloads-folder + on('task', { removeDirectory }); return config; }, experimentalSessionAndOrigin: true, - specPattern: getSpecPattern(), + specPattern: getSpecPattern(testDirs, process.env), baseUrl }, videoCompression: 15, diff --git a/cypress/e2e/tests/pages/data/agent-configuration-rke2-data.ts b/cypress/e2e/blueprints/agent-configuration/agent-configuration-rke2-data.ts similarity index 100% rename from cypress/e2e/tests/pages/data/agent-configuration-rke2-data.ts rename to cypress/e2e/blueprints/agent-configuration/agent-configuration-rke2-data.ts diff --git a/cypress/e2e/tests/pages/data/agent-configuration-rke2-payload.ts b/cypress/e2e/blueprints/agent-configuration/agent-configuration-rke2-payload.ts similarity index 100% rename from cypress/e2e/tests/pages/data/agent-configuration-rke2-payload.ts rename to cypress/e2e/blueprints/agent-configuration/agent-configuration-rke2-payload.ts diff --git a/cypress/e2e/blueprints/cluster_management/machine-deployments-edit.yml b/cypress/e2e/blueprints/cluster_management/machine-deployments-edit.yml new file mode 100644 index 00000000000..45a107e2f3a --- /dev/null +++ b/cypress/e2e/blueprints/cluster_management/machine-deployments-edit.yml @@ -0,0 +1,52 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineDeployment +metadata: + creationTimestamp: '2023-12-07T18:14:50Z' + generation: 1 + labels: + cluster.x-k8s.io/cluster-name: local + managedFields: + - apiVersion: cluster.x-k8s.io/v1beta1 + fieldsType: FieldsV1 + fieldsV1: + f:spec: + .: {} + f:clusterName: {} + f:selector: {} + f:template: + .: {} + f:metadata: {} + f:spec: + .: {} + f:clusterName: {} + manager: rancher + operation: Update + time: '2023-12-07T18:14:50Z' + name: e2e-machinedeployment-name-1701972886077 + namespace: default + resourceVersion: '22851' + uid: f5bf052d-7bbf-483a-a20a-b2f6e48d1e15 +spec: + clusterName: local + minReadySeconds: 0 + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 1 + selector: + matchLabels: + cluster.x-k8s.io/cluster-name: local + cluster.x-k8s.io/deployment-name: e2e-machinedeployment-name-1701972886077 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + template: + metadata: + labels: + cluster.x-k8s.io/cluster-name: local + cluster.x-k8s.io/deployment-name: e2e-machinedeployment-name-1701972886077 + spec: + bootstrap: {} + clusterName: local + infrastructureRef: {} diff --git a/cypress/e2e/blueprints/cluster_management/machine-deployments.yml b/cypress/e2e/blueprints/cluster_management/machine-deployments.yml new file mode 100644 index 00000000000..3487b20fd15 --- /dev/null +++ b/cypress/e2e/blueprints/cluster_management/machine-deployments.yml @@ -0,0 +1,65 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineDeployment +metadata: + name: e2etest + namespace: default +# annotations: key: string +# labels: key: string +spec: + selector: + matchLabels:# key: string +# matchExpressions: +# - key: string +# operator: string +# values: +# - string + template: + metadata: + labels:# key: string +# annotations: key: string +# generateName: string +# name: string +# namespace: string +# ownerReferences: +# - apiVersion: string +# blockOwnerDeletion: boolean +# controller: boolean +# kind: string +# name: string +# uid: string + spec: +# bootstrap: +# configRef: +# apiVersion: string +# fieldPath: string +# kind: string +# name: string +# namespace: string +# resourceVersion: string +# uid: string +# data: string +# dataSecretName: string + clusterName: local +# failureDomain: string +# infrastructureRef: +# apiVersion: string +# fieldPath: string +# kind: string +# name: string +# namespace: string +# resourceVersion: string +# uid: string +# nodeDrainTimeout: string +# providerID: string +# version: string + clusterName: local +# minReadySeconds: int +# paused: boolean +# progressDeadlineSeconds: int +# replicas: int +# revisionHistoryLimit: int +# strategy: +# type: string +# rollingUpdate: +# maxSurge: json +# maxUnavailable: json \ No newline at end of file diff --git a/cypress/e2e/blueprints/cluster_management/machine-sets-edit.yml b/cypress/e2e/blueprints/cluster_management/machine-sets-edit.yml new file mode 100644 index 00000000000..c38d55c00b5 --- /dev/null +++ b/cypress/e2e/blueprints/cluster_management/machine-sets-edit.yml @@ -0,0 +1,44 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineSet +metadata: + creationTimestamp: '2023-12-06T23:41:44Z' + generation: 3 + labels: + cluster.x-k8s.io/cluster-name: local + managedFields: + - apiVersion: cluster.x-k8s.io/v1beta1 + fieldsType: FieldsV1 + fieldsV1: + f:spec: + .: {} + f:clusterName: {} + f:replicas: {} + f:selector: {} + f:template: + .: {} + f:metadata: {} + f:spec: + .: {} + f:clusterName: {} + manager: rancher + operation: Update + time: '2023-12-06T23:46:28Z' + name: e2e-machine-name-1701906098950 + namespace: default + resourceVersion: '647485' + uid: 98380f64-0706-4522-8dc2-b91a7f012dcf +spec: + clusterName: local + deletePolicy: Random + replicas: 1 + selector: + matchLabels: + cluster.x-k8s.io/set-name: e2e-machine-name-1701906098950 + template: + metadata: + labels: + cluster.x-k8s.io/set-name: e2e-machine-name-1701906098950 + spec: + bootstrap: {} + clusterName: local + infrastructureRef: {} diff --git a/cypress/e2e/blueprints/cluster_management/machine-sets.yml b/cypress/e2e/blueprints/cluster_management/machine-sets.yml new file mode 100644 index 00000000000..21e0f9a66c3 --- /dev/null +++ b/cypress/e2e/blueprints/cluster_management/machine-sets.yml @@ -0,0 +1,58 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: MachineSet +metadata: + name: e2etest + namespace: default +# annotations: key: string +# labels: key: string +spec: + selector: + matchLabels:# key: string +# matchExpressions: +# - key: string +# operator: string +# values: +# - string + template: + metadata: + labels:# key: string +# annotations: key: string +# generateName: string +# name: string +# namespace: string +# ownerReferences: +# - apiVersion: string +# blockOwnerDeletion: boolean +# controller: boolean +# kind: string +# name: string +# uid: string + spec: + bootstrap: +# configRef: +# apiVersion: string +# fieldPath: string +# kind: string +# name: string +# namespace: string +# resourceVersion: string +# uid: string +# data: string + dataSecretName: secretName + clusterName: local +# failureDomain: string +# infrastructureRef: +# apiVersion: string +# fieldPath: string +# kind: string +# name: string +# namespace: string +# resourceVersion: string +# uid: string +# nodeDrainTimeout: string +# providerID: string +# version: string + clusterName: local +# deletePolicy: string +# minReadySeconds: int +# replicas: int \ No newline at end of file diff --git a/cypress/e2e/blueprints/cluster_management/machines-edit.yml b/cypress/e2e/blueprints/cluster_management/machines-edit.yml new file mode 100644 index 00000000000..5b8289e504e --- /dev/null +++ b/cypress/e2e/blueprints/cluster_management/machines-edit.yml @@ -0,0 +1,33 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Machine +metadata: + creationTimestamp: '2023-12-06T22:21:54Z' + generation: 1 + labels: + cluster.x-k8s.io/cluster-name: local + managedFields: + - apiVersion: cluster.x-k8s.io/v1beta1 + fieldsType: FieldsV1 + fieldsV1: + f:spec: + .: {} + f:bootstrap: + .: {} + f:dataSecretName: {} + f:clusterName: {} + f:infrastructureRef: {} + manager: rancher + operation: Update + time: '2023-12-06T22:21:54Z' + name: e2e-machine-name-1701901308645 + namespace: default + resourceVersion: '609444' + uid: 7d61939a-b44a-4113-a7d1-9db2eda08811 +spec: + bootstrap: + dataSecretName: secretname + clusterName: local + infrastructureRef: + namespace: default + resourceVersion: abc123 + nodeDeletionTimeout: 10s diff --git a/cypress/e2e/blueprints/cluster_management/machines.yml b/cypress/e2e/blueprints/cluster_management/machines.yml new file mode 100644 index 00000000000..5062159c902 --- /dev/null +++ b/cypress/e2e/blueprints/cluster_management/machines.yml @@ -0,0 +1,32 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Machine +metadata: + name: string + namespace: default +# annotations: key: string +# labels: key: string +spec: + bootstrap: +# configRef: +# apiVersion: string +# fieldPath: string +# kind: string +# name: string +# namespace: string +# resourceVersion: string +# uid: string +# data: string + dataSecretName: secretname + clusterName: local +# failureDomain: string +# infrastructureRef: +# apiVersion: string +# fieldPath: string +# kind: string +# name: string +# namespace: string +# resourceVersion: string +# uid: string +# nodeDrainTimeout: string +# providerID: string +# version: string \ No newline at end of file diff --git a/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts b/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts new file mode 100644 index 00000000000..d817fce64fc --- /dev/null +++ b/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts @@ -0,0 +1,37 @@ +export const createPayloadData = { + id: 'e2e-pod-security-admission-1705617529465', + type: 'management.cattle.io.podsecurityadmissionconfigurationtemplate', + apiVersion: 'management.cattle.io/v3', + configuration: { + defaults: { + audit: 'baseline', 'audit-version': 'latest', enforce: 'privileged', 'enforce-version': 'latest', warn: 'restricted', 'warn-version': 'latest' + }, + exemptions: { + usernames: ['admin', 'user'], runtimeClasses: ['myclass1', 'myclass2'], namespaces: ['ingress-nginx', 'kube-system'] + } + }, + kind: 'PodSecurityAdmissionConfigurationTemplate', + metadata: { + fields: ['e2e-pod-security-admission-1705617529465', '18s'], name: 'e2e-pod-security-admission-1705617529465', resourceVersion: '831667' + }, + description: 'e2e-pod-security-admission-1705617529465-description' +}; + +export const updatePayloadData = { + id: 'e2e-pod-security-admission-1705628550961', + type: 'management.cattle.io.podsecurityadmissionconfigurationtemplate', + apiVersion: 'management.cattle.io/v3', + configuration: { + defaults: { + audit: 'baseline', 'audit-version': 'v1.25', enforce: 'privileged', 'enforce-version': 'v1.25', warn: 'restricted', 'warn-version': 'v1.25' + }, + exemptions: { + usernames: ['admin1', 'user1'], runtimeClasses: ['myclass3', 'myclass4'], namespaces: ['cattle-system', 'cattle-epinio-system'] + } + }, + kind: 'PodSecurityAdmissionConfigurationTemplate', + metadata: { + fields: ['e2e-pod-security-admission-1705628550961', '7s'], name: 'e2e-pod-security-admission-1705628550961', resourceVersion: '938739' + }, + description: 'e2e-pod-security-admission-1705628550961-description-edit' +}; diff --git a/cypress/e2e/po/components/ResourceList/resource-list-masthead.po.ts b/cypress/e2e/po/components/ResourceList/resource-list-masthead.po.ts index 6608a59b45e..0f452a7eaf5 100644 --- a/cypress/e2e/po/components/ResourceList/resource-list-masthead.po.ts +++ b/cypress/e2e/po/components/ResourceList/resource-list-masthead.po.ts @@ -8,4 +8,8 @@ export default class ResourceListMastheadPo extends ComponentPo { title() { return this.self().get('.title h1').invoke('text'); } + + create() { + return this.self().find('[data-testid="masthead-create-yaml"]').click(); + } } diff --git a/cypress/e2e/po/components/cru-resource.po.ts b/cypress/e2e/po/components/cru-resource.po.ts index 7f9bc6ab04d..c3df465a6c2 100644 --- a/cypress/e2e/po/components/cru-resource.po.ts +++ b/cypress/e2e/po/components/cru-resource.po.ts @@ -1,4 +1,5 @@ import ComponentPo from '@/cypress/e2e/po/components/component.po'; +import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po'; export default class CruResourcePo extends ComponentPo { selectSubType(groupIndex: number, itemIndex: number) { @@ -6,4 +7,22 @@ export default class CruResourcePo extends ComponentPo { .eq(groupIndex).find('.item') .eq(itemIndex); } + + selectSubTypeByIndex(index: number) { + return this.self().find('.subtypes-container > div') + .eq(index); + } + + saveOrCreate(): AsyncButtonPo { + return new AsyncButtonPo('[data-testid="form-save"]', this.self()); + } + + saveAndWaitForRequests(method, endpoint: string, statusCode?: number): Cypress.Chainable { + cy.intercept(method, endpoint).as(endpoint); + this.saveOrCreate().click(); + /* eslint-disable cypress/no-assigning-return-values */ + const wait = cy.wait(`@${ endpoint }`, { timeout: 10000 }); + + return statusCode ? wait.its('response.statusCode').should('eq', statusCode) : wait; + } } diff --git a/cypress/e2e/po/components/ember/ember-accordion.po.ts b/cypress/e2e/po/components/ember/ember-accordion.po.ts index e57250f9158..c36a121aae4 100644 --- a/cypress/e2e/po/components/ember/ember-accordion.po.ts +++ b/cypress/e2e/po/components/ember/ember-accordion.po.ts @@ -1,5 +1,4 @@ import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po'; - export default class EmberAccordionPo extends EmberComponentPo { private headerSelector: string; private contentSelector: string; diff --git a/cypress/e2e/po/components/ember/ember-checkbox-input.po.ts b/cypress/e2e/po/components/ember/ember-checkbox-input.po.ts new file mode 100644 index 00000000000..b62a6ee8916 --- /dev/null +++ b/cypress/e2e/po/components/ember/ember-checkbox-input.po.ts @@ -0,0 +1,19 @@ +import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po'; + +export default class EmberCheckboxInputPo extends EmberComponentPo { + /** + * Click on the checkbox input button + * @returns + */ + set(): Cypress.Chainable { + return this.input().click({ force: true }); + } + + /** + * Return the checkbox input button from a given container + * @returns + */ + private input(): Cypress.Chainable { + return this.self().find('.ember-checkbox'); + } +} diff --git a/cypress/e2e/po/components/ember/ember-form-pod-security-template.po.ts b/cypress/e2e/po/components/ember/ember-form-pod-security-template.po.ts new file mode 100644 index 00000000000..d1bfeea562d --- /dev/null +++ b/cypress/e2e/po/components/ember/ember-form-pod-security-template.po.ts @@ -0,0 +1,29 @@ +import EmberAccordionPo from '@/cypress/e2e/po/components/ember/ember-accordion.po'; +import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po'; +import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po'; + +export default class EmberAddPodSecurityTemplatePo extends EmberComponentPo { + templateName(): EmberInputPo { + return new EmberInputPo('[data-testid="form-name-description__name"]'); + } + + templateDescription(): EmberInputPo { + return new EmberInputPo('.ember-text-area'); + } + + addDescription() { + this.self().find('div > a.btn', 'Add a Description').click(); + } + + accordion() { + return new EmberAccordionPo('.accordion-wrapper'); + } + + create() { + return this.self().find('button.btn').contains('Create').click(); + } + + save() { + return this.self().find('button.btn').contains('Save').click(); + } +} diff --git a/cypress/e2e/po/components/ember/ember-form-rke-templates.po.ts b/cypress/e2e/po/components/ember/ember-form-rke-templates.po.ts new file mode 100644 index 00000000000..5813966b5d7 --- /dev/null +++ b/cypress/e2e/po/components/ember/ember-form-rke-templates.po.ts @@ -0,0 +1,16 @@ +import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po'; +import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po'; + +export default class EmberFormRkeTemplatesPo extends EmberComponentPo { + templateDetails(index): EmberInputPo { + return new EmberInputPo(`.horizontal-form .row:nth-of-type(1) input:nth-child(${ index })`); + } + + create() { + return this.self().contains('[data-testid="save-cancel-rke1"] button', 'Create').click(); + } + + save() { + return this.self().contains('[data-testid="save-cancel-rke1"] button', 'Save').click(); + } +} diff --git a/cypress/e2e/po/components/ember/ember-modal-add-edit-cluster-driver.po.ts b/cypress/e2e/po/components/ember/ember-modal-add-edit-cluster-driver.po.ts new file mode 100644 index 00000000000..c63e3805ff8 --- /dev/null +++ b/cypress/e2e/po/components/ember/ember-modal-add-edit-cluster-driver.po.ts @@ -0,0 +1,20 @@ +import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po'; +import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po'; + +export default class EmberModalClusterDriverPo extends EmberModalPo { + formInput(index: number) { + return new EmberInputPo(`.modal-open .inline-form:nth-of-type(${ index }) input`); + } + + addDomainButton() { + this.self().find('button').contains('Add Domain').click(); + } + + create() { + return this.self().find('button').contains('Create').click(); + } + + save() { + return this.self().find('button').contains('Save').click(); + } +} diff --git a/cypress/e2e/po/components/ember/ember-modal-add-edit-node-driver.po.ts b/cypress/e2e/po/components/ember/ember-modal-add-edit-node-driver.po.ts new file mode 100644 index 00000000000..1dd7d3fd220 --- /dev/null +++ b/cypress/e2e/po/components/ember/ember-modal-add-edit-node-driver.po.ts @@ -0,0 +1,20 @@ +import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po'; +import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po'; + +export default class EmberModalNodeDriverPo extends EmberModalPo { + formInput(index: number) { + return new EmberInputPo(`.modal-open .inline-form:nth-of-type(${ index }) input`); + } + + addDomainButton() { + this.self().find('button').contains('Add Domain').click(); + } + + create() { + return this.self().find('button').contains('Create').click(); + } + + save() { + return this.self().find('button').contains('Save').click(); + } +} diff --git a/cypress/e2e/po/components/ember/ember-modal-add-node-template.po.ts b/cypress/e2e/po/components/ember/ember-modal-add-node-template.po.ts new file mode 100644 index 00000000000..db7eae2d329 --- /dev/null +++ b/cypress/e2e/po/components/ember/ember-modal-add-node-template.po.ts @@ -0,0 +1,33 @@ +import EmberAccordionPo from '@/cypress/e2e/po/components/ember/ember-accordion.po'; +import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po'; +import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po'; + +export default class EmberModalAddNodeTemplatePo extends EmberModalPo { + serviceProviderOptions(label: string) { + return this.self().contains('.nav-box-item', new RegExp(` ${ label } `)); + } + + nextButton(label: string) { + return this.self().contains('.btn', label, { timeout: 10000 }); + } + + accordion() { + return new EmberAccordionPo(''); + } + + checkOption(value: string) { + return this.self().find('.form-control').contains(value).click(); + } + + templateName(): EmberInputPo { + return new EmberInputPo('[data-testid="form-name-description__name"]'); + } + + create() { + return this.self().find('button').contains('Create').click(); + } + + save() { + return this.self().find('button').contains('Save').click(); + } +} diff --git a/cypress/e2e/po/components/ember/ember-modal.po.ts b/cypress/e2e/po/components/ember/ember-modal.po.ts index a4931385d64..b2ca2d8192c 100644 --- a/cypress/e2e/po/components/ember/ember-modal.po.ts +++ b/cypress/e2e/po/components/ember/ember-modal.po.ts @@ -4,4 +4,12 @@ export default class EmberModalPo extends EmberComponentPo { constructor() { super('.modal-open'); } + + deactivate() { + return this.self().contains('.btn', 'Deactivate').click(); + } + + delete() { + return this.self().contains('.btn', 'Delete').click(); + } } diff --git a/cypress/e2e/po/components/ember/ember-select.po.ts b/cypress/e2e/po/components/ember/ember-select.po.ts new file mode 100644 index 00000000000..2388af538a5 --- /dev/null +++ b/cypress/e2e/po/components/ember/ember-select.po.ts @@ -0,0 +1,25 @@ +import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po'; + +export default class EmberSelectPo extends EmberComponentPo { + getMenuItem(label: string, index = 0) { + return this.self().eq(index).contains(label); + } + + selectMenuItemByLabel(label: string, index = 0) { + return this.self().eq(index).contains(label).click(); + } + + /** + * Select an