diff --git a/cypress/e2e/tests/navigation/side-nav/main-side-menu.spec.ts b/cypress/e2e/tests/navigation/side-nav/main-side-menu.spec.ts index a26e141ce0..9c27cd6fbf 100644 --- a/cypress/e2e/tests/navigation/side-nav/main-side-menu.spec.ts +++ b/cypress/e2e/tests/navigation/side-nav/main-side-menu.spec.ts @@ -1,11 +1,8 @@ -import { CURRENT_RANCHER_VERSION } from '@shell/config/version.js'; import HomePagePo from '@/cypress/e2e/po/pages/home.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import PagePo from '@/cypress/e2e/po/pages/page.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; -import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po'; import { generateFakeClusterDataAndIntercepts } from '@/cypress/e2e/blueprints/nav/fake-cluster'; -import { RANCHER_PAGE_EXCEPTIONS, catchTargetPageException } from '@/cypress/support/utils/exception-utils'; const longClusterDescription = 'this-is-some-really-really-really-really-really-really-long-decription'; const fakeProvClusterId = 'some-fake-cluster-id'; @@ -47,32 +44,6 @@ describe('Side Menu: main', () => { cy.url().should('include', '/projectsnamespaces'); }); - // testing https://github.com/rancher/dashboard/issues/10192 - it('"documentation" link in editing a cluster should open in a new tab', { tags: ['@navigation', '@adminUser'] }, () => { - catchTargetPageException(RANCHER_PAGE_EXCEPTIONS); - - const page = new PagePo(''); - const clusterList = new ClusterManagerListPagePo('_'); - - page.navToMenuEntry('Cluster Management'); - clusterList.waitForPage(); - - clusterList.list().actionMenu(fakeProvClusterId).getMenuItem('Edit Config').click(); - - // since in Cypress we cannot assert directly a link on a new tab - // next best thing is to assert that the link has _blank - // change it to _seft, then assert the link of the new page - cy.get('[data-testid="edit-cluster-reprovisioning-documentation"] a').should('be.visible') - .then(($a) => { - expect($a).to.have.attr('target', '_blank'); - // update attr to open in same tab - $a.attr('target', '_self'); - }) - .click(); - - cy.url().should('include', `https://ranchermanager.docs.rancher.com/v${ CURRENT_RANCHER_VERSION }/how-to-guides/new-user-guides/launch-kubernetes-with-rancher/rke1-vs-rke2-differences#cluster-api`); - }); - it('Local cluster should show a name and description on the side menu and display a tooltip when hovering it show the full name and description', { tags: ['@navigation', '@adminUser'] }, () => { BurgerMenuPo.toggle(); diff --git a/cypress/e2e/tests/pages/explorer2/workloads/jobs.spec.ts b/cypress/e2e/tests/pages/explorer2/workloads/jobs.spec.ts index a7bff2a21b..872b5486d4 100644 --- a/cypress/e2e/tests/pages/explorer2/workloads/jobs.spec.ts +++ b/cypress/e2e/tests/pages/explorer2/workloads/jobs.spec.ts @@ -17,6 +17,9 @@ describe('Cluster Explorer', { tags: ['@explorer2', '@adminUser'] }, () => { }); it('Creating a job while creating a new namespace should succeed', () => { + cy.intercept('POST', 'v1/namespaces').as('createNamespace'); + cy.intercept('POST', 'v1/batch.jobs').as('createJob'); + // list view jobs const workloadsJobsListPage = new WorkloadsJobsListPagePo('local'); @@ -31,6 +34,8 @@ describe('Cluster Explorer', { tags: ['@explorer2', '@adminUser'] }, () => { workloadsJobDetailsPage.name().set(jobName); workloadsJobDetailsPage.containerImage().set(containerImageName); workloadsJobDetailsPage.saveCreateForm().click(); + cy.wait('@createNamespace').its('response.statusCode').should('eq', 201); + cy.wait('@createJob').its('response.statusCode').should('eq', 201); workloadsJobsListPage.listElementWithName(jobName).should('exist'); diff --git a/cypress/e2e/tests/pages/global-settings/feature-flags.spec.ts b/cypress/e2e/tests/pages/global-settings/feature-flags.spec.ts index 3ce9de27a1..016f1c49e2 100644 --- a/cypress/e2e/tests/pages/global-settings/feature-flags.spec.ts +++ b/cypress/e2e/tests/pages/global-settings/feature-flags.spec.ts @@ -133,6 +133,7 @@ describe('Feature Flags', { testIsolation: 'off' }, () => { featureFlagsPage.list().details('unsupported-storage-drivers', 0).should('include.text', 'Disabled'); // Activate + featureFlagsPage.list().elementWithName('unsupported-storage-drivers').scrollIntoView().should('be.visible'); featureFlagsPage.list().clickRowActionMenuItem('unsupported-storage-drivers', 'Activate'); featureFlagsPage.clickCardActionButtonAndWait('Activate', 'unsupported-storage-drivers', true); @@ -142,6 +143,7 @@ describe('Feature Flags', { testIsolation: 'off' }, () => { // Deactivate FeatureFlagsPagePo.navTo(); + featureFlagsPage.list().elementWithName('unsupported-storage-drivers').scrollIntoView().should('be.visible'); featureFlagsPage.list().clickRowActionMenuItem('unsupported-storage-drivers', 'Deactivate'); featureFlagsPage.clickCardActionButtonAndWait('Deactivate', 'unsupported-storage-drivers', false); diff --git a/cypress/e2e/tests/pages/global-settings/index.spec.ts b/cypress/e2e/tests/pages/global-settings/index.spec.ts index 81373d7b10..c6430a6fca 100644 --- a/cypress/e2e/tests/pages/global-settings/index.spec.ts +++ b/cypress/e2e/tests/pages/global-settings/index.spec.ts @@ -1,6 +1,6 @@ import PagePo from '@/cypress/e2e/po/pages/page.po'; -describe('Global Settings Index', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, () => { +describe('Global Settings Index', { testIsolation: 'off', tags: ['@globalSettings', '@adminUser'] }, () => { before(() => { cy.login(); }); diff --git a/cypress/e2e/tests/pages/manager/edit-fake-cluster.spec.ts b/cypress/e2e/tests/pages/manager/edit-fake-cluster.spec.ts index 02a8a410e6..51b0e27dc5 100644 --- a/cypress/e2e/tests/pages/manager/edit-fake-cluster.spec.ts +++ b/cypress/e2e/tests/pages/manager/edit-fake-cluster.spec.ts @@ -2,6 +2,9 @@ import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/clu import ClusterManagerEditGenericPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/edit/cluster-edit-generic.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import HomePagePo from '@/cypress/e2e/po/pages/home.po'; +import { RANCHER_PAGE_EXCEPTIONS, catchTargetPageException } from '@/cypress/support/utils/exception-utils'; +import { CURRENT_RANCHER_VERSION } from '@shell/config/version.js'; +import PagePo from '@/cypress/e2e/po/pages/page.po'; import { generateFakeClusterDataAndIntercepts } from '@/cypress/e2e/blueprints/nav/fake-cluster'; const fakeProvClusterId = 'some-fake-cluster-id'; @@ -38,5 +41,33 @@ describe('Cluster Edit', { tags: ['@manager', '@adminUser'] }, () => { // secrets need to be populated also, check fake-cluster -> INTERCEPT -> cy.intercept('GET', `/v1/secrets?*` ....) editCluster.registryAuthenticationField().checkOptionSelected('registryconfig-auth-reg2 (HTTP Basic Auth: aaa)'); }); + + // testing https://github.com/rancher/dashboard/issues/10192 + it('"documentation" link in editing a cluster should open in a new tab', () => { + HomePagePo.goTo(); + + catchTargetPageException(RANCHER_PAGE_EXCEPTIONS); + + const page = new PagePo(''); + const clusterList = new ClusterManagerListPagePo('_'); + + page.navToMenuEntry('Cluster Management'); + clusterList.waitForPage(); + + clusterList.list().actionMenu(fakeProvClusterId).getMenuItem('Edit Config').click(); + + // since in Cypress we cannot assert directly a link on a new tab + // next best thing is to assert that the link has _blank + // change it to _seft, then assert the link of the new page + cy.get('[data-testid="edit-cluster-reprovisioning-documentation"] a').should('be.visible') + .then(($a) => { + expect($a).to.have.attr('target', '_blank'); + // update attr to open in same tab + $a.attr('target', '_self'); + }) + .click(); + + cy.url().should('include', `https://ranchermanager.docs.rancher.com/v${ CURRENT_RANCHER_VERSION }/how-to-guides/new-user-guides/launch-kubernetes-with-rancher/rke1-vs-rke2-differences#cluster-api`); + }); }); }); diff --git a/cypress/e2e/tests/pages/manager/jwt-authentication.spec.ts b/cypress/e2e/tests/pages/manager/jwt-authentication.spec.ts index 1e6d1f41f5..22be15c684 100644 --- a/cypress/e2e/tests/pages/manager/jwt-authentication.spec.ts +++ b/cypress/e2e/tests/pages/manager/jwt-authentication.spec.ts @@ -140,17 +140,12 @@ describe('JWT Authentication', { testIsolation: 'off', tags: ['@manager', '@admi after('clean up', () => { if (removeCluster0) { // delete cluster - cy.get('@rke2Ec2ClusterName0').then((name) => { - cy.deleteRancherResource('v1', `provisioning.cattle.io.clusters/${ namespace }`, name); - removeCluster0 = false; - }); + cy.deleteRancherResource('v1', `provisioning.cattle.io.clusters/${ namespace }`, instance0); } + if (removeCluster1) { // delete cluster - cy.get('@rke2Ec2ClusterName1').then((name) => { - cy.deleteRancherResource('v1', `provisioning.cattle.io.clusters/${ namespace }`, name); - removeCluster1 = false; - }); + cy.deleteRancherResource('v1', `provisioning.cattle.io.clusters/${ namespace }`, instance1); } }); }); diff --git a/cypress/e2e/tests/pages/users-and-auth/index.spec.ts b/cypress/e2e/tests/pages/users-and-auth/index.spec.ts index a58fa1eaaf..1043ba5aa5 100644 --- a/cypress/e2e/tests/pages/users-and-auth/index.spec.ts +++ b/cypress/e2e/tests/pages/users-and-auth/index.spec.ts @@ -12,17 +12,16 @@ function updateUserRetentionSetting(settingId, newValue) { }); } -describe('Auth Index', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, () => { +describe('Auth Index', { testIsolation: 'off' }, () => { const runTimestamp = +new Date(); const usernameBlock = `user_to_block_${ runTimestamp }`; - const usernameRetention = `user_retention_access_${ runTimestamp }`; const userIdsList = []; before(() => { cy.login(); }); - it('can redirect', () => { + it('can redirect', { tags: ['@usersAndAuths', '@adminUser'] }, () => { const page = new PagePo('/c/local/auth'); page.goTo(); @@ -30,160 +29,154 @@ describe('Auth Index', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] cy.url().should('includes', `${ Cypress.config().baseUrl }/c/local/auth/management.cattle.io.user`); }); - it('can navigate to user retention settings', () => { - const page = new PagePo('/c/local/auth'); + describe('User retention: admin user', { tags: ['@usersAndAuths', '@adminUser'] }, () => { + it('can navigate to user retention settings', () => { + const page = new PagePo('/c/local/auth'); - page.goTo(); + page.goTo(); - const usersPo = new UsersPo(); + const usersPo = new UsersPo(); - usersPo.userRetentionLink().click(); + usersPo.userRetentionLink().click(); - cy.url().should('includes', `${ Cypress.config().baseUrl }/c/local/auth/user.retention`); - }); - - it('save button should be disabled when form is invalid', () => { - const page = new PagePo('/c/local/auth/user.retention'); - - page.goTo(); - - const userRetentionPo = new UserRetentionPo(); - - userRetentionPo.disableAfterPeriodCheckbox().set(); - userRetentionPo.disableAfterPeriodInput().set('30d'); - - userRetentionPo.saveButton().expectToBeDisabled(); - }); - - it('save button should be enabled when form is valid', () => { - const page = new PagePo('/c/local/auth/user.retention'); - - page.goTo(); - - const userRetentionPo = new UserRetentionPo(); - - userRetentionPo.disableAfterPeriodCheckbox().set(); - userRetentionPo.disableAfterPeriodInput().set('300h'); - userRetentionPo.userRetentionCron().set('0 0 1 1 *'); - - userRetentionPo.saveButton().expectToBeEnabled(); - }); - - it('can save user retention settings', () => { - const page = new PagePo('/c/local/auth/user.retention'); - - page.goTo(); - - const userRetentionPo = new UserRetentionPo(); - - userRetentionPo.disableAfterPeriodCheckbox().set(); - userRetentionPo.disableAfterPeriodInput().set('300h'); - userRetentionPo.deleteAfterPeriodCheckbox().set(); - userRetentionPo.deleteAfterPeriodInput().set('600h'); - userRetentionPo.userRetentionCron().set('0 0 1 1 *'); - userRetentionPo.userLastLoginDefault().set('1718744536000'); - - userRetentionPo.saveButton().expectToBeEnabled(); - userRetentionPo.saveButton().click(); - - cy.url().should('include', '/management.cattle.io.user'); - - const usersPo = new UsersPo(); - - usersPo.userRetentionLink().checkVisible(); - usersPo.userRetentionLink().click(); - - userRetentionPo.disableAfterPeriodCheckbox().checkExists(); - userRetentionPo.disableAfterPeriodCheckbox().isChecked(); - userRetentionPo.disableAfterPeriodInput().value().should('equal', '300h'); - userRetentionPo.deleteAfterPeriodCheckbox().isChecked(); - userRetentionPo.deleteAfterPeriodInput().value().should('equal', '600h'); - userRetentionPo.userRetentionCron().value().should('equal', '0 0 1 1 *'); - userRetentionPo.userLastLoginDefault().value().should('equal', '1718744536000'); - }); - - it('setup a user account that will be blocked', () => { - const usersPo = new UsersPo(); - - cy.createUser({ - username: usernameBlock, - globalRole: { role: 'user' }, - projectRole: { - clusterId: 'local', - projectName: 'Default', - role: 'project-member', - } - }).then((resp: Cypress.Response) => { - const userId = resp.body.id; - - userIdsList.push(userId); + cy.url().should('includes', `${ Cypress.config().baseUrl }/c/local/auth/user.retention`); }); - // Initialize the retention settings in case they are not. + it('save button should be disabled when form is invalid', () => { + const page = new PagePo('/c/local/auth/user.retention'); - updateUserRetentionSetting('disable-inactive-user-after', '50h'); + page.goTo(); - updateUserRetentionSetting('user-retention-cron', '* * * * *'); + const userRetentionPo = new UserRetentionPo(); - updateUserRetentionSetting('delete-inactive-user-after', '500h'); + userRetentionPo.disableAfterPeriodCheckbox().set(); + userRetentionPo.disableAfterPeriodInput().set('30d'); - usersPo.goTo(); - - usersPo.waitForPage(); - - // login as test user once to activate the retention - cy.login(usernameBlock, Cypress.env('password'), false); - }); - - it('verify the user account has countdown timers', () => { - const usersPo = new UsersPo(); - - cy.logout(); - cy.login(); - - usersPo.goTo(); - usersPo.waitForPage(); - - // Disable After - usersPo.list().resourceTable().sortableTable().rowWithPartialName(usernameBlock) - .column(7) - .should('not.eq', '-'); - - // Delete After - usersPo.list().resourceTable().sortableTable().rowWithPartialName(usernameBlock) - .column(8) - .should('not.eq', '-'); - }); - - it('standard user should not have access to user retention page', () => { - const usersPo = new UsersPo(); - - cy.createUser({ - username: usernameRetention, - globalRole: { role: 'user' }, - projectRole: { - clusterId: 'local', - projectName: 'Default', - role: 'project-member', - } - }).then((resp: Cypress.Response) => { - const userId = resp.body.id; - - userIdsList.push(userId); + userRetentionPo.saveButton().expectToBeDisabled(); }); - // logout from admin - cy.logout(); - cy.url().should('includes', `${ Cypress.config().baseUrl }/auth/login`); + it('save button should be enabled when form is valid', () => { + const page = new PagePo('/c/local/auth/user.retention'); - // login as test user - cy.login(usernameRetention, Cypress.env('password')); - usersPo.goTo(); - usersPo.waitForPage(); - usersPo.userRetentionLink().checkNotExists(); + page.goTo(); + + const userRetentionPo = new UserRetentionPo(); + + userRetentionPo.disableAfterPeriodCheckbox().set(); + userRetentionPo.disableAfterPeriodInput().set('300h'); + userRetentionPo.userRetentionCron().set('0 0 1 1 *'); + + userRetentionPo.saveButton().expectToBeEnabled(); + }); + + it('can save user retention settings', () => { + const page = new PagePo('/c/local/auth/user.retention'); + + page.goTo(); + + const userRetentionPo = new UserRetentionPo(); + + userRetentionPo.disableAfterPeriodCheckbox().set(); + userRetentionPo.disableAfterPeriodInput().set('300h'); + userRetentionPo.deleteAfterPeriodCheckbox().set(); + userRetentionPo.deleteAfterPeriodInput().set('600h'); + userRetentionPo.userRetentionCron().set('0 0 1 1 *'); + userRetentionPo.userLastLoginDefault().set('1718744536000'); + + userRetentionPo.saveButton().expectToBeEnabled(); + userRetentionPo.saveButton().click(); + + cy.url().should('include', '/management.cattle.io.user'); + + const usersPo = new UsersPo(); + + usersPo.userRetentionLink().checkVisible(); + usersPo.userRetentionLink().click(); + + userRetentionPo.disableAfterPeriodCheckbox().checkExists(); + userRetentionPo.disableAfterPeriodCheckbox().isChecked(); + userRetentionPo.disableAfterPeriodInput().value().should('equal', '300h'); + userRetentionPo.deleteAfterPeriodCheckbox().isChecked(); + userRetentionPo.deleteAfterPeriodInput().value().should('equal', '600h'); + userRetentionPo.userRetentionCron().value().should('equal', '0 0 1 1 *'); + userRetentionPo.userLastLoginDefault().value().should('equal', '1718744536000'); + }); + + it('setup a user account that will be blocked', () => { + const usersPo = new UsersPo(); + + cy.createUser({ + username: usernameBlock, + globalRole: { role: 'user' }, + projectRole: { + clusterId: 'local', + projectName: 'Default', + role: 'project-member', + } + }).then((resp: Cypress.Response) => { + const userId = resp.body.id; + + userIdsList.push(userId); + }); + + // Initialize the retention settings in case they are not. + + updateUserRetentionSetting('disable-inactive-user-after', '50h'); + + updateUserRetentionSetting('user-retention-cron', '* * * * *'); + + updateUserRetentionSetting('delete-inactive-user-after', '500h'); + + usersPo.goTo(); + + usersPo.waitForPage(); + + // login as test user once to activate the retention + cy.login(usernameBlock, Cypress.env('password'), false); + }); + + it('verify the user account has countdown timers', () => { + const usersPo = new UsersPo(); + + cy.logout(); + cy.login(); + + usersPo.goTo(); + usersPo.waitForPage(); + + // Disable After + usersPo.list().resourceTable().sortableTable().rowWithPartialName(usernameBlock) + .column(7) + .should('not.eq', '-'); + + // Delete After + usersPo.list().resourceTable().sortableTable().rowWithPartialName(usernameBlock) + .column(8) + .should('not.eq', '-'); + }); + + after(() => { + // reset user retention settings + updateUserRetentionSetting('disable-inactive-user-after', null); + + updateUserRetentionSetting('user-retention-cron', null); + + updateUserRetentionSetting('delete-inactive-user-after', null); + + // delete users + userIdsList.forEach((r) => cy.deleteRancherResource('v3', 'Users', r, false)); + }); }); - after(() => { - userIdsList.forEach((r) => cy.deleteRancherResource('v3', 'Users', r, false)); + describe('User retention: standard user', { tags: ['@usersAndAuths', '@standardUser'] }, () => { + it('standard user should not have access to user retention page', () => { + const usersPo = new UsersPo(); + + // login as standard user + cy.login(); + usersPo.goTo(); + usersPo.waitForPage(); + usersPo.userRetentionLink().checkNotExists(); + }); }); }); diff --git a/cypress/jenkins/init.sh b/cypress/jenkins/init.sh index ea8b9e1a39..e1d7a22356 100755 --- a/cypress/jenkins/init.sh +++ b/cypress/jenkins/init.sh @@ -213,8 +213,7 @@ fi echo "Rancher type: ${RANCHER_TYPE}" -override_node=$(semver lt "${RANCHER_VERSION}" "2.9.99") -if [[ ${override_node} -eq 0 && "${RANCHER_IMAGE_TAG}" != "head" ]]; then NODEJS_VERSION="16.20.2"; fi +if semver lt "${RANCHER_VERSION}" "2.9.99" && [[ "${RANCHER_IMAGE_TAG}" != "head" ]]; then NODEJS_VERSION="16.20.2"; fi corral config vars set rancher_type "${RANCHER_TYPE}" corral config vars set nodejs_version "${NODEJS_VERSION}"