diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index cf0c613b020..d3ed37403b9 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -71,14 +71,15 @@ jobs: { username: 'standard_user', tag: '@standardUser' } ] features: [ - ['@navigation', '@extensions'], - ['@charts'], - ['@explorer'], - ['@fleet'], - ['@generic', '@globalSettings'], - ['@manager'], - ['@userMenu', '@usersAndAuths'], - ['@components'], + ['@navigation', '@extensions'], + ['@charts'], + ['@explorer'], + ['@fleet'], + ['@generic', '@globalSettings'], + ['@manager'], + ['@userMenu', '@usersAndAuths'], + ['@components'], + ['@vai'] ] runs-on: ubuntu-latest steps: @@ -119,7 +120,6 @@ jobs: GREP_TAGS: ${{ matrix.role.tag }}Setup+${{ matrix.features[0] }} --@jenkins ${{ matrix.role.tag }}Setup+${{ matrix.features[1] || matrix.features[0] }} --@jenkins TEST_USERNAME: admin TEST_ONLY: setup - - name: Run user tests run: | yarn e2e:prod diff --git a/cypress.config.ts b/cypress.config.ts index 6c6abbd6e17..3c5b702f850 100644 --- a/cypress.config.ts +++ b/cypress.config.ts @@ -9,7 +9,7 @@ require('dotenv').config(); * VARIABLES */ const hasCoverage = (process.env.TEST_INSTRUMENT === 'true') || false; // Add coverage if instrumented -const testDirs = ['components', 'setup', 'pages', 'navigation', 'global-ui']; +const testDirs = ['priority', 'components', 'setup', 'pages', 'navigation', 'global-ui', 'features']; const skipSetup = process.env.TEST_SKIP?.includes('setup'); const baseUrl = (process.env.TEST_BASE_URL || 'https://localhost:8005').replace(/\/$/, ''); const DEFAULT_USERNAME = 'admin'; diff --git a/cypress/e2e/blueprints/explorer/cluster/events.ts b/cypress/e2e/blueprints/explorer/cluster/events.ts index 91503062fb8..32e7cf41688 100644 --- a/cypress/e2e/blueprints/explorer/cluster/events.ts +++ b/cypress/e2e/blueprints/explorer/cluster/events.ts @@ -5,7 +5,7 @@ const eventsGetEmptyEventsSet = { createTypes: { event: `${ Cypress.env('api') }/v1/events` }, actions: {}, resourceType: 'event', - revision: '95942', + revision: Number.MAX_VALUE, // The UI will use this point in history to start watching for changes from. If it's too low (than the global system revision) we will spam with requests data: [] }; @@ -16,7 +16,7 @@ const eventsGetResponseSmallSet = { createTypes: { event: `${ Cypress.env('api') }/v1/events` }, actions: {}, resourceType: 'event', - revision: '95942', + revision: Number.MAX_VALUE, // The UI will use this point in history to start watching for changes from. If it's too low (than the global system revision) we will spam with requests count: 3, data: [ { diff --git a/cypress/e2e/blueprints/explorer/more-resources/api/custom-resource-definition-get.ts b/cypress/e2e/blueprints/explorer/more-resources/api/custom-resource-definition-get.ts index 145f83402d4..37ce83b7b69 100644 --- a/cypress/e2e/blueprints/explorer/more-resources/api/custom-resource-definition-get.ts +++ b/cypress/e2e/blueprints/explorer/more-resources/api/custom-resource-definition-get.ts @@ -5,7 +5,7 @@ const crdsGetResponseSmallSet = { createTypes: { 'apiextensions.k8s.io.customresourcedefinition': 'https://yonasb29head.qa.rancher.space/v1/apiextensions.k8s.io.customresourcedefinitions' }, actions: {}, resourceType: 'apiextensions.k8s.io.customresourcedefinition', - revision: '123', + revision: Number.MAX_VALUE, // The UI will use this point in history to start watching for changes from. If it's too low (than the global system revision) we will spam with requests count: 2, data: [ { diff --git a/cypress/e2e/blueprints/roles/global-roles-get.ts b/cypress/e2e/blueprints/roles/global-roles-get.ts index a338bdb541a..b0c606f637c 100644 --- a/cypress/e2e/blueprints/roles/global-roles-get.ts +++ b/cypress/e2e/blueprints/roles/global-roles-get.ts @@ -5,7 +5,7 @@ const globalRolesGetResponseSmallSet = { createTypes: { 'management.cattle.io.globalrole': 'https://yonasb29head.qa.rancher.space/v1/management.cattle.io.globalroles' }, actions: {}, resourceType: 'management.cattle.io.globalrole', - revision: '123', + revision: Number.MAX_VALUE, // The UI will use this point in history to start watching for changes from. If it's too low (than the global system revision) we will spam with requests count: 2, data: [ { diff --git a/cypress/e2e/blueprints/users/users-get.ts b/cypress/e2e/blueprints/users/users-get.ts index 1f95f4ae996..90bed6d1e4f 100644 --- a/cypress/e2e/blueprints/users/users-get.ts +++ b/cypress/e2e/blueprints/users/users-get.ts @@ -43,6 +43,7 @@ const usersGetResponseSmallSet = { uuid: null }, resourceType: 'user', + revision: Number.MAX_VALUE, // The UI will use this point in history to start watching for changes from. If it's too low (than the global system revision) we will spam with requests data: [ { actions: { diff --git a/cypress/e2e/po/components/component.po.ts b/cypress/e2e/po/components/component.po.ts index 94a3efbf315..1762ea2c5e8 100644 --- a/cypress/e2e/po/components/component.po.ts +++ b/cypress/e2e/po/components/component.po.ts @@ -79,7 +79,7 @@ export default class ComponentPo { return this.self().should('exist'); } - checkNotExists(): Cypress.Chainable { - return this.self().should('not.exist'); + checkNotExists(options?: GetOptions): Cypress.Chainable { + return this.self(options).should('not.exist'); } } diff --git a/cypress/e2e/po/components/sortable-table.po.ts b/cypress/e2e/po/components/sortable-table.po.ts index f092729b16b..0e22d6f10f8 100644 --- a/cypress/e2e/po/components/sortable-table.po.ts +++ b/cypress/e2e/po/components/sortable-table.po.ts @@ -244,6 +244,10 @@ export default class SortableTablePo extends ComponentPo { cy.get('tbody', { timeout: 10000 }).find('.data-loading').should('not.exist'); } + checkNoRowsNotVisible() { + cy.get('tbody', { timeout: 10000 }).find('.no-rows').should('not.exist'); + } + // pagination pagination() { return new PaginationPo(); diff --git a/cypress/e2e/po/pages/cluster-page.po.ts b/cypress/e2e/po/pages/cluster-page.po.ts new file mode 100644 index 00000000000..a320f3c3bf6 --- /dev/null +++ b/cypress/e2e/po/pages/cluster-page.po.ts @@ -0,0 +1,18 @@ +import PagePo from '@/cypress/e2e/po/pages/page.po'; + +export default abstract class ClusterPage extends PagePo { + private static createPath(clusterId: string, pathAfterCluster: string) { + return `/c/${ clusterId }/${ pathAfterCluster }`; + } + + /** + * Fetch the cluster id from the url... (note - you need to be on a cluster page for this to work) + */ + static clusterId() { + return cy.url().then((url: string) => /\/c\/([a-z\-_]*)\/\S*/.exec(url)?.[1]); + } + + constructor(clusterId = '_', pathAfterCluster = '') { + super(ClusterPage.createPath(clusterId, pathAfterCluster)); + } +} diff --git a/cypress/e2e/po/pages/global-settings/feature-flags.po.ts b/cypress/e2e/po/pages/global-settings/feature-flags.po.ts index a19046eb27e..9ba6893bddf 100644 --- a/cypress/e2e/po/pages/global-settings/feature-flags.po.ts +++ b/cypress/e2e/po/pages/global-settings/feature-flags.po.ts @@ -4,15 +4,19 @@ import CardPo from '@/cypress/e2e/po/components/card.po'; import { CypressChainable } from '@/cypress/e2e/po/po.types'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; +import { EXTRA_LONG_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; export class FeatureFlagsPagePo extends RootClusterPage { - static url = '/c/_/settings/management.cattle.io.feature'; - static goTo(): Cypress.Chainable { - return super.goTo(FeatureFlagsPagePo.url); + private static createPath(clusterId: string) { + return `/c/${ clusterId }/settings/management.cattle.io.feature`; } - constructor() { - super(FeatureFlagsPagePo.url); + static goTo(clusterId: string): Cypress.Chainable { + return super.goTo(FeatureFlagsPagePo.createPath(clusterId)); + } + + constructor(clusterId = '_') { + super(FeatureFlagsPagePo.createPath(clusterId)); } static navTo() { @@ -57,15 +61,33 @@ export class FeatureFlagsPagePo extends RootClusterPage { * @param value * @returns */ - clickCardActionButtonAndWait(label: 'Activate' | 'Deactivate', endpoint: string, value: boolean): Cypress.Chainable { + clickCardActionButtonAndWait( + label: 'Activate' | 'Deactivate', + endpoint: string, + value: boolean, + config: { + waitForModal: boolean + waitForRequest: boolean + } = { + waitForModal: false, + waitForRequest: true, + }) { cy.intercept('PUT', `/v1/management.cattle.io.features/${ endpoint }`).as(endpoint); this.cardActionButton(label).click(); - return cy.wait(`@${ endpoint }`).then(({ request, response }) => { - expect(response?.statusCode).to.eq(200); - expect(request.body.spec).to.have.property('value', value); - expect(response?.body.spec).to.have.property('value', value); - }); + if (config.waitForRequest) { + cy.wait(`@${ endpoint }`).then(({ request, response }) => { + expect(response?.statusCode).to.eq(200); + expect(request.body.spec).to.have.property('value', value); + expect(response?.body.spec).to.have.property('value', value); + }); + } + + if (config.waitForModal) { + const card = new CardPo(); + + card.checkNotExists(EXTRA_LONG_TIMEOUT_OPT); + } } getFeatureFlag(featureFlag: string): Cypress.Chainable { diff --git a/cypress/e2e/po/pages/global-settings/performance.po.ts b/cypress/e2e/po/pages/global-settings/performance.po.ts index b7bf2288629..e7a8eba545e 100644 --- a/cypress/e2e/po/pages/global-settings/performance.po.ts +++ b/cypress/e2e/po/pages/global-settings/performance.po.ts @@ -5,16 +5,20 @@ import ModalWithCardPo from '@/cypress/e2e/po/components/modal-with-card.po'; import RootClusterPage from '@/cypress/e2e/po/pages/root-cluster-page'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; +import GenericPrompt from '@/cypress/e2e/po/prompts/genericPrompt.po'; export class PerformancePagePo extends RootClusterPage { - static url = '/c/_/settings/performance' + private static createPath(clusterId: string) { + return `/c/${ clusterId }/settings/performance`; + } + static modal = new ModalWithCardPo(); - static goTo(): Cypress.Chainable { - return super.goTo(PerformancePagePo.url); + static goTo(clusterId: string): Cypress.Chainable { + return super.goTo(PerformancePagePo.createPath(clusterId)); } - constructor() { - super(PerformancePagePo.url); + constructor(clusterId = '_') { + super(PerformancePagePo.createPath(clusterId)); } static navTo() { @@ -24,6 +28,10 @@ export class PerformancePagePo extends RootClusterPage { sideNav.navToSideMenuEntryByLabel('Performance'); } + incompatibleModal(): GenericPrompt { + return new GenericPrompt('.prompt-restore'); + } + inactivityCheckbox(): CheckboxInputPo { return CheckboxInputPo.byLabel(this.self(), 'Enable inactivity session expiration '); } @@ -60,11 +68,15 @@ export class PerformancePagePo extends RootClusterPage { return CheckboxInputPo.byLabel(this.self(), 'Enable Advanced Websocket Web Worker '); } + serverSidePaginationCheckbox(): CheckboxInputPo { + return CheckboxInputPo.byLabel(this.self(), 'Enable Server-side Pagination '); + } + applyButton() { return new AsyncButtonPo('[data-testid="performance__save-btn"]', this.self()); } - applyAndWait(context, endpoint = 'ui-performance', statusCode?: number): Cypress.Chainable { + applyAndWait(context: string, endpoint = 'ui-performance', statusCode?: number): Cypress.Chainable { cy.intercept('PUT', endpoint).as(context); this.applyButton().click(); diff --git a/cypress/e2e/po/pages/users-and-auth/roles.po.ts b/cypress/e2e/po/pages/users-and-auth/roles.po.ts index dd88add6e8a..45f15becbb7 100644 --- a/cypress/e2e/po/pages/users-and-auth/roles.po.ts +++ b/cypress/e2e/po/pages/users-and-auth/roles.po.ts @@ -4,21 +4,17 @@ import GlobalRoleEditPo from '@/cypress/e2e/po/edit/management.cattle.io.globalr import RoleTemplateEditPo from '@/cypress/e2e/po/edit/management.cattle.io.roletemplate.po'; import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po'; import RoleListPo from '@/cypress/e2e/po/lists/role-list.po'; -import PagePo from '@/cypress/e2e/po/pages/page.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; +import ClusterPage from '@/cypress/e2e/po/pages/cluster-page.po'; -export default class RolesPo extends PagePo { - private static createPath(clusterId: string) { - return `/c/${ clusterId }/auth/roles`; - } - +export default class RolesPo extends ClusterPage { static goTo(path: string): Cypress.Chainable { throw new Error('invalid'); } constructor(private clusterId = '_') { - super(RolesPo.createPath(clusterId)); + super(clusterId, 'auth/roles'); } static navTo() { diff --git a/cypress/e2e/po/pages/users-and-auth/users.po.ts b/cypress/e2e/po/pages/users-and-auth/users.po.ts index d3b19f3a421..34c9ebaae1a 100644 --- a/cypress/e2e/po/pages/users-and-auth/users.po.ts +++ b/cypress/e2e/po/pages/users-and-auth/users.po.ts @@ -1,16 +1,12 @@ -import PagePo from '@/cypress/e2e/po/pages/page.po'; import MgmtUsersListPo from '@/cypress/e2e/po/lists/management.cattle.io.user.po'; import MgmtUserEditPo from '@/cypress/e2e/po/edit/management.cattle.io.user.po'; import MgmtUserResourceDetailPo from '@/cypress/e2e/po/detail/management.cattle.io.user.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import LinkPo from '@/cypress/e2e/po/components/link.po'; +import ClusterPage from '@/cypress/e2e/po/pages/cluster-page.po'; -export default class UsersPo extends PagePo { - private static createPath(clusterId: string) { - return `/c/${ clusterId }/auth/management.cattle.io.user`; - } - +export default class UsersPo extends ClusterPage { static goTo(path: string): Cypress.Chainable { throw new Error('invalid'); } @@ -24,7 +20,7 @@ export default class UsersPo extends PagePo { } constructor(private clusterId = '_') { - super(UsersPo.createPath(clusterId)); + super(clusterId, 'auth/management.cattle.io.user'); } waitForRequests() { diff --git a/cypress/e2e/po/prompts/genericPrompt.po.ts b/cypress/e2e/po/prompts/genericPrompt.po.ts new file mode 100644 index 00000000000..65f816bb796 --- /dev/null +++ b/cypress/e2e/po/prompts/genericPrompt.po.ts @@ -0,0 +1,22 @@ +import ComponentPo from '@/cypress/e2e/po/components/component.po'; +import CardPo from '@/cypress/e2e/po/components/card.po'; + +export default class GenericPrompt extends ComponentPo { + card = new CardPo(); + + getTitle() { + return this.card.getTitle(); + } + + getBody() { + return this.card.getBody(); + } + + cancel() { + return this.self().find('.btn role-secondary'); + } + + submit(text: string) { + return this.card.getActionButton().contains(text).click(); + } +} diff --git a/cypress/e2e/tests/pages/explorer/dashboard/cluster-dashboard.spec.ts b/cypress/e2e/tests/pages/explorer/dashboard/cluster-dashboard.spec.ts index f82b39e80c9..8e9cee4ffbb 100644 --- a/cypress/e2e/tests/pages/explorer/dashboard/cluster-dashboard.spec.ts +++ b/cypress/e2e/tests/pages/explorer/dashboard/cluster-dashboard.spec.ts @@ -246,7 +246,7 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi events.sortableTable().rowElements().should('have.length.gte', 2); }); - it('can view events table empty if no events', { tags: ['@vai'] }, () => { + it('can view events table empty if no events', { tags: ['@vai', '@adminUser'] }, () => { const events = new EventsPagePo('local'); HomePagePo.goTo(); diff --git a/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts b/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts index 4e8020528d8..e8a6ddeef1f 100644 --- a/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts +++ b/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts @@ -11,7 +11,7 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { const uniquePod = 'aaa-e2e-test-pod-name'; const podNamesList = []; let nsName1: string; @@ -146,8 +146,6 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, }); it('sorting changes the order of paginated events data', () => { - ClusterDashboardPagePo.navTo(); - clusterDashboard.waitForPage(undefined, 'cluster-events'); EventsPagePo.navTo(); events.waitForPage(); @@ -178,9 +176,7 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, it('pagination is hidden', () => { // generate small set of events data generateEventsDataSmall(); - ClusterDashboardPagePo.navTo(); - clusterDashboard.waitForPage(undefined, 'cluster-events'); - EventsPagePo.navTo(); + events.goTo(); events.waitForPage(); cy.wait('@eventsDataSmall'); diff --git a/cypress/e2e/tests/pages/explorer/more-resources/api/custom-resource-definitions.spec.ts b/cypress/e2e/tests/pages/explorer/more-resources/api/custom-resource-definitions.spec.ts index 91a555f7099..b6fd68d9d4e 100644 --- a/cypress/e2e/tests/pages/explorer/more-resources/api/custom-resource-definitions.spec.ts +++ b/cypress/e2e/tests/pages/explorer/more-resources/api/custom-resource-definitions.spec.ts @@ -12,9 +12,9 @@ describe('CustomResourceDefinitions', { testIsolation: 'off', tags: ['@explorer' cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { it('can create a crd and see it in list view', () => { - CustomResourceDefinitionsPagePo.navTo(); + crdsPage.goTo(); crdsPage.waitForPage(); crdsPage.create(); @@ -53,7 +53,7 @@ describe('CustomResourceDefinitions', { testIsolation: 'off', tags: ['@explorer' cy.getRancherResource('v1', 'apiextensions.k8s.io.customresourcedefinitions').then((resp: Cypress.Response) => { const count = resp.body.count; - CustomResourceDefinitionsPagePo.navTo(); + crdsPage.goTo(); // Remove any odd state from previous create (which can result in additional table row not from backend) crdsPage.waitForPage(); // pagination is visible @@ -128,7 +128,8 @@ describe('CustomResourceDefinitions', { testIsolation: 'off', tags: ['@explorer' it('sorting changes the order of paginated CRDs data', () => { CustomResourceDefinitionsPagePo.navTo(); crdsPage.waitForPage(); - crdsPage.sortableTable().checkLoadingIndicatorNotVisible(); + crdsPage.sortableTable().checkVisible(); + crdsPage.sortableTable().checkNoRowsNotVisible(); let indexBeforeSort: number; @@ -170,10 +171,10 @@ describe('CustomResourceDefinitions', { testIsolation: 'off', tags: ['@explorer' crdsPage.sortableTable().checkRowCount(false, 2); crdsPage.sortableTable().pagination().checkNotExists(); }); - }); - after('clean up', () => { - // delete crd - cy.deleteRancherResource('v1', 'apiextensions.k8s.io.customresourcedefinitions', crdName); + after('clean up', () => { + // delete crd + cy.deleteRancherResource('v1', 'apiextensions.k8s.io.customresourcedefinitions', crdName); + }); }); }); diff --git a/cypress/e2e/tests/pages/explorer/more-resources/core/service-accounts.spec.ts b/cypress/e2e/tests/pages/explorer/more-resources/core/service-accounts.spec.ts index 1695741c4ee..95bc134c8a3 100644 --- a/cypress/e2e/tests/pages/explorer/more-resources/core/service-accounts.spec.ts +++ b/cypress/e2e/tests/pages/explorer/more-resources/core/service-accounts.spec.ts @@ -8,7 +8,7 @@ describe('Service Accounts', { testIsolation: 'off', tags: ['@explorer', '@admin cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/more-resources/fleet/contents.spec.ts b/cypress/e2e/tests/pages/explorer/more-resources/fleet/contents.spec.ts index 4e6e5a1f3a7..33820f5d912 100644 --- a/cypress/e2e/tests/pages/explorer/more-resources/fleet/contents.spec.ts +++ b/cypress/e2e/tests/pages/explorer/more-resources/fleet/contents.spec.ts @@ -8,7 +8,7 @@ describe('Contents', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] } cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { it('validate fleet contents table in empty state', () => { fleetContentsNoData(); contentsPagePo.goTo(); diff --git a/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-role-bindings.spec.ts b/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-role-bindings.spec.ts index 2ff699c2891..8bab7f770c9 100644 --- a/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-role-bindings.spec.ts +++ b/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-role-bindings.spec.ts @@ -8,7 +8,7 @@ describe('ClusterRoleBindings', { testIsolation: 'off', tags: ['@explorer', '@ad cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { it('validate cluster role bindings table in empty state', () => { clusterRoleBindingNoData(); clusterRoleBindingsPage.goTo(); diff --git a/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-roles.spec.ts b/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-roles.spec.ts index 93b2305696a..5ae3b544d06 100644 --- a/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-roles.spec.ts +++ b/cypress/e2e/tests/pages/explorer/more-resources/rbac/cluster-roles.spec.ts @@ -8,7 +8,7 @@ describe('ClusterRoles', { testIsolation: 'off', tags: ['@explorer', '@adminUser cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { it('validate cluster roles table in empty state', () => { clusterRolesNoData(); clusterRolesPage.goTo(); diff --git a/cypress/e2e/tests/pages/explorer/more-resources/rbac/role-bindings.spec.ts b/cypress/e2e/tests/pages/explorer/more-resources/rbac/role-bindings.spec.ts index b980c7a9449..b584378525c 100644 --- a/cypress/e2e/tests/pages/explorer/more-resources/rbac/role-bindings.spec.ts +++ b/cypress/e2e/tests/pages/explorer/more-resources/rbac/role-bindings.spec.ts @@ -8,7 +8,7 @@ describe('RoleBindings', { testIsolation: 'off', tags: ['@explorer', '@adminUser cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/more-resources/rbac/roles.spec.ts b/cypress/e2e/tests/pages/explorer/more-resources/rbac/roles.spec.ts index 280e67fee57..766a398ec44 100644 --- a/cypress/e2e/tests/pages/explorer/more-resources/rbac/roles.spec.ts +++ b/cypress/e2e/tests/pages/explorer/more-resources/rbac/roles.spec.ts @@ -8,7 +8,7 @@ describe('Roles', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, ( cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/service-discovery/horizontal-pod-autoscalers.spec.ts b/cypress/e2e/tests/pages/explorer/service-discovery/horizontal-pod-autoscalers.spec.ts index 8b1159696fa..a24e4939622 100644 --- a/cypress/e2e/tests/pages/explorer/service-discovery/horizontal-pod-autoscalers.spec.ts +++ b/cypress/e2e/tests/pages/explorer/service-discovery/horizontal-pod-autoscalers.spec.ts @@ -8,7 +8,7 @@ describe('HorizontalPodAutoscalers', { testIsolation: 'off', tags: ['@explorer', cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/service-discovery/ingress.spec.ts b/cypress/e2e/tests/pages/explorer/service-discovery/ingress.spec.ts index c1132dc7a8d..6797ab0f95d 100644 --- a/cypress/e2e/tests/pages/explorer/service-discovery/ingress.spec.ts +++ b/cypress/e2e/tests/pages/explorer/service-discovery/ingress.spec.ts @@ -24,7 +24,7 @@ describe('Ingresses', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] cy.get('@consoleWarn').should('not.be.calledWith', warnMsg); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/service-discovery/services.spec.ts b/cypress/e2e/tests/pages/explorer/service-discovery/services.spec.ts index 7e60e4b8c13..ffd4164cf0c 100644 --- a/cypress/e2e/tests/pages/explorer/service-discovery/services.spec.ts +++ b/cypress/e2e/tests/pages/explorer/service-discovery/services.spec.ts @@ -8,7 +8,7 @@ describe('Services', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] } cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/storage/persistent-volume-claims.spec.ts b/cypress/e2e/tests/pages/explorer/storage/persistent-volume-claims.spec.ts index 924177fd020..bb14d90bf48 100644 --- a/cypress/e2e/tests/pages/explorer/storage/persistent-volume-claims.spec.ts +++ b/cypress/e2e/tests/pages/explorer/storage/persistent-volume-claims.spec.ts @@ -8,7 +8,7 @@ describe('PersistentVolumeClaims', { testIsolation: 'off', tags: ['@explorer', ' cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/storage/persistent-volumes.spec.ts b/cypress/e2e/tests/pages/explorer/storage/persistent-volumes.spec.ts index 1c2e943f6b9..e13df1d4f43 100644 --- a/cypress/e2e/tests/pages/explorer/storage/persistent-volumes.spec.ts +++ b/cypress/e2e/tests/pages/explorer/storage/persistent-volumes.spec.ts @@ -8,7 +8,7 @@ describe('PersistentVolumes', { testIsolation: 'off', tags: ['@explorer', '@admi cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/storage/storage-classes.spec.ts b/cypress/e2e/tests/pages/explorer/storage/storage-classes.spec.ts index 2aa73f3b57b..83c630fdda5 100644 --- a/cypress/e2e/tests/pages/explorer/storage/storage-classes.spec.ts +++ b/cypress/e2e/tests/pages/explorer/storage/storage-classes.spec.ts @@ -8,7 +8,7 @@ describe('StorageClasses', { testIsolation: 'off', tags: ['@explorer', '@adminUs cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before('set up', () => { cy.updateNamespaceFilter('local', 'none', '{\"local\":[]}'); }); diff --git a/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts b/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts index 8fe4312bcc3..2868327d69f 100644 --- a/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts +++ b/cypress/e2e/tests/pages/explorer/workloads/pods.spec.ts @@ -12,7 +12,7 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, () cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { const uniquePod = 'aaa-e2e-test-pod-name'; const podNamesList = []; let nsName1: string; diff --git a/cypress/e2e/tests/pages/fleet/advanced/bundles.spec.ts b/cypress/e2e/tests/pages/fleet/advanced/bundles.spec.ts index 0d4f3134dfb..ae495d0e397 100644 --- a/cypress/e2e/tests/pages/fleet/advanced/bundles.spec.ts +++ b/cypress/e2e/tests/pages/fleet/advanced/bundles.spec.ts @@ -10,7 +10,7 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () const fleetBundles = new FleetBundlesListPagePo(); const headerPo = new HeaderPo(); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before(() => { cy.login(); }); diff --git a/cypress/e2e/tests/pages/fleet/advanced/cluster-registration-tokens.spec.ts b/cypress/e2e/tests/pages/fleet/advanced/cluster-registration-tokens.spec.ts index 11595cdb7b7..acb461d9677 100644 --- a/cypress/e2e/tests/pages/fleet/advanced/cluster-registration-tokens.spec.ts +++ b/cypress/e2e/tests/pages/fleet/advanced/cluster-registration-tokens.spec.ts @@ -8,7 +8,7 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet', const fleetTokensPage = new FleetClusterRegistrationTokenListPagePo(); const headerPo = new HeaderPo(); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before(() => { cy.login(); }); diff --git a/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts b/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts index f431ef41fd3..b79155a2632 100644 --- a/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts +++ b/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts @@ -12,7 +12,7 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, cy.login(); }); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { it('check table headers are available in list and details view', () => { FleetWorkspaceListPagePo.navTo(); fleetWorkspacesPage.waitForPage(); diff --git a/cypress/e2e/tests/pages/fleet/cluster-groups.spec.ts b/cypress/e2e/tests/pages/fleet/cluster-groups.spec.ts index 2c3a4111d64..41a5d9907a5 100644 --- a/cypress/e2e/tests/pages/fleet/cluster-groups.spec.ts +++ b/cypress/e2e/tests/pages/fleet/cluster-groups.spec.ts @@ -6,7 +6,7 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser' const fleetClusterGroups = new FleetClusterGroupsListPagePo(); const headerPo = new HeaderPo(); - describe('List', { tags: ['@vai'] }, () => { + describe('List', { tags: ['@vai', '@adminUser'] }, () => { before(() => { cy.login(); }); diff --git a/cypress/e2e/tests/pages/fleet/fleet-clusters.spec.ts b/cypress/e2e/tests/pages/fleet/fleet-clusters.spec.ts index 76eed7451a0..c78f9562866 100644 --- a/cypress/e2e/tests/pages/fleet/fleet-clusters.spec.ts +++ b/cypress/e2e/tests/pages/fleet/fleet-clusters.spec.ts @@ -345,7 +345,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => { }); }); - it('check table headers are available in list and details view', { tags: ['@vai'] }, () => { + it('check table headers are available in list and details view', { tags: ['@vai', '@adminUser'] }, () => { const clusterName = 'local'; // create gitrepo diff --git a/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts b/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts index b331e387953..b707db16a82 100644 --- a/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts +++ b/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts @@ -144,7 +144,7 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ( ; }); - it('check table headers are available in list and details view', { tags: ['@vai'] }, function() { + it('check table headers are available in list and details view', { tags: ['@vai', '@adminUser'] }, function() { const workspace = 'fleet-default'; // go to fleet gitrepo diff --git a/cypress/e2e/tests/pages/global-settings/peformance.spec.ts b/cypress/e2e/tests/pages/global-settings/peformance.spec.ts index d5bcf3ee0ca..fb6f1d8ef4f 100644 --- a/cypress/e2e/tests/pages/global-settings/peformance.spec.ts +++ b/cypress/e2e/tests/pages/global-settings/peformance.spec.ts @@ -1,6 +1,5 @@ import { PerformancePagePo } from '@/cypress/e2e/po/pages/global-settings/performance.po'; import HomePagePo from '@/cypress/e2e/po/pages/home.po'; -import CardPo from '@/cypress/e2e/po/components/card.po'; const performancePage = new PerformancePagePo(); const performanceSettingsOrginal = []; @@ -169,10 +168,8 @@ describe('Performance', { testIsolation: 'off', tags: ['@globalSettings', '@admi performancePage.namespaceFilteringCheckbox().isUnchecked(); performancePage.namespaceFilteringCheckbox().set(); - const cardPo = new CardPo(); - - cardPo.getBody().contains('Required Namespace / Project Filtering is incomaptible with Manual Refresh and Incremental Loading. Enabling this will disable them.'); - cardPo.getActionButton().contains('Enable').click(); + performancePage.incompatibleModal().getBody().contains('Required Namespace / Project Filtering is incompatible with Manual Refresh and Incremental Loading. Enabling this will disable them.'); + performancePage.incompatibleModal().submit('Enable'); performancePage.namespaceFilteringCheckbox().isChecked(); performancePage.applyAndWait('forceNsFilterV2-true').then(({ request, response }) => { expect(response?.statusCode).to.eq(200); diff --git a/cypress/e2e/tests/pages/user-menu/account-api-keys.spec.ts b/cypress/e2e/tests/pages/user-menu/account-api-keys.spec.ts index 956b7a8e3d2..257c56718de 100644 --- a/cypress/e2e/tests/pages/user-menu/account-api-keys.spec.ts +++ b/cypress/e2e/tests/pages/user-menu/account-api-keys.spec.ts @@ -260,9 +260,9 @@ describe('Account and API Keys', { testIsolation: 'off' }, () => { accountPage.sortableTable().checkRowCount(false, 3); accountPage.sortableTable().pagination().checkNotExists(); }); - }); - after(() => { - tokenIdsList.forEach((r) => cy.deleteRancherResource('v3', 'tokens', r, false)); + after(() => { + tokenIdsList.forEach((r) => cy.deleteRancherResource('v3', 'tokens', r, false)); + }); }); }); diff --git a/cypress/e2e/tests/pages/users-and-auth/roles.spec.ts b/cypress/e2e/tests/pages/users-and-auth/roles.spec.ts index 69cd1bc717c..2c21c6df98c 100644 --- a/cypress/e2e/tests/pages/users-and-auth/roles.spec.ts +++ b/cypress/e2e/tests/pages/users-and-auth/roles.spec.ts @@ -6,18 +6,18 @@ import * as path from 'path'; import * as jsyaml from 'js-yaml'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import { generateGlobalRolesDataSmall } from '@/cypress/e2e/blueprints/roles/global-roles-get'; -import HomePagePo from '@/cypress/e2e/po/pages/home.po'; +import { BLANK_CLUSTER } from '@shell/store/store-types.js'; -const roles = new RolesPo('_'); -const usersPo = new UsersPo('_'); +const roles = new RolesPo(BLANK_CLUSTER); +const usersPo = new UsersPo(BLANK_CLUSTER); const userCreate = usersPo.createEdit(); const sideNav = new ProductNavPo(); const downloadsFolder = Cypress.config('downloadsFolder'); -let runTimestamp; -let runPrefix; -let globalRoleName; +let runTimestamp: number; +let runPrefix: string; +let globalRoleName: string; describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { describe('Roles', () => { @@ -25,9 +25,10 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { cy.login(); cy.viewport(1280, 720); }); + it('can create a Global Role', () => { - // We want to define these here because if this test fails after it created the global role all subsequent - // retries will reference the wrong global-role because a second roll will with the same name but different id will be created + // We want to define these here because if this test fails after it created the global role all subsequent + // retries will reference the wrong global-role because a second roll will with the same name but different id will be created runTimestamp = +new Date(); runPrefix = `e2e-test-${ runTimestamp }`; globalRoleName = `${ runPrefix }-my-global-role`; @@ -221,7 +222,7 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { }); }); - describe('List', { testIsolation: 'off', tags: ['@vai'] }, () => { + describe('List', { testIsolation: 'off', tags: ['@vai', '@adminUser'] }, () => { const uniqueRoleName = 'aaa-e2e-test-name'; const globalRolesIdsList = []; const rolesList = roles.list('GLOBAL'); @@ -257,6 +258,7 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { cy.getRancherResource('v1', 'management.cattle.io.globalroles').then((resp: Cypress.Response) => { const count = resp.body.count; + usersPo.goTo(); // This is needed for the @vai only world RolesPo.navTo(); roles.waitForPage(); @@ -430,8 +432,9 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { it('pagination is hidden', () => { generateGlobalRolesDataSmall(); - HomePagePo.goTo(); // this is needed here for the intercept to work + usersPo.goTo(); // this is needed here for the intercept to work RolesPo.navTo(); + roles.waitForPage(); cy.wait('@globalRolesDataSmall'); rolesList.resourceTable().sortableTable().checkVisible(); diff --git a/cypress/e2e/tests/pages/users-and-auth/users.spec.ts b/cypress/e2e/tests/pages/users-and-auth/users.spec.ts index a00ff8409cf..4b53d06dc8d 100644 --- a/cypress/e2e/tests/pages/users-and-auth/users.spec.ts +++ b/cypress/e2e/tests/pages/users-and-auth/users.spec.ts @@ -4,7 +4,6 @@ import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; import * as jsyaml from 'js-yaml'; import * as path from 'path'; import { generateUsersDataSmall } from '@/cypress/e2e/blueprints/users/users-get'; -import HomePagePo from '@/cypress/e2e/po/pages/home.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; const usersPo = new UsersPo('_'); @@ -265,7 +264,7 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { }); }); - describe('List', { testIsolation: 'off', tags: ['@vai'] }, () => { + describe('List', { testIsolation: 'off', tags: ['@vai', '@adminUser'] }, () => { const uniqueUserName = 'aaa-e2e-test-name'; const userIdsList = []; @@ -296,7 +295,7 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { }); it('pagination is visible and user is able to navigate through users data', () => { - UsersPo.navTo(); + usersPo.goTo(); // This is needed for the @vai only world usersPo.waitForPage(); // get users count @@ -465,8 +464,9 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { it('pagination is hidden', () => { generateUsersDataSmall(); - HomePagePo.goTo(); // this is needed here for the intercept to work + usersPo.goTo(); // this is needed here for the intercept to work UsersPo.navTo(); + usersPo.waitForPage(); cy.wait('@usersDataSmall'); usersPo.list().resourceTable().sortableTable().checkVisible(); diff --git a/cypress/e2e/tests/priority/vai-setup.spec.ts b/cypress/e2e/tests/priority/vai-setup.spec.ts new file mode 100644 index 00000000000..d97f388c634 --- /dev/null +++ b/cypress/e2e/tests/priority/vai-setup.spec.ts @@ -0,0 +1,42 @@ + +import HomePagePo from '@/cypress/e2e/po/pages/home.po'; +import { PerformancePagePo } from '@/cypress/e2e/po/pages/global-settings/performance.po'; +import { FeatureFlagsPagePo } from '@/cypress/e2e/po/pages/global-settings/feature-flags.po'; + +const performancePage = new PerformancePagePo('local'); +const featureFlagsPage = new FeatureFlagsPagePo('local'); + +describe('Setup Vai', { testIsolation: 'off', tags: ['@vai', '@adminUser'] }, () => { + before(() => { + cy.login(); + HomePagePo.goTo(); + }); + + it('Enable Feature Flag', () => { + FeatureFlagsPagePo.navTo(); + featureFlagsPage.waitForPage(); + + featureFlagsPage.list().details('ui-sql-cache', 0).should('include.text', 'Disabled'); + + featureFlagsPage.list().clickRowActionMenuItem('ui-sql-cache', 'Activate'); + featureFlagsPage.clickCardActionButtonAndWait('Activate', 'ui-sql-cache', true, { waitForModal: true, waitForRequest: true }); + + featureFlagsPage.list().details('ui-sql-cache', 0).should('include.text', 'Active'); + }); + + it('Enable Performance Setting', () => { + PerformancePagePo.navTo(); + performancePage.waitForPage(); + + performancePage.serverSidePaginationCheckbox().checkVisible(); + + performancePage.serverSidePaginationCheckbox().isUnchecked(); + performancePage.serverSidePaginationCheckbox().set(); + performancePage.serverSidePaginationCheckbox().isChecked(); + + performancePage.incompatibleModal().checkVisible(); + performancePage.incompatibleModal().submit('Enable'); + + performancePage.applyButton().click(); + }); +}); diff --git a/cypress/e2e/tests/setup/rancher-setup.spec.ts b/cypress/e2e/tests/setup/rancher-setup.spec.ts index 908543f3b65..067353090a7 100644 --- a/cypress/e2e/tests/setup/rancher-setup.spec.ts +++ b/cypress/e2e/tests/setup/rancher-setup.spec.ts @@ -6,7 +6,7 @@ import { serverUrlLocalhostCases, urlWithTrailingForwardSlash, httpUrl, nonUrlCa // Cypress or the GrepTags avoid to run multiples times the same test for each tag used. // This is a temporary solution till initialization is not handled as a test -describe('Rancher setup', { tags: ['@adminUserSetup', '@standardUserSetup', '@setup', '@components', '@navigation', '@charts', '@explorer', '@extensions', '@fleet', '@generic', '@globalSettings', '@manager', '@userMenu', '@usersAndAuths'] }, () => { +describe('Rancher setup', { tags: ['@adminUserSetup', '@standardUserSetup', '@setup', '@components', '@navigation', '@charts', '@explorer', '@extensions', '@fleet', '@generic', '@globalSettings', '@manager', '@userMenu', '@usersAndAuths', '@vai'] }, () => { const rancherSetupLoginPage = new RancherSetupLoginPagePo(); const rancherSetupConfigurePage = new RancherSetupConfigurePage(); const homePage = new HomePagePo(); diff --git a/shell/assets/translations/en-us.yaml b/shell/assets/translations/en-us.yaml index 2e869b2fbc4..26aea5e2b19 100644 --- a/shell/assets/translations/en-us.yaml +++ b/shell/assets/translations/en-us.yaml @@ -7402,7 +7402,7 @@ performance: When enabled, resources will appear more quickly, but it may take slightly longer to load the entire set of resources. This setting only applies to resources that come from the Kubernetes API checkboxLabel: Enable incremental loading inputLabel: Resource Threshold - incompatibleDescription: "Incremental Loading is incomaptible with Namespace/Project filtering and Server-side Pagination. Enabling this will disable them." + incompatibleDescription: "Incremental Loading is incompatible with Namespace/Project filtering and Server-side Pagination. Enabling this will disable them." manualRefresh: label: Manual Refresh setting: You can configure a threshold above which manual refresh will be enabled. @@ -7411,7 +7411,7 @@ performance: When enabled, list data will not auto-update but instead the user must manually trigger a list-view refresh. This setting only applies to resources that come from the Kubernetes API checkboxLabel: Enable manual refresh of data for lists inputLabel: Resource Threshold - incompatibleDescription: "Manual Refresh is incomaptible with Namespace/Project filtering and Server-side Pagination. Enabling this will disable them." + incompatibleDescription: "Manual Refresh is incompatible with Namespace/Project filtering and Server-side Pagination. Enabling this will disable them." websocketNotification: label: Websocket Notifications description: |- @@ -7442,7 +7442,7 @@ performance: label: Require Namespace / Project Filtering description: Require the user to select namespaces and/or projects. This restricts the number of resources fetched when viewing lists and should help the responsiveness of the UI in systems with a lot of resources. checkboxLabel: Enable Required Namespace / Project Filtering - incompatibleDescription: "Required Namespace / Project Filtering is incomaptible with Manual Refresh and Incremental Loading. Enabling this will disable them." + incompatibleDescription: "Required Namespace / Project Filtering is incompatible with Manual Refresh and Incremental Loading. Enabling this will disable them." advancedWorker: label: Websocket Web Worker description: Updates to resources pushed to the UI come via WebSocket and are handled in the UI thread. Enable this option to handle cluster WebSocket updates in a Web Worker in a separate thread. This should help the responsiveness of the UI in systems where resources change often. @@ -7459,7 +7459,7 @@ performance: description: By default Lists will fetch all resources and paginate in the browser (create the page given sorting and filtering settings). Change this setting to enable pagination server-side. This should help the responsiveness of the UI in systems with a lot of resources. checkboxLabel: Enable Server-side Pagination applicable: "This applies to the following resource types" - incompatibleDescription: "Server-side Pagination is incomaptible with Manual Refresh and Incremental Loading. Enabling this will disable them." + incompatibleDescription: "Server-side Pagination is incompatible with Manual Refresh and Incremental Loading. Enabling this will disable them." featureFlag: The Feature Flag `ui-sql-cache` must be enabled to use this feature resources: generic: most resources in the cluster's 'More Resources' section diff --git a/shell/pages/c/_cluster/settings/performance.vue b/shell/pages/c/_cluster/settings/performance.vue index 877e190767d..27a7e83d9a1 100644 --- a/shell/pages/c/_cluster/settings/performance.vue +++ b/shell/pages/c/_cluster/settings/performance.vue @@ -161,7 +161,7 @@ export default { return; } - // We're enabling a preference. Are there any incomaptible preferences? + // We're enabling a preference. Are there any incompatible preferences? if ((incompatible[property] || []).every((p) => !this.value[p].enabled)) { // No, just set and exit this.value[property].enabled = true;