diff --git a/cypress/e2e/blueprints/blueprint.utils.ts b/cypress/e2e/blueprints/blueprint.utils.ts new file mode 100644 index 00000000000..e6ac6cae1da --- /dev/null +++ b/cypress/e2e/blueprints/blueprint.utils.ts @@ -0,0 +1 @@ +export const CYPRESS_SAFE_RESOURCE_REVISION = 999999999; diff --git a/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts b/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts index d817fce64fc..03013093d8c 100644 --- a/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts +++ b/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + export const createPayloadData = { id: 'e2e-pod-security-admission-1705617529465', type: 'management.cattle.io.podsecurityadmissionconfigurationtemplate', @@ -12,7 +14,7 @@ export const createPayloadData = { }, kind: 'PodSecurityAdmissionConfigurationTemplate', metadata: { - fields: ['e2e-pod-security-admission-1705617529465', '18s'], name: 'e2e-pod-security-admission-1705617529465', resourceVersion: '831667' + fields: ['e2e-pod-security-admission-1705617529465', '18s'], name: 'e2e-pod-security-admission-1705617529465', resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION }, description: 'e2e-pod-security-admission-1705617529465-description' }; @@ -31,7 +33,7 @@ export const updatePayloadData = { }, kind: 'PodSecurityAdmissionConfigurationTemplate', metadata: { - fields: ['e2e-pod-security-admission-1705628550961', '7s'], name: 'e2e-pod-security-admission-1705628550961', resourceVersion: '938739' + fields: ['e2e-pod-security-admission-1705628550961', '7s'], name: 'e2e-pod-security-admission-1705628550961', resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION }, description: 'e2e-pod-security-admission-1705628550961-description-edit' }; diff --git a/cypress/e2e/blueprints/explorer/cluster/events.ts b/cypress/e2e/blueprints/explorer/cluster/events.ts index 32e7cf41688..0d2ef6a86a9 100644 --- a/cypress/e2e/blueprints/explorer/cluster/events.ts +++ b/cypress/e2e/blueprints/explorer/cluster/events.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/events - return empty events data const eventsGetEmptyEventsSet = { type: 'collection', @@ -5,7 +7,7 @@ const eventsGetEmptyEventsSet = { createTypes: { event: `${ Cypress.env('api') }/v1/events` }, actions: {}, resourceType: 'event', - 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 + revision: CYPRESS_SAFE_RESOURCE_REVISION, // 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 +18,7 @@ const eventsGetResponseSmallSet = { createTypes: { event: `${ Cypress.env('api') }/v1/events` }, actions: {}, resourceType: 'event', - 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 + revision: CYPRESS_SAFE_RESOURCE_REVISION, // 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: [ { @@ -40,7 +42,7 @@ const eventsGetResponseSmallSet = { name: 'fleet-agent-0.17d80b90a6d2c7ab', namespace: 'cattle-fleet-local-system', relationships: null, - resourceVersion: '0', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -71,7 +73,7 @@ const eventsGetResponseSmallSet = { name: 'fleet-agent-0.17d80b90a6d2c7ab', namespace: 'cattle-fleet-local-system', relationships: null, - resourceVersion: '0', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -102,7 +104,7 @@ const eventsGetResponseSmallSet = { name: 'fleet-agent-0.17d80b90a6d2c7ab', namespace: 'cattle-fleet-local-system', relationships: null, - resourceVersion: '0', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/explorer/core/service-accounts-get.ts b/cypress/e2e/blueprints/explorer/core/service-accounts-get.ts index b6009faf76c..3b3d9226e17 100644 --- a/cypress/e2e/blueprints/explorer/core/service-accounts-get.ts +++ b/cypress/e2e/blueprints/explorer/core/service-accounts-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/serviceaccounts - return empty service accounts data const serviceAccGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const serviceAccGetResponseEmpty = { createTypes: { serviceaccount: 'https://yonasb29.qa.rancher.space/v1/serviceaccounts' }, actions: {}, resourceType: 'serviceaccount', - revision: '129651', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const serviceAcctResponseSmallSet = { createTypes: { serviceaccount: 'https://yonasb29.qa.rancher.space/v1/serviceaccounts' }, actions: {}, resourceType: 'serviceaccount', - revision: '129651', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 3, data: [ { @@ -55,7 +57,7 @@ const serviceAcctResponseSmallSet = { state: 'succeeded' } ], - resourceVersion: '7124', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -104,7 +106,7 @@ const serviceAcctResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '9344', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -165,7 +167,7 @@ const serviceAcctResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '9342', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/explorer/fleet/contents-get.ts b/cypress/e2e/blueprints/explorer/fleet/contents-get.ts index cc478e1acdf..d48ac3cb231 100644 --- a/cypress/e2e/blueprints/explorer/fleet/contents-get.ts +++ b/cypress/e2e/blueprints/explorer/fleet/contents-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/fleet.cattle.io.contents - return empty contents data const fleetContentsGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const fleetContentsGetResponseEmpty = { createTypes: { 'fleet.cattle.io.content': 'https://yonasb29head.qa.rancher.space/v1/fleet.cattle.io.contents' }, actions: {}, resourceType: 'fleet.cattle.io.content', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const fleetContentsResponseSmallSet = { createTypes: { 'fleet.cattle.io.content': 'https://yonasb29head.qa.rancher.space/v1/fleet.cattle.io.contents' }, actions: {}, resourceType: 'fleet.cattle.io.content', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 2, data: [ { @@ -41,7 +43,7 @@ const fleetContentsResponseSmallSet = { generation: 1, name: 's-65075fe21d0e5087693027a2fdbb5ed559295ed1ffeb5957f98d77decb4a5', relationships: null, - resourceVersion: '4380255', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -73,7 +75,7 @@ const fleetContentsResponseSmallSet = { generation: 1, name: 's-807cc7bcb0de2dae39c913c375f676238d021519258d34913ccc842519c63', relationships: null, - resourceVersion: '8041', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', 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 37ce83b7b69..9a4e4c6c775 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 @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + // GET /v1/apiextensions.k8s.io.customresourcedefinitions - small set of crds data const crdsGetResponseSmallSet = { type: 'collection', @@ -5,7 +7,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: 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 + revision: CYPRESS_SAFE_RESOURCE_REVISION, // 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: [ { @@ -28,7 +30,7 @@ const crdsGetResponseSmallSet = { generation: 1, name: 'users.management.cattle.io', relationships: null, - resourceVersion: '4473', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'CRD is established', @@ -129,7 +131,7 @@ const crdsGetResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '1417', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'CRD is established', diff --git a/cypress/e2e/blueprints/explorer/rbac/cluster-role-bindings-get.ts b/cypress/e2e/blueprints/explorer/rbac/cluster-role-bindings-get.ts index b00ce702991..cabd973eec5 100644 --- a/cypress/e2e/blueprints/explorer/rbac/cluster-role-bindings-get.ts +++ b/cypress/e2e/blueprints/explorer/rbac/cluster-role-bindings-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/rbac.authorization.k8s.io.clusterrolebinding - return empty cluster role binding data const clusterRoleBindingGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const clusterRoleBindingGetResponseEmpty = { createTypes: { 'rbac.authorization.k8s.io.clusterrolebinding': 'https://yonasb29head.qa.rancher.space/v1/rbac.authorization.k8s.io.clusterrolebindings' }, actions: {}, resourceType: 'rbac.authorization.k8s.io.clusterrolebinding', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const clusterRoleBindingResponseSmallSet = { createTypes: { 'rbac.authorization.k8s.io.clusterrolebinding': 'https://yonasb29head.qa.rancher.space/v1/rbac.authorization.k8s.io.clusterrolebindings' }, actions: {}, resourceType: 'rbac.authorization.k8s.io.clusterrolebinding', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 2, data: [ { @@ -58,7 +60,7 @@ const clusterRoleBindingResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '434584', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -118,7 +120,7 @@ const clusterRoleBindingResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '5149', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/explorer/rbac/cluster-roles-get.ts b/cypress/e2e/blueprints/explorer/rbac/cluster-roles-get.ts index 8067016d05a..ae554d62fe0 100644 --- a/cypress/e2e/blueprints/explorer/rbac/cluster-roles-get.ts +++ b/cypress/e2e/blueprints/explorer/rbac/cluster-roles-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/rbac.authorization.k8s.io.clusterrolebinding - return empty cluster roles data const clusterRolesGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const clusterRolesGetResponseEmpty = { createTypes: { 'rbac.authorization.k8s.io.clusterrole': 'https://yonasb29h3.qa.rancher.space/v1/rbac.authorization.k8s.io.clusterroles' }, actions: {}, resourceType: 'rbac.authorization.k8s.io.clusterrole', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const clusterRolesResponseSmallSet = { createTypes: { 'rbac.authorization.k8s.io.clusterrole': 'https://yonasb29h3.qa.rancher.space/v1/rbac.authorization.k8s.io.clusterroles' }, actions: {}, resourceType: 'rbac.authorization.k8s.io.clusterrole', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 2, data: [ { @@ -49,7 +51,7 @@ const clusterRolesResponseSmallSet = { labels: { 'kubernetes.io/bootstrapping': 'rbac-defaults' }, name: 'admin', relationships: null, - resourceVersion: '4878', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -94,7 +96,7 @@ const clusterRolesResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '4838', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/explorer/rbac/role-bindings-get.ts b/cypress/e2e/blueprints/explorer/rbac/role-bindings-get.ts index 0be3c32a317..62c88453890 100644 --- a/cypress/e2e/blueprints/explorer/rbac/role-bindings-get.ts +++ b/cypress/e2e/blueprints/explorer/rbac/role-bindings-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/rbac.authorization.k8s.io.rolebindings- return empty role binding data const roleBindingGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const roleBindingGetResponseEmpty = { createTypes: { 'rbac.authorization.k8s.io.rolebinding': 'https://yonasb29head.qa.rancher.space/v1/rbac.authorization.k8s.io.rolebindings' }, actions: {}, resourceType: 'rbac.authorization.k8s.io.rolebinding', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const roleBindingResponseSmallSet = { createTypes: { 'rbac.authorization.k8s.io.rolebinding': 'https://yonasb29head.qa.rancher.space/v1/rbac.authorization.k8s.io.rolebindings' }, actions: {}, resourceType: 'rbac.authorization.k8s.io.rolebinding', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 3, data: [ { @@ -66,7 +68,7 @@ const roleBindingResponseSmallSet = { message: 'Resource is current' } ], - resourceVersion: '445143', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -134,7 +136,7 @@ const roleBindingResponseSmallSet = { message: 'Resource is current' } ], - resourceVersion: '4386433', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -203,7 +205,7 @@ const roleBindingResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '5141', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/explorer/rbac/roles-get.ts b/cypress/e2e/blueprints/explorer/rbac/roles-get.ts index 8e938f3d15f..25181d3d231 100644 --- a/cypress/e2e/blueprints/explorer/rbac/roles-get.ts +++ b/cypress/e2e/blueprints/explorer/rbac/roles-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/rbac.authorization.k8s.io.roles - return empty roles data const rolesGetResponseEmpty = { type: 'collection', @@ -10,13 +12,13 @@ const rolesGetResponseEmpty = { }; // GET /v1/rbac.authorization.k8s.io.roles - small set of roles data -const rolesResponseSmallSet = { +const rolesResponseSmallSet = (namespace = 'kube-system') => ({ type: 'collection', links: { self: 'https://localhost:8005/v1/rbac.authorization.k8s.io.roles' }, createTypes: { 'rbac.authorization.k8s.io.role': 'https://localhost:8005/v1/rbac.authorization.k8s.io.roles' }, actions: {}, resourceType: 'rbac.authorization.k8s.io.role', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 2, data: [ { @@ -54,7 +56,7 @@ const rolesResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '6958', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -89,13 +91,13 @@ const rolesResponseSmallSet = { ] }, { - id: 'kube-system/extension-apiserver-authentication-reader', + id: `${ namespace }/extension-apiserver-authentication-reader`, type: 'rbac.authorization.k8s.io.role', links: { - remove: 'https://localhost:8005/v1/rbac.authorization.k8s.io.roles/kube-system/extension-apiserver-authentication-reader', - self: 'https://localhost:8005/v1/rbac.authorization.k8s.io.roles/kube-system/extension-apiserver-authentication-reader', - update: 'https://localhost:8005/v1/rbac.authorization.k8s.io.roles/kube-system/extension-apiserver-authentication-reader', - view: 'https://localhost:8005/apis/rbac.authorization.k8s.io/v1/namespaces/kube-system/roles/extension-apiserver-authentication-reader' + remove: `https://localhost:8005/v1/rbac.authorization.k8s.io.roles/${ namespace }/extension-apiserver-authentication-reader`, + self: `https://localhost:8005/v1/rbac.authorization.k8s.io.roles/${ namespace }/extension-apiserver-authentication-reader`, + update: `https://localhost:8005/v1/rbac.authorization.k8s.io.roles/${ namespace }/extension-apiserver-authentication-reader`, + view: `https://localhost:8005/apis/rbac.authorization.k8s.io/v1/namespaces/${ namespace }/roles/extension-apiserver-authentication-reader` }, apiVersion: 'rbac.authorization.k8s.io/v1', kind: 'Role', @@ -111,9 +113,9 @@ const rolesResponseSmallSet = { ], labels: { 'kubernetes.io/bootstrapping': 'rbac-defaults' }, name: 'extension-apiserver-authentication-reader', - namespace: 'kube-system', + namespace, relationships: null, - resourceVersion: '4825', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -142,7 +144,7 @@ const rolesResponseSmallSet = { ] }, ] -}; +}); function reply(statusCode: number, body: any) { return (req) => { @@ -157,6 +159,6 @@ export function rolesNoData(): Cypress.Chainable { return cy.intercept('GET', '/v1/rbac.authorization.k8s.io.roles?*', reply(200, rolesGetResponseEmpty)).as('rolesNoData'); } -export function generateRolesDataSmall(): Cypress.Chainable { - return cy.intercept('GET', '/v1/rbac.authorization.k8s.io.roles?*', reply(200, rolesResponseSmallSet)).as('rolesDataSmall'); +export function generateRolesDataSmall(as: string, namespace?: string): Cypress.Chainable { + return cy.intercept('GET', '/v1/rbac.authorization.k8s.io.roles?*', reply(200, rolesResponseSmallSet(namespace))).as(as); } diff --git a/cypress/e2e/blueprints/explorer/storage/persistent-volume-claims-get.ts b/cypress/e2e/blueprints/explorer/storage/persistent-volume-claims-get.ts index b753461715b..deed8ff5485 100644 --- a/cypress/e2e/blueprints/explorer/storage/persistent-volume-claims-get.ts +++ b/cypress/e2e/blueprints/explorer/storage/persistent-volume-claims-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/persistentvolumeclaim- return empty persistentvolumeclaims data const persistentvolumeclaimsGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const persistentvolumeclaimsGetResponseEmpty = { createTypes: { persistentvolumeclaim: 'https://yonasb29head.qa.rancher.space/v1/persistentvolumeclaims' }, actions: {}, resourceType: 'persistentvolumeclaim', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const persistentvolumeclaimsResponseSmallSet = { createTypes: { persistentvolumeclaim: 'https://yonasb29head.qa.rancher.space/v1/persistentvolumeclaims' }, actions: {}, resourceType: 'persistentvolumeclaim', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 1, data: [{ id: 'cattle-system/test', @@ -56,10 +58,10 @@ function reply(statusCode: number, body: any) { }; } -export function persistentVolumeClaimsNoData(): Cypress.Chainable { - return cy.intercept('GET', '/v1/persistentvolumeclaims?*', reply(200, persistentvolumeclaimsGetResponseEmpty)).as('persistentvolumeclaimsNoData'); +export function persistentVolumeClaimsNoData(tag: string): Cypress.Chainable { + return cy.intercept('GET', '/v1/persistentvolumeclaims?*', reply(200, persistentvolumeclaimsGetResponseEmpty)).as(tag); } -export function generatePersistentVolumeClaimsDataSmall(): Cypress.Chainable { - return cy.intercept('GET', '/v1/persistentvolumeclaims?*', reply(200, persistentvolumeclaimsResponseSmallSet)).as('persistentvolumeclaimsDataSmall'); +export function generatePersistentVolumeClaimsDataSmall(tag: string): Cypress.Chainable { + return cy.intercept('GET', '/v1/persistentvolumeclaims?*', reply(200, persistentvolumeclaimsResponseSmallSet)).as(tag); } diff --git a/cypress/e2e/blueprints/explorer/storage/persistent-volumes-get.ts b/cypress/e2e/blueprints/explorer/storage/persistent-volumes-get.ts index 8e6e7006c18..4db44a01697 100644 --- a/cypress/e2e/blueprints/explorer/storage/persistent-volumes-get.ts +++ b/cypress/e2e/blueprints/explorer/storage/persistent-volumes-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/persistentvolumes- return empty persistentvolumes data const persistentvolumesGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const persistentvolumesGetResponseEmpty = { createTypes: { persistentvolume: 'https://yonasb29head.qa.rancher.space/v1/persistentvolumes' }, actions: {}, resourceType: 'persistentvolume', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const persistentvolumesResponseSmallSet = { createTypes: { persistentvolume: 'https://yonasb29head.qa.rancher.space/v1/persistentvolumes' }, actions: {}, resourceType: 'persistentvolume', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 1, data: [{ id: 'test', diff --git a/cypress/e2e/blueprints/explorer/storage/storage-classes-get.ts b/cypress/e2e/blueprints/explorer/storage/storage-classes-get.ts index b713209f68d..23f4aba4932 100644 --- a/cypress/e2e/blueprints/explorer/storage/storage-classes-get.ts +++ b/cypress/e2e/blueprints/explorer/storage/storage-classes-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../blueprint.utils'; + // GET /v1/storage.k8s.io.storageclasses- return empty storageclasses data const pstorageclassesGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const pstorageclassesGetResponseEmpty = { createTypes: { 'storage.k8s.io.storageclass': 'https://yonasb29head.qa.rancher.space/v1/storage.k8s.io.storageclasses' }, actions: {}, resourceType: 'storage.k8s.io.storageclass', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const storageclassesResponseSmallSet = { createTypes: { 'storage.k8s.io.storageclass': 'https://yonasb29head.qa.rancher.space/v1/storage.k8s.io.storageclasses' }, actions: {}, resourceType: 'storage.k8s.io.storageclass', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 1, data: [{ id: 'test', diff --git a/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-create.ts b/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-create.ts index 3d34689b7a7..401b76a25cb 100644 --- a/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-create.ts +++ b/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-create.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + export const createDeploymentBlueprint = { apiVersion: 'apps/v1', kind: 'Deployment', @@ -209,7 +211,7 @@ export const deploymentCreateResponse = { rel: 'uses' } ], - resourceVersion: '12999795', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'replicas: 0/1', diff --git a/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-get.ts b/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-get.ts index 5518fe4f76e..50b0329fe33 100644 --- a/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-get.ts +++ b/cypress/e2e/blueprints/explorer/workloads/deployments/deployment-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + export const deploymentGetResponse = { id: 'default/test-deployment', links: { @@ -154,7 +156,7 @@ export const deploymentGetResponse = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '12999825', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', diff --git a/cypress/e2e/blueprints/explorer/workloads/deployments/deplyment-list.ts b/cypress/e2e/blueprints/explorer/workloads/deployments/deplyment-list.ts index 2ad01e3b301..5f3ef26fc8e 100644 --- a/cypress/e2e/blueprints/explorer/workloads/deployments/deplyment-list.ts +++ b/cypress/e2e/blueprints/explorer/workloads/deployments/deplyment-list.ts @@ -1,10 +1,12 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + export const deploymentCollection = { type: 'collection', links: { self: 'https://localhost:8005/v1/apps.deployments' }, createTypes: { 'apps.deployment': 'https://localhost:8005/v1/apps.deployments' }, actions: {}, resourceType: 'apps.deployment', - revision: '12999812', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 15, data: [ @@ -164,7 +166,7 @@ export const deploymentCollection = { transitioning: true } ], - resourceVersion: '12999806', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment does not have minimum availability.', @@ -255,7 +257,7 @@ export const deploymentCollectionResponseFull = { createTypes: { 'apps.deployment': 'https://localhost:8005/v1/apps.deployments' }, actions: {}, resourceType: 'apps.deployment', - revision: '12999812', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 15, data: [ { @@ -454,7 +456,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '6109', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -805,7 +807,7 @@ export const deploymentCollectionResponseFull = { state: 'deployed' } ], - resourceVersion: '3067', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -1112,7 +1114,7 @@ export const deploymentCollectionResponseFull = { state: 'deployed' } ], - resourceVersion: '3089', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -1391,7 +1393,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '787692', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -2064,7 +2066,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '787803', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -2703,7 +2705,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '787731', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -3085,7 +3087,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '12995749', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -3515,7 +3517,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '787962', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -3950,7 +3952,7 @@ export const deploymentCollectionResponseFull = { state: 'deployed' } ], - resourceVersion: '663180', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -4295,7 +4297,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '12900726', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', @@ -4560,7 +4562,7 @@ export const deploymentCollectionResponseFull = { transitioning: true } ], - resourceVersion: '12999806', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment does not have minimum availability.', @@ -4950,7 +4952,7 @@ export const deploymentCollectionResponseFull = { message: 'ReplicaSet is available. Replicas: 1' } ], - resourceVersion: '1377', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Deployment is available. Replicas: 1', diff --git a/cypress/e2e/blueprints/explorer/workloads/pods/pods-get.ts b/cypress/e2e/blueprints/explorer/workloads/pods/pods-get.ts index d7c4eb30cd5..f1d63e32cdc 100644 --- a/cypress/e2e/blueprints/explorer/workloads/pods/pods-get.ts +++ b/cypress/e2e/blueprints/explorer/workloads/pods/pods-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + // GET /v1/pods - small set of pods data const podsGetResponseSmallSet = { type: 'collection', @@ -49,7 +51,7 @@ const podsGetResponseSmallSet = { message: 'Resource is always ready' } ], - resourceVersion: '541786', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -248,7 +250,7 @@ const podsGetResponseSmallSet = { message: 'Resource is always ready' } ], - resourceVersion: '541885', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -447,7 +449,7 @@ const podsGetResponseSmallSet = { message: 'Resource is always ready' } ], - resourceVersion: '541968', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', diff --git a/cypress/e2e/blueprints/explorer/workloads/service-discovery/horizontal-pod-autoscalers-get.ts b/cypress/e2e/blueprints/explorer/workloads/service-discovery/horizontal-pod-autoscalers-get.ts index 1dda9af3597..51b7b030c25 100644 --- a/cypress/e2e/blueprints/explorer/workloads/service-discovery/horizontal-pod-autoscalers-get.ts +++ b/cypress/e2e/blueprints/explorer/workloads/service-discovery/horizontal-pod-autoscalers-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + // GET /v1/autoscaling.horizontalpodautoscalers - return empty horizontalpodautoscalers data const horizontalpodautoscalerGetResponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const horizontalpodautoscalerGetResponseEmpty = { createTypes: { 'autoscaling.horizontalpodautoscaler': 'https://yonasb29head.qa.rancher.space/v1/autoscaling.horizontalpodautoscalers' }, actions: {}, resourceType: 'autoscaling.horizontalpodautoscaler', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const horizontalpodautoscalerGetResponseSmallSet = { createTypes: { 'autoscaling.horizontalpodautoscaler': 'https://yonasb29head.qa.rancher.space/v1/autoscaling.horizontalpodautoscalers' }, actions: {}, resourceType: 'autoscaling.horizontalpodautoscaler', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 1, data: [ { diff --git a/cypress/e2e/blueprints/explorer/workloads/service-discovery/ingresses-get.ts b/cypress/e2e/blueprints/explorer/workloads/service-discovery/ingresses-get.ts index 6b81f17cdf1..037e4eb4e09 100644 --- a/cypress/e2e/blueprints/explorer/workloads/service-discovery/ingresses-get.ts +++ b/cypress/e2e/blueprints/explorer/workloads/service-discovery/ingresses-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + // GET /v1/networking.k8s.io.ingresses - return empty ingresses data const ingressesGetReponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const ingressesGetReponseEmpty = { createTypes: { 'networking.k8s.io.ingress': 'https://yonasb29head.qa.rancher.space/v1/networking.k8s.io.ingresses' }, actions: {}, resourceType: 'networking.k8s.io.ingress', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const ingressesGetResponseSmallSet = { createTypes: { 'networking.k8s.io.ingress': 'https://yonasb29head.qa.rancher.space/v1/networking.k8s.io.ingresses' }, actions: {}, resourceType: 'networking.k8s.io.ingress', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 2, data: [ { @@ -67,7 +69,7 @@ const ingressesGetResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '4941', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -140,7 +142,7 @@ const ingressesGetResponseSmallSet = { name: 'test', namespace: 'default', relationships: null, - resourceVersion: '5040682', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/explorer/workloads/service-discovery/services-get.ts b/cypress/e2e/blueprints/explorer/workloads/service-discovery/services-get.ts index e80930b2c8f..5b4edc0f6f4 100644 --- a/cypress/e2e/blueprints/explorer/workloads/service-discovery/services-get.ts +++ b/cypress/e2e/blueprints/explorer/workloads/service-discovery/services-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../../../blueprint.utils'; + // GET /v1/services - return empty services data const servicesGetReponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const servicesGetReponseEmpty = { createTypes: { service: 'https://yonasb29.qa.rancher.space/v1/services' }, actions: {}, resourceType: 'service', - revision: '80155', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const servicesGetResponseSmallSet = { createTypes: { service: 'https://yonasb29.qa.rancher.space/v1/services' }, actions: {}, resourceType: 'service', - revision: '80155', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 3, data: [ { @@ -76,7 +78,7 @@ const servicesGetResponseSmallSet = { message: 'Resource is current' } ], - resourceVersion: '4158', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Service is ready', @@ -165,7 +167,7 @@ const servicesGetResponseSmallSet = { state: 'deployed' } ], - resourceVersion: '8539', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Service is ready', @@ -227,7 +229,7 @@ const servicesGetResponseSmallSet = { name: 'kubernetes', namespace: 'default', relationships: null, - resourceVersion: '224', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Service is ready', diff --git a/cypress/e2e/blueprints/fleet/cluster-registration-tokens-get.ts b/cypress/e2e/blueprints/fleet/cluster-registration-tokens-get.ts index af8bf4348c6..13725a084e1 100644 --- a/cypress/e2e/blueprints/fleet/cluster-registration-tokens-get.ts +++ b/cypress/e2e/blueprints/fleet/cluster-registration-tokens-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + // GET /v1/fleet.cattle.io.clusterregistrationtokens - return empty clusterregistrationtokens data const clusterRegistrationTokensGetReponseEmpty = { type: 'collection', @@ -5,7 +7,7 @@ const clusterRegistrationTokensGetReponseEmpty = { createTypes: { 'fleet.cattle.io.clusterregistrationtoken': 'https://yonasb29h3.qa.rancher.space/v1/fleet.cattle.io.clusterregistrationtokens' }, actions: {}, resourceType: 'fleet.cattle.io.clusterregistrationtoken', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 0, data: [] }; @@ -17,7 +19,7 @@ const clusterRegistrationTokensGetResponseSmallSet = { createTypes: { 'fleet.cattle.io.clusterregistrationtoken': 'https://yonasb29h3.qa.rancher.space/v1/fleet.cattle.io.clusterregistrationtokens' }, actions: {}, resourceType: 'fleet.cattle.io.clusterregistrationtoken', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 1, data: [ { @@ -84,7 +86,7 @@ const clusterRegistrationTokensGetResponseSmallSet = { message: 'Resource is always ready' } ], - resourceVersion: '396332', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/fleet/workspaces-get.ts b/cypress/e2e/blueprints/fleet/workspaces-get.ts index c6e5fb922b9..ca55a53d013 100644 --- a/cypress/e2e/blueprints/fleet/workspaces-get.ts +++ b/cypress/e2e/blueprints/fleet/workspaces-get.ts @@ -1,10 +1,12 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + // GET /v1/management.cattle.io.fleetworkspaces - small set of fleet workspaces data const fleetworkspacesGetResponseSmallSet = { type: 'collection', links: { self: 'https://yonasb29h3.qa.rancher.space/v1/management.cattle.io.fleetworkspaces' }, actions: {}, resourceType: 'management.cattle.io.fleetworkspace', - revision: '123', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 2, data: [ { @@ -34,7 +36,7 @@ const fleetworkspacesGetResponseSmallSet = { state: 'active' } ], - resourceVersion: '4483', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -81,7 +83,7 @@ const fleetworkspacesGetResponseSmallSet = { state: 'active' } ], - resourceVersion: '5284', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/global_settings/home-links-response.ts b/cypress/e2e/blueprints/global_settings/home-links-response.ts index 43d1e7132b4..989b8bf3e86 100644 --- a/cypress/e2e/blueprints/global_settings/home-links-response.ts +++ b/cypress/e2e/blueprints/global_settings/home-links-response.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + export function applyCustomLinksResponse(customLinkName: string, customLinkUrl:string):object { return { id: 'ui-custom-links', @@ -36,7 +38,7 @@ export function applyCustomLinksResponse(customLinkName: string, customLinkUrl:s ], name: 'ui-custom-links', relationships: null, - resourceVersion: '820268', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -88,7 +90,7 @@ export function removeCustomLinksResponse():object { ], name: 'ui-custom-links', relationships: null, - resourceVersion: '820268', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/manager/digital-ocean-cluster-provisioning-response.ts b/cypress/e2e/blueprints/manager/digital-ocean-cluster-provisioning-response.ts index df6a176ac3f..0ea06f9de0a 100644 --- a/cypress/e2e/blueprints/manager/digital-ocean-cluster-provisioning-response.ts +++ b/cypress/e2e/blueprints/manager/digital-ocean-cluster-provisioning-response.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + export function clusterProvDigitalOceanSingleResponse(clusterName: string, cloudCredName: string, machinePoolId: string):object { return { type: 'collection', @@ -5,7 +7,7 @@ export function clusterProvDigitalOceanSingleResponse(clusterName: string, cloud createTypes: { 'provisioning.cattle.io.cluster': 'https://localhost:8005/v1/provisioning.cattle.io.clusters' }, actions: {}, resourceType: 'provisioning.cattle.io.cluster', - revision: '9258713', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 9, data: [ { @@ -145,7 +147,7 @@ export function clusterProvDigitalOceanSingleResponse(clusterName: string, cloud message: 'Resource is always ready' } ], - resourceVersion: '9258672', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is Ready', diff --git a/cypress/e2e/blueprints/manager/machine-pool-config-response.ts b/cypress/e2e/blueprints/manager/machine-pool-config-response.ts index 92fa33e7430..ab86dc70ed1 100644 --- a/cypress/e2e/blueprints/manager/machine-pool-config-response.ts +++ b/cypress/e2e/blueprints/manager/machine-pool-config-response.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + export function machinePoolConfigResponse(clusterName:string, machinePoolId:string ):object { return { id: `fleet-default/nc-${ clusterName }-pool1-${ machinePoolId }`, @@ -62,7 +64,7 @@ export function machinePoolConfigResponse(clusterName:string, machinePoolId:stri message: 'Resource is current' } ], - resourceVersion: '9683918', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/nav/edit-cluster.ts b/cypress/e2e/blueprints/nav/edit-cluster.ts index 49ac529fed3..fb90d99f6bb 100644 --- a/cypress/e2e/blueprints/nav/edit-cluster.ts +++ b/cypress/e2e/blueprints/nav/edit-cluster.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + // /v1/management.cattle.io.nodedrivers?* export function generateFakeNodeDriversReply():any { return { @@ -44,7 +46,7 @@ export function generateFakeNodeDriversReply():any { message: 'Resource is current' } ], - resourceVersion: '2429', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -244,7 +246,7 @@ export function generateFakeMachineConfigReply(provClusterId:string, machinePool message: 'Resource is current' } ], - resourceVersion: '141967', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -296,7 +298,7 @@ export function generateFakeSecretsReply():any { name: 'registryconfig-auth-reg1', namespace: 'fleet-default', relationships: null, - resourceVersion: '526944', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is always ready', @@ -334,7 +336,7 @@ export function generateFakeSecretsReply():any { name: 'registryconfig-auth-reg2', namespace: 'fleet-default', relationships: null, - resourceVersion: '526944', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is always ready', diff --git a/cypress/e2e/blueprints/nav/fake-cluster.ts b/cypress/e2e/blueprints/nav/fake-cluster.ts index a40e3dfa3df..8391e69528d 100644 --- a/cypress/e2e/blueprints/nav/fake-cluster.ts +++ b/cypress/e2e/blueprints/nav/fake-cluster.ts @@ -14,6 +14,8 @@ import { generateFakeSecretsReply } from './edit-cluster.ts'; +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + // GENERAL DATA NOT CONFIGURABLE, for now... const MACHINE_POOL_ID = '995mj'; const CLOUD_CRED_ID = 'srb7v'; @@ -159,7 +161,7 @@ function generateProvClusterObj(provClusterId, mgmtClusterId) { message: 'Resource is always ready' } ], - resourceVersion: '7555', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is Ready', @@ -505,7 +507,7 @@ function generateMgmtClusterObj(provClusterId, mgmtClusterId) { message: 'Resource is always ready' } ], - resourceVersion: '8138', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is Ready', @@ -1102,7 +1104,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { message: 'Resource is Ready' } ], - resourceVersion: '2689', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1154,7 +1156,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { }, name: 'cattle-fleet-system', relationships: null, - resourceVersion: '2965', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1205,7 +1207,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { }, name: 'cattle-impersonation-system', relationships: null, - resourceVersion: '2649', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1269,7 +1271,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { message: 'Resource is current' } ], - resourceVersion: '2683', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1317,7 +1319,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { }, name: 'default', relationships: null, - resourceVersion: '2622', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1366,7 +1368,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { }, name: 'kube-node-lease', relationships: null, - resourceVersion: '2631', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1415,7 +1417,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { }, name: 'kube-public', relationships: null, - resourceVersion: '2634', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1463,7 +1465,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { }, name: 'kube-system', relationships: null, - resourceVersion: '2711', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1523,7 +1525,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { message: 'Resource is Ready' } ], - resourceVersion: '2605', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1583,7 +1585,7 @@ function generateFakeNamespacesReply(mgmtClusterId) { state: 'deployed' } ], - resourceVersion: '2652', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', @@ -1693,7 +1695,7 @@ function generateFakeDaemonsetsReply(mgmtClusterId) { message: 'Resource is current' } ], - resourceVersion: '1251', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'All replicas scheduled as expected. Replicas: 1', @@ -2253,7 +2255,7 @@ function generateFakeDaemonsetsReply(mgmtClusterId) { message: 'Resource is current' } ], - resourceVersion: '2182', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'All replicas scheduled as expected. Replicas: 1', diff --git a/cypress/e2e/blueprints/other-products/opa-gatekeeper.js b/cypress/e2e/blueprints/other-products/opa-gatekeeper.js index 6a06607d392..061a93e150d 100644 --- a/cypress/e2e/blueprints/other-products/opa-gatekeeper.js +++ b/cypress/e2e/blueprints/other-products/opa-gatekeeper.js @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + const k8sSchemas = [ { id: 'status.gatekeeper.sh.expansiontemplatepodstatus', @@ -778,7 +780,7 @@ const allowedReposGet = { createTypes: { 'constraints.gatekeeper.sh.k8sallowedrepos': 'https://localhost:8005/k8s/clusters/local/v1/constraints.gatekeeper.sh.k8sallowedrepos' }, actions: {}, resourceType: 'constraints.gatekeeper.sh.k8sallowedrepos', - revision: '35356', + revision: CYPRESS_SAFE_RESOURCE_REVISION, data: [] }; @@ -788,7 +790,7 @@ const requiredLabelsGet = { createTypes: { 'constraints.gatekeeper.sh.k8srequiredlabels': 'https://localhost:8005/k8s/clusters/local/v1/constraints.gatekeeper.sh.k8srequiredlabels' }, actions: {}, resourceType: 'constraints.gatekeeper.sh.k8srequiredlabels', - revision: '35356', + revision: CYPRESS_SAFE_RESOURCE_REVISION, data: [] }; @@ -798,7 +800,7 @@ const constraintTemplatesGet = { createTypes: { 'templates.gatekeeper.sh.constrainttemplate': 'https://localhost:8005/k8s/clusters/local/v1/templates.gatekeeper.sh.constrainttemplates' }, actions: {}, resourceType: 'templates.gatekeeper.sh.constrainttemplate', - revision: '36243', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 2, data: [ { @@ -826,7 +828,7 @@ const constraintTemplatesGet = { labels: { 'app.kubernetes.io/managed-by': 'Helm' }, name: 'k8sallowedrepos', relationships: null, - resourceVersion: '27313', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -927,7 +929,7 @@ const constraintTemplatesGet = { labels: { 'app.kubernetes.io/managed-by': 'Helm' }, name: 'k8srequiredlabels', relationships: null, - resourceVersion: '27315', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/other-products/v2-monitoring.js b/cypress/e2e/blueprints/other-products/v2-monitoring.js index ca8a34b5d02..ad2709ea198 100644 --- a/cypress/e2e/blueprints/other-products/v2-monitoring.js +++ b/cypress/e2e/blueprints/other-products/v2-monitoring.js @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + // GET /k8s/clusters/local/v1/monitoring.coreos.com.podmonitors const podMonitorsGet = { type: 'collection', @@ -5,7 +7,7 @@ const podMonitorsGet = { createTypes: { 'monitoring.coreos.com.podmonitor': 'https://209.97.184.234.sslip.io/k8s/clusters/local/v1/monitoring.coreos.com.podmonitors' }, actions: {}, resourceType: 'monitoring.coreos.com.podmonitor', - revision: '7091', + revision: CYPRESS_SAFE_RESOURCE_REVISION, data: [] }; @@ -16,7 +18,7 @@ const serviceMonitorsGet = { createTypes: { 'monitoring.coreos.com.servicemonitor': 'https://209.97.184.234.sslip.io/k8s/clusters/local/v1/monitoring.coreos.com.servicemonitors' }, actions: {}, resourceType: 'monitoring.coreos.com.servicemonitor', - revision: '7091', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 14, data: [ { @@ -99,7 +101,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3944', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -223,7 +225,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3938', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -350,7 +352,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3941', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -485,7 +487,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3945', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -615,7 +617,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3947', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -745,7 +747,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3943', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -881,7 +883,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3950', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1004,7 +1006,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3942', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1142,7 +1144,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3939', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1273,7 +1275,7 @@ const serviceMonitorsGet = { state: 'deployed' } ], - resourceVersion: '3946', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1391,7 +1393,7 @@ const serviceMonitorsGet = { name: 'rancher-monitoring-apiserver', namespace: 'default', relationships: null, - resourceVersion: '3952', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1527,7 +1529,7 @@ const serviceMonitorsGet = { name: 'rancher-monitoring-coredns', namespace: 'kube-system', relationships: null, - resourceVersion: '3940', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1644,7 +1646,7 @@ const serviceMonitorsGet = { name: 'rancher-monitoring-ingress-nginx', namespace: 'kube-system', relationships: null, - resourceVersion: '3949', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1771,7 +1773,7 @@ const serviceMonitorsGet = { name: 'rancher-monitoring-kubelet', namespace: 'kube-system', relationships: null, - resourceVersion: '3948', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -1929,7 +1931,7 @@ const alertManagerConfigsGet = { createTypes: { 'monitoring.coreos.com.alertmanagerconfig': 'https://209.97.184.234.sslip.io/k8s/clusters/local/v1/monitoring.coreos.com.alertmanagerconfigs' }, actions: {}, resourceType: 'monitoring.coreos.com.alertmanagerconfig', - revision: '9702', + revision: CYPRESS_SAFE_RESOURCE_REVISION, data: [ { id: 'default/test-alert', @@ -1975,7 +1977,7 @@ const alertManagerConfigsGet = { name: 'test-alert', namespace: 'default', relationships: null, - resourceVersion: '95805', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -2188,7 +2190,7 @@ const rancherMonitoringAlertmanagerGet = { message: 'Resource is always ready' } ], - resourceVersion: '4368', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -2346,7 +2348,7 @@ const alertManagerRancherMonitoringAlertmanagerGet = { name: 'alertmanager-rancher-monitoring-alertmanager', namespace: 'cattle-monitoring-system', relationships: null, - resourceVersion: '3573', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is always ready', @@ -2364,7 +2366,7 @@ const prometheusRulesGet = { createTypes: { 'monitoring.coreos.com.prometheusrule': 'https://209.97.184.234.sslip.io/k8s/clusters/local/v1/monitoring.coreos.com.prometheusrules' }, actions: {}, resourceType: 'monitoring.coreos.com.prometheusrule', - revision: '11253', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 27, data: [ { @@ -2449,7 +2451,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3932', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -2638,7 +2640,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3907', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -2750,7 +2752,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3933', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -3002,7 +3004,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3912', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -3134,7 +3136,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3916', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -3308,7 +3310,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3927', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -3481,7 +3483,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3922', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -3652,7 +3654,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3920', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -3769,7 +3771,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3915', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -3930,7 +3932,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3909', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -4039,7 +4041,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3910', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -4164,7 +4166,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3928', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -4309,7 +4311,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3917', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -4425,7 +4427,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3931', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -4690,7 +4692,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3908', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -4879,7 +4881,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3926', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -5035,7 +5037,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3935', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -5158,7 +5160,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3925', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -5324,7 +5326,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3923', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -5436,7 +5438,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3930', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -5548,7 +5550,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3929', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -5788,7 +5790,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3919', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -6084,7 +6086,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3918', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -6229,7 +6231,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3924', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -6341,7 +6343,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3921', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -6462,7 +6464,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3911', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -6794,7 +6796,7 @@ const prometheusRulesGet = { state: 'deployed' } ], - resourceVersion: '3934', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -6900,7 +6902,7 @@ const prometheusesGet = { createTypes: { 'monitoring.coreos.com.prometheus': 'https://209.97.184.234.sslip.io/k8s/clusters/local/v1/monitoring.coreos.com.prometheuses' }, actions: {}, resourceType: 'monitoring.coreos.com.prometheus', - revision: '11828', + revision: CYPRESS_SAFE_RESOURCE_REVISION, count: 1, data: [ { @@ -7133,7 +7135,7 @@ const prometheusesGet = { state: 'deployed' } ], - resourceVersion: '4515', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/roles/global-roles-get.ts b/cypress/e2e/blueprints/roles/global-roles-get.ts index b0c606f637c..43cb057d39b 100644 --- a/cypress/e2e/blueprints/roles/global-roles-get.ts +++ b/cypress/e2e/blueprints/roles/global-roles-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + // GET /v1/management.cattle.io.globalroles - small set of pods data const globalRolesGetResponseSmallSet = { type: 'collection', @@ -5,7 +7,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: 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 + revision: CYPRESS_SAFE_RESOURCE_REVISION, // 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: [ { @@ -51,7 +53,7 @@ const globalRolesGetResponseSmallSet = { message: 'Resource is current' } ], - resourceVersion: '5497', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', @@ -145,7 +147,7 @@ const globalRolesGetResponseSmallSet = { message: 'Resource is current' } ], - resourceVersion: '5484', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is current', diff --git a/cypress/e2e/blueprints/users/users-get.ts b/cypress/e2e/blueprints/users/users-get.ts index 90bed6d1e4f..582eda01f02 100644 --- a/cypress/e2e/blueprints/users/users-get.ts +++ b/cypress/e2e/blueprints/users/users-get.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '../blueprint.utils'; + // GET /v3/users - small set of users data const usersGetResponseSmallSet = { type: 'collection', @@ -43,7 +45,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 + revision: CYPRESS_SAFE_RESOURCE_REVISION, // 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/header.po.ts b/cypress/e2e/po/components/header.po.ts index 6bebe15c3ff..1915f0e4d7c 100644 --- a/cypress/e2e/po/components/header.po.ts +++ b/cypress/e2e/po/components/header.po.ts @@ -1,13 +1,25 @@ import ComponentPo from '@/cypress/e2e/po/components/component.po'; import { WorkspaceSwitcherPo } from '@/cypress/e2e/po/components/workspace-switcher.po'; import { ImportYamlPo } from '@/cypress/e2e/po/components/import-yaml.po'; -import Kubectl from '~/cypress/e2e/po/components/kubectl.po'; +import Kubectl from '@/cypress/e2e/po/components/kubectl.po'; +import { NamespaceFilterPo } from '@/cypress/e2e/po/components/namespace-filter.po'; export class HeaderPo extends ComponentPo { constructor() { super('[data-testid="header"]'); } + projectNamespaceFilter() { + return new NamespaceFilterPo(); + } + + selectNamespaceFilterOption(singleOption: string) { + this.projectNamespaceFilter().toggle(); + this.projectNamespaceFilter().clickOptionByLabel(singleOption); + this.projectNamespaceFilter().isChecked(singleOption); + this.projectNamespaceFilter().toggle(); + } + selectWorkspace(name: string) { const wsFilter = new WorkspaceSwitcherPo(); diff --git a/cypress/e2e/po/components/pagination.po.ts b/cypress/e2e/po/components/pagination.po.ts index c42d6179e9c..02a967098cb 100644 --- a/cypress/e2e/po/components/pagination.po.ts +++ b/cypress/e2e/po/components/pagination.po.ts @@ -1,4 +1,5 @@ import ComponentPo from '@/cypress/e2e/po/components/component.po'; +import ProductNavPo from '~/cypress/e2e/po/side-bars/product-side-nav.po'; export default class PaginationPo extends ComponentPo { constructor(selector = 'div.paging') { @@ -24,4 +25,18 @@ export default class PaginationPo extends ComponentPo { paginationText() { return this.self().find('span').invoke('text'); } + + /** + * Check the x of y pagination text against the side nav count + */ + checkPaginationText(productNav: ProductNavPo, options: { + sideNameLabel: string, + expectedText: (count: number) => string + }) { + this.paginationText().then((el) => { + productNav.sideMenuEntryByLabelCount(options.sideNameLabel).then((count) => { + expect(el.trim()).to.eq(options.expectedText(count.trim())); + }); + }); + } } diff --git a/cypress/e2e/po/components/sortable-table.po.ts b/cypress/e2e/po/components/sortable-table.po.ts index 39412587d89..5e76ba836bd 100644 --- a/cypress/e2e/po/components/sortable-table.po.ts +++ b/cypress/e2e/po/components/sortable-table.po.ts @@ -7,6 +7,12 @@ import PaginationPo from '@/cypress/e2e/po/components/pagination.po'; import HeaderRowPo from '@/cypress/e2e/po/components/header-row.po'; export default class SortableTablePo extends ComponentPo { + /** + * Create a name that should, when sorted by name, by default appear first + */ + static firstByDefaultName(context = 'resource'): string { + return `11111-first-in-list-unique-${ context }`; + } // // sortable-table-header // diff --git a/cypress/e2e/po/pages/chart-repositories.po.ts b/cypress/e2e/po/pages/chart-repositories.po.ts index ffa2f92a2c5..ba5c1fdb010 100644 --- a/cypress/e2e/po/pages/chart-repositories.po.ts +++ b/cypress/e2e/po/pages/chart-repositories.po.ts @@ -29,7 +29,7 @@ export default class ChartRepositoriesPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Apps'); sideNav.navToSideMenuEntryByLabel('Repositories'); } else { diff --git a/cypress/e2e/po/pages/explorer/charts/charts.po.ts b/cypress/e2e/po/pages/explorer/charts/charts.po.ts index c809a0db6f2..d09520aad30 100644 --- a/cypress/e2e/po/pages/explorer/charts/charts.po.ts +++ b/cypress/e2e/po/pages/explorer/charts/charts.po.ts @@ -24,7 +24,7 @@ export class ChartsPage extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Apps'); } diff --git a/cypress/e2e/po/pages/explorer/cluster-dashboard.po.ts b/cypress/e2e/po/pages/explorer/cluster-dashboard.po.ts index 92ba3571c74..693a942152e 100644 --- a/cypress/e2e/po/pages/explorer/cluster-dashboard.po.ts +++ b/cypress/e2e/po/pages/explorer/cluster-dashboard.po.ts @@ -23,7 +23,7 @@ export default class ClusterDashboardPagePo extends PagePo { const burgerMenu = new BurgerMenuPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); } customizeAppearanceButton() { diff --git a/cypress/e2e/po/pages/explorer/config-map.po.ts b/cypress/e2e/po/pages/explorer/config-map.po.ts index 60459d0536d..930f55e86cc 100644 --- a/cypress/e2e/po/pages/explorer/config-map.po.ts +++ b/cypress/e2e/po/pages/explorer/config-map.po.ts @@ -17,7 +17,7 @@ export class ConfigMapPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Storage'); sideNav.navToSideMenuEntryByLabel('ConfigMaps'); } diff --git a/cypress/e2e/po/pages/explorer/custom-resource-definitions.po.ts b/cypress/e2e/po/pages/explorer/custom-resource-definitions.po.ts index 0d82746e851..ab689fc0afe 100644 --- a/cypress/e2e/po/pages/explorer/custom-resource-definitions.po.ts +++ b/cypress/e2e/po/pages/explorer/custom-resource-definitions.po.ts @@ -23,7 +23,7 @@ export class CustomResourceDefinitionsPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('More Resources'); sideNav.navToSideMenuGroupByLabel('API'); sideNav.navToSideMenuEntryByLabel('CustomResourceDefinitions'); diff --git a/cypress/e2e/po/pages/explorer/horizontal-pod-autoscalers.po.ts b/cypress/e2e/po/pages/explorer/horizontal-pod-autoscalers.po.ts index 9939ed9f41e..6d762443b67 100644 --- a/cypress/e2e/po/pages/explorer/horizontal-pod-autoscalers.po.ts +++ b/cypress/e2e/po/pages/explorer/horizontal-pod-autoscalers.po.ts @@ -21,7 +21,7 @@ export class HorizontalPodAutoscalersPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Service Discovery'); sideNav.navToSideMenuEntryByLabel('HorizontalPodAutoscalers'); } diff --git a/cypress/e2e/po/pages/explorer/ingress.po.ts b/cypress/e2e/po/pages/explorer/ingress.po.ts index feb37cb7943..ebccd71e6aa 100644 --- a/cypress/e2e/po/pages/explorer/ingress.po.ts +++ b/cypress/e2e/po/pages/explorer/ingress.po.ts @@ -22,7 +22,7 @@ export class IngressPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Service Discovery'); sideNav.navToSideMenuEntryByLabel('Ingresses'); } diff --git a/cypress/e2e/po/pages/explorer/network-policy.po.ts b/cypress/e2e/po/pages/explorer/network-policy.po.ts index ad229c9d6ab..01d89a9be4f 100644 --- a/cypress/e2e/po/pages/explorer/network-policy.po.ts +++ b/cypress/e2e/po/pages/explorer/network-policy.po.ts @@ -17,7 +17,7 @@ export class NetworkPolicyPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Policy'); sideNav.navToSideMenuEntryByLabel('Network Policies'); } diff --git a/cypress/e2e/po/pages/explorer/persistent-volume-claims.po.ts b/cypress/e2e/po/pages/explorer/persistent-volume-claims.po.ts index 91a14960beb..7e26e458325 100644 --- a/cypress/e2e/po/pages/explorer/persistent-volume-claims.po.ts +++ b/cypress/e2e/po/pages/explorer/persistent-volume-claims.po.ts @@ -21,7 +21,7 @@ export class PersistentVolumeClaimsPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Storage'); sideNav.navToSideMenuEntryByLabel('PersistentVolumeClaims'); } diff --git a/cypress/e2e/po/pages/explorer/persistent-volumes.po.ts b/cypress/e2e/po/pages/explorer/persistent-volumes.po.ts index ca342f59f1e..ec10860bba3 100644 --- a/cypress/e2e/po/pages/explorer/persistent-volumes.po.ts +++ b/cypress/e2e/po/pages/explorer/persistent-volumes.po.ts @@ -22,7 +22,7 @@ export class PersistentVolumesPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Storage'); sideNav.navToSideMenuEntryByLabel('PersistentVolumes'); } diff --git a/cypress/e2e/po/pages/explorer/services.po.ts b/cypress/e2e/po/pages/explorer/services.po.ts index 6266356c8e6..0aca6ad8a21 100644 --- a/cypress/e2e/po/pages/explorer/services.po.ts +++ b/cypress/e2e/po/pages/explorer/services.po.ts @@ -22,7 +22,7 @@ export class ServicesPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Service Discovery'); sideNav.navToSideMenuEntryByLabel('Ingresses'); } diff --git a/cypress/e2e/po/pages/explorer/storage-classes.po.ts b/cypress/e2e/po/pages/explorer/storage-classes.po.ts index 12b74811383..4859841ac64 100644 --- a/cypress/e2e/po/pages/explorer/storage-classes.po.ts +++ b/cypress/e2e/po/pages/explorer/storage-classes.po.ts @@ -22,7 +22,7 @@ export class StorageClassesPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Storage'); sideNav.navToSideMenuEntryByLabel('StorageClasses'); } diff --git a/cypress/e2e/po/pages/explorer/workloads-pods.po.ts b/cypress/e2e/po/pages/explorer/workloads-pods.po.ts index 4f2fb95fd73..366d4f63f6d 100644 --- a/cypress/e2e/po/pages/explorer/workloads-pods.po.ts +++ b/cypress/e2e/po/pages/explorer/workloads-pods.po.ts @@ -23,7 +23,7 @@ export class WorkloadsPodsListPagePo extends PagePo { const sideNav = new ProductNavPo(); BurgerMenuPo.toggle(); - burgerMenu.clusters().contains(clusterId).click(); + burgerMenu.clusterNotPinnedList().contains(clusterId).click(); sideNav.navToSideMenuGroupByLabel('Workloads'); sideNav.navToSideMenuEntryByLabel('Pods'); } diff --git a/cypress/e2e/po/pages/fleet/fleet-dashboard.po.ts b/cypress/e2e/po/pages/fleet/fleet-dashboard.po.ts index cf6809143f2..be82a80b991 100644 --- a/cypress/e2e/po/pages/fleet/fleet-dashboard.po.ts +++ b/cypress/e2e/po/pages/fleet/fleet-dashboard.po.ts @@ -1,6 +1,7 @@ import PagePo from '@/cypress/e2e/po/pages/page.po'; import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; +import { LONG_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; export class FleetDashboardPagePo extends PagePo { static url: string; @@ -26,7 +27,8 @@ export class FleetDashboardPagePo extends PagePo { static navTo() { BurgerMenuPo.toggle(); - BurgerMenuPo.burgerMenuNavToMenubyLabel('Continuous Delivery'); + // Give extra time to ensure fleet comes up + BurgerMenuPo.burgerMenuNavToMenubyLabel('Continuous Delivery', LONG_TIMEOUT_OPT); } constructor(clusterId: string) { diff --git a/cypress/e2e/po/side-bars/burger-side-menu.po.ts b/cypress/e2e/po/side-bars/burger-side-menu.po.ts index 466b59c2340..c9937b99391 100644 --- a/cypress/e2e/po/side-bars/burger-side-menu.po.ts +++ b/cypress/e2e/po/side-bars/burger-side-menu.po.ts @@ -1,4 +1,4 @@ -import ComponentPo from '@/cypress/e2e/po/components/component.po'; +import ComponentPo, { GetOptions } from '@/cypress/e2e/po/components/component.po'; export default class BurgerMenuPo extends ComponentPo { constructor() { @@ -19,8 +19,8 @@ export default class BurgerMenuPo extends ComponentPo { * Navigates to a top-level side menu entry by label (non-cluster) * @returns {Cypress.Chainable} */ - static burgerMenuNavToMenubyLabel(label: string): Cypress.Chainable { - return this.sideMenu().should('exist').find('.option').contains(label) + static burgerMenuNavToMenubyLabel(label: string, options?: GetOptions): Cypress.Chainable { + return this.sideMenu().should('exist').find('.option').contains(label, options) .click({ force: true }); } @@ -127,16 +127,27 @@ export default class BurgerMenuPo extends ComponentPo { return this.self().find('.body .option'); } + /** + * Get all clusters, whether pinned, filtered or not + */ + allClusters(): Cypress.Chainable { + return this.self().find('.body .cluster.selector.option'); + } + + goToCluster(clusterId = 'local') { + return this.self().find('.cluster-name').contains(clusterId).click(); + } + /** * Get all the available cluster navigation links * @returns {Cypress.Chainable} */ - clusters(): Cypress.Chainable { + clusterNotPinnedList(): Cypress.Chainable { return this.self().find('.body .clustersList .cluster.selector.option'); } pinFirstCluster(): Cypress.Chainable { - return this.clusters().first().trigger('mouseover').find('.pin') + return this.clusterNotPinnedList().first().trigger('mouseover').find('.pin') .invoke('show') .click(); } @@ -150,11 +161,11 @@ export default class BurgerMenuPo extends ComponentPo { } getClusterDescription(): Cypress.Chainable { - return this.clusters().first().find('.description').invoke('text'); + return this.clusterNotPinnedList().first().find('.description').invoke('text'); } showClusterDescriptionTooltip(): Cypress.Chainable { - return this.clusters().first().find('.description').trigger('mouseenter'); + return this.clusterNotPinnedList().first().find('.description').trigger('mouseenter'); } getClusterDescriptionTooltipContent(): Cypress.Chainable { diff --git a/cypress/e2e/po/side-bars/product-side-nav.po.ts b/cypress/e2e/po/side-bars/product-side-nav.po.ts index 61eb6d3b5a2..57391d1881a 100644 --- a/cypress/e2e/po/side-bars/product-side-nav.po.ts +++ b/cypress/e2e/po/side-bars/product-side-nav.po.ts @@ -37,12 +37,20 @@ export default class ProductNavPo extends ComponentPo { return cy.get('.side-nav', LONG_TIMEOUT_OPT).should('exist').contains('.accordion.has-children', label, LONG_TIMEOUT_OPT).click(); } + sideMenuEntryByLabelCount(label: string): Cypress.Chainable { + return this.sideMenuEntryByLabel(label).parent().find('.count').should('exist') + .invoke('text'); + } + + sideMenuEntryByLabel(label: string): Cypress.Chainable { + return this.self().should('exist', LONG_TIMEOUT_OPT).find('.child.nav-type a .label').contains(label); + } + /** * Navigate to a side menu entry by label */ navToSideMenuEntryByLabel(label: string): Cypress.Chainable { - return this.self().should('exist', LONG_TIMEOUT_OPT).find('.child.nav-type a .label').contains(label) - .click({ force: true }); + return this.sideMenuEntryByLabel(label).click({ force: true }); } /** diff --git a/cypress/e2e/po/side-bars/user-menu.po.ts b/cypress/e2e/po/side-bars/user-menu.po.ts index 944247d1071..5f0df55b77d 100644 --- a/cypress/e2e/po/side-bars/user-menu.po.ts +++ b/cypress/e2e/po/side-bars/user-menu.po.ts @@ -95,14 +95,21 @@ export default class UserMenuPo extends ComponentPo { return this.userMenu().find('li').should('be.visible').and('have.length', 4); } + /** + * label: 'Preferences', 'Account & API Keys', or 'Log Out' + * @param label + * @returns + */ + getMenuItem(label: 'Preferences' | 'Account & API Keys' | 'Log Out') { + return this.ensureOpen().then(() => this.getMenuItems().contains(label)); + } + /** * label: 'Preferences', 'Account & API Keys', or 'Log Out' * @param label * @returns */ clickMenuItem(label: 'Preferences' | 'Account & API Keys' | 'Log Out') { - this.ensureOpen().then(() => { - return this.getMenuItems().contains(label).click(); - }); + return this.getMenuItem(label).click(); } } diff --git a/cypress/e2e/tests/navigation/page-actions.spec.ts b/cypress/e2e/tests/navigation/page-actions.spec.ts index 51287f60a3c..afcd77bbde6 100644 --- a/cypress/e2e/tests/navigation/page-actions.spec.ts +++ b/cypress/e2e/tests/navigation/page-actions.spec.ts @@ -1,4 +1,4 @@ -import PageActions from '@/cypress/e2e/po/side-bars/page-actions.po'; +// import PageActions from '@/cypress/e2e/po/side-bars/page-actions.po'; import HomePagePo from '@/cypress/e2e/po/pages/home.po'; describe('Page Actions', { tags: ['@navigation', '@adminUser', '@standardUser'] }, () => { @@ -9,18 +9,18 @@ describe('Page Actions', { tags: ['@navigation', '@adminUser', '@standardUser'] }); // TODO: Verify cause of race condition issue making navigation link not trigger - it.skip('Can restore hidden cards and displays welcome section', () => { - const homePage = new HomePagePo(); + // it.skip('Can restore hidden cards and displays welcome section', () => { + // const homePage = new HomePagePo(); - homePage - .checkIsCurrentPage(); - PageActions.open(); - const pageActionsPo = new PageActions(); + // homePage + // .checkIsCurrentPage(); + // PageActions.open(); + // const pageActionsPo = new PageActions(); - pageActionsPo.restoreLink().click(); + // pageActionsPo.restoreLink().click(); - homePage - .title() - .should('eq', 'Welcome to Rancher'); - }); + // homePage + // .title() + // .should('eq', 'Welcome to Rancher'); + // }); }); 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 54649c0dd78..a26e141ce04 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 @@ -102,7 +102,7 @@ describe('Side Menu: main', () => { it('Can display list of available clusters', { tags: ['@navigation', '@adminUser'] }, () => { const burgerMenuPo = new BurgerMenuPo(); - burgerMenuPo.clusters().should('exist'); + burgerMenuPo.clusterNotPinnedList().should('exist'); }); it('Pinned and unpinned cluster', { tags: ['@navigation', '@adminUser', '@standardUser'] }, () => { @@ -123,25 +123,25 @@ describe('Side Menu: main', () => { it('Should show tooltip on mouse-hover when the menu is collapsed', { tags: ['@navigation', '@adminUser', '@standardUser'] }, () => { const burgerMenuPo = new BurgerMenuPo(); - burgerMenuPo.clusters().first().trigger('mouseover'); + burgerMenuPo.allClusters().first().trigger('mouseover'); BurgerMenuPo.checkIconTooltipOff(); BurgerMenuPo.toggle(); BurgerMenuPo.checkIconTooltipOn(); }); // TODO: #5966: Verify cause of race condition issue making navigation link not trigger - it.skip('Contains valid links', { tags: ['@navigation', '@adminUser', '@standardUser'] }, () => { - const burgerMenuPo = new BurgerMenuPo(); - // Navigate through all the links - - burgerMenuPo.links().each((_, idx) => { - // Cant bind to looped element due DOM changes while opening/closing side bar - burgerMenuPo.links().eq(idx).should('be.visible').click({ force: true }) - .then((linkEl) => { - cy.location('href').should('exist'); - }); - }); - }); + // it.skip('Contains valid links', { tags: ['@navigation', '@adminUser', '@standardUser'] }, () => { + // const burgerMenuPo = new BurgerMenuPo(); + // // Navigate through all the links + + // burgerMenuPo.links().each((_, idx) => { + // // Cant bind to looped element due DOM changes while opening/closing side bar + // burgerMenuPo.links().eq(idx).should('be.visible').click({ force: true }) + // .then((linkEl) => { + // cy.location('href').should('exist'); + // }); + // }); + // }); it('Check first item in global section is Cluster Management', { tags: ['@navigation', '@adminUser', '@standardUser'] }, () => { HomePagePo.goTo(); diff --git a/cypress/e2e/tests/navigation/side-nav/product-side-nav.spec.ts b/cypress/e2e/tests/navigation/side-nav/product-side-nav.spec.ts index b3aa67a781e..937ea0c0f42 100644 --- a/cypress/e2e/tests/navigation/side-nav/product-side-nav.spec.ts +++ b/cypress/e2e/tests/navigation/side-nav/product-side-nav.spec.ts @@ -24,7 +24,7 @@ describe('Side navigation: Cluster ', { tags: ['@navigation', '@adminUser'] }, ( BurgerMenuPo.toggle(); const burgerMenuPo = new BurgerMenuPo(); - burgerMenuPo.clusters().eq(0).should('be.visible').click(); + burgerMenuPo.goToCluster('local').click(); }); it('Can access to first navigation link on click', () => { diff --git a/cypress/e2e/tests/pages/explorer/api/api-services.spec.ts b/cypress/e2e/tests/pages/explorer/api/api-services.spec.ts index 4bff4f2107e..09116afa5c9 100644 --- a/cypress/e2e/tests/pages/explorer/api/api-services.spec.ts +++ b/cypress/e2e/tests/pages/explorer/api/api-services.spec.ts @@ -15,14 +15,17 @@ describe('Cluster Explorer', { tags: ['@explorer', '@adminUser'] }, () => { apiServicesPage.title().should('contain', 'APIServices'); const sortableTable = apiServicesPage.sortableTable(); + const count = 3; - sortableTable.rowElements().its('length').then((count: number) => { - cy.keyboardControls({ shiftKey: true, key: 'j' }, count + 2); + sortableTable.rowElements().should(($els) => { + expect($els.length).to.be.greaterThan(count - 1); + }); - sortableTable.selectedCountText().should('contain', `${ count } selected`); + cy.keyboardControls({ shiftKey: true, key: 'j' }, count); - sortableTable.selectedCount().should('eq', count); - }); + sortableTable.selectedCountText().should('contain', `${ count } selected`); + + sortableTable.selectedCount().should('eq', count); }); }); }); diff --git a/cypress/e2e/tests/pages/explorer/apps/repositories.spec.ts b/cypress/e2e/tests/pages/explorer/apps/repositories.spec.ts index 9537298afda..4f41407a373 100644 --- a/cypress/e2e/tests/pages/explorer/apps/repositories.spec.ts +++ b/cypress/e2e/tests/pages/explorer/apps/repositories.spec.ts @@ -24,7 +24,14 @@ describe('Apps', () => { const appRepoCreate = new AppClusterRepoEditPo('local', 'create'); appRepoList.sortableTable().checkLoadingIndicatorNotVisible(); + appRepoList.sortableTable().rowCount().should('be.lessThan', 10); // catch page size 10... + // Check that the table has settled and rendered all rows + // This is a bit hacky, but assume table settled when we have all of these three rows + appRepoList.sortableTable().rowElementWithName('Partners').should('be.visible'); + appRepoList.sortableTable().rowElementWithName('Rancher').should('be.visible'); + appRepoList.sortableTable().rowElementWithName('RKE2').should('be.visible'); + // Table settled. Get row count appRepoList.sortableTable().rowCount().then((count) => { // track repo rows diff --git a/cypress/e2e/tests/pages/explorer/dashboard/certificates.spec.ts b/cypress/e2e/tests/pages/explorer/dashboard/certificates.spec.ts index 47833c56482..9d8ab9b4b06 100644 --- a/cypress/e2e/tests/pages/explorer/dashboard/certificates.spec.ts +++ b/cypress/e2e/tests/pages/explorer/dashboard/certificates.spec.ts @@ -1,6 +1,7 @@ import ClusterDashboardPagePo from '@/cypress/e2e/po/pages/explorer/cluster-dashboard.po'; import { SecretsPagePo } from '@/cypress/e2e/po/pages/explorer/secrets.po'; +import { CYPRESS_SAFE_RESOURCE_REVISION } from '@/cypress/e2e/blueprints/blueprint.utils'; const certName = 'expired'; const certNs = 'defaut'; @@ -31,7 +32,7 @@ const expiredCert = { name: certName, namespace: certNs, relationships: null, - resourceVersion: '17963647', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: 'Resource is always ready', 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 003ee8cb9af..cc96ee91bd6 100644 --- a/cypress/e2e/tests/pages/explorer/dashboard/cluster-dashboard.spec.ts +++ b/cypress/e2e/tests/pages/explorer/dashboard/cluster-dashboard.spec.ts @@ -32,8 +32,6 @@ const simpleBox = new SimpleBoxPo(); const header = new HeaderPo(); describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, () => { - const podName = `e2e-test-${ +new Date() }`; - before(() => { cy.login(); }); @@ -55,12 +53,12 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi BurgerMenuPo.checkIfClusterMenuLinkIsHighlighted('local'); }); - it.skip('[Vue3 Skip]: has the correct title', () => { - clusterDashboard.goTo('local'); - clusterDashboard.waitForPage(undefined, 'cluster-events'); + // it.skip('[Vue3 Skip]: has the correct title', () => { + // clusterDashboard.goTo('local'); + // clusterDashboard.waitForPage(undefined, 'cluster-events'); - cy.title().should('eq', 'Rancher - local - Cluster Dashboard'); - }); + // cy.title().should('eq', 'Rancher - local - Cluster Dashboard'); + // }); it('shows fleet controller status', () => { ClusterDashboardPagePo.navTo(); @@ -158,7 +156,7 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi header.customBadge().should('contain', settings.description.new); const burgerMenu = new BurgerMenuPo(); - burgerMenu.clusters().first().find('span').should('contain', settings.iconText); + burgerMenu.clusterNotPinnedList().first().find('span').should('contain', settings.iconText); // Reset clusterDashboard.customizeAppearanceButton().click(); @@ -173,7 +171,7 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi header.clusterIcon().children().should('have.class', 'cluster-local-logo'); header.clusterName().should('contain', 'local'); header.customBadge().should('not.exist'); - burgerMenu.clusters().first().find('svg').should('have.class', 'cluster-local-logo'); + burgerMenu.clusterNotPinnedList().first().find('svg').should('have.class', 'cluster-local-logo'); }); it('can view deployments', () => { @@ -216,6 +214,7 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi }); let removePod = false; + let podName = `e2e-test`; const projName = `project${ +new Date() }`; const nsName = `namespace${ +new Date() }`; @@ -237,7 +236,10 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi // create pod // eslint-disable-next-line no-return-assign - cy.createPod(nsName, podName, 'nginx:latest').then(() => removePod = true); + cy.createPod(nsName, podName, 'nginx:latest').then((resp) => { + podName = resp.body.metadata.name; + removePod = true; + }); }); }); @@ -300,18 +302,20 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi beforeEach(() => { stdProjectName = `standard-user-project${ +new Date() }`; stdNsName = `standard-user-ns${ +new Date() }`; - stdUsername = `standard-user-${ +new Date() }`; + stdUsername = `standard-user`; + const password = Cypress.env('password'); + // log in as admin cy.login(); cy.getRancherResource('v3', 'users?me=true').then((resp: Cypress.Response) => { const adminUserId = resp.body.data[0].id.trim(); // create project - cy.createProject(stdProjectName, 'local', adminUserId).then((resp: Cypress.Response) => { + return cy.createProject(stdProjectName, 'local', adminUserId).then((resp: Cypress.Response) => { cy.wrap(resp.body.id.trim()).as('standardUserProject'); // create ns in project - cy.get('@standardUserProject').then((projId) => { + return cy.get('@standardUserProject').then((projId) => { cy.createNamespaceInProject(stdNsName, projId); // create std user and assign to project @@ -320,17 +324,24 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi globalRole: { role: 'user' }, projectRole: { clusterId: 'local', projectName: stdProjectName, role: 'project-owner' - } - }).as('createUserRequest'); + }, + password + }) + .as('createUserRequest') + .then((resp) => { + stdUsername = resp.body.username; + + // log in as new standard user + cy.login(stdUsername, password, false); + + // go to cluster dashboard + ClusterDashboardPagePo.navTo(); + + return clusterDashboard.waitForPage(); + }); }); }); }); - // log in as new standard user - cy.login(stdUsername, Cypress.env('password'), false); - - // go to cluster dashboard - ClusterDashboardPagePo.navTo(); - clusterDashboard.waitForPage(); }); // note - this would be 'fleet agent' on downstream clusters @@ -347,12 +358,12 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi cy.login(); cy.deleteRancherResource('v1', 'namespaces', stdNsName); - cy.get('@standardUserProject').then((projectId) => { + cy.get('@standardUserProject').then((projectId) => { cy.deleteRancherResource('v3', 'projects', projectId); }); cy.get('@createUserRequest').then((req) => { - const userId = req.body.userPrincipalId.split('//').pop(); + const userId = req.body.id; cy.deleteRancherResource('v3', 'users', userId); }); @@ -361,7 +372,7 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi after(function() { if (removePod) { - cy.deleteRancherResource('v1', `pods/${ nsName }`, `pod-${ podName }`); + cy.deleteRancherResource('v1', `pods/${ nsName }`, `${ podName }`); cy.deleteRancherResource('v1', 'namespaces', `${ nsName }`); cy.deleteRancherResource('v3', 'projects', this.projId); } diff --git a/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts b/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts index e8a6ddeef1f..cb3698c3568 100644 --- a/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts +++ b/cypress/e2e/tests/pages/explorer/dashboard/events.spec.ts @@ -2,6 +2,7 @@ import ClusterDashboardPagePo from '@/cypress/e2e/po/pages/explorer/cluster-dash import { EventsPagePo } from '@/cypress/e2e/po/pages/explorer/events.po'; import { generateEventsDataSmall } from '@/cypress/e2e/blueprints/explorer/cluster/events'; import LoadingPo from '@/cypress/e2e/po/components/loading.po'; +import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po'; const clusterDashboard = new ClusterDashboardPagePo('local'); const events = new EventsPagePo('local'); @@ -12,7 +13,7 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, }); describe('List', { tags: ['@vai', '@adminUser'] }, () => { - const uniquePod = 'aaa-e2e-test-pod-name'; + let uniquePod = SortableTablePo.firstByDefaultName('pod'); const podNamesList = []; let nsName1: string; let nsName2: string; @@ -29,10 +30,10 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, let i = 0; while (i < 125) { - const podName = `e2e-${ Cypress._.uniqueId(Date.now().toString()) }`; + const podName = Cypress._.uniqueId(Date.now().toString()); - cy.createPod(nsName1, podName, 'nginx:latest', false).then(() => { - podNamesList.push(`pod-${ podName }`); + cy.createPod(nsName1, podName, 'nginx:latest', false, { createNameOptions: { prefixContext: true } }).then((resp) => { + podNamesList.push(resp.body.metadata.name); }); i++; @@ -46,76 +47,85 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, cy.createNamespace(nsName2); // create unique pod for filtering/sorting test - cy.createPod(nsName2, uniquePod, 'nginx:latest'); + cy.createPod(nsName2, uniquePod, 'nginx:latest', true, { createNameOptions: { prefixContext: true } }).then((resp) => { + uniquePod = resp.body.metadata.name; + }); }); }); it('pagination is visible and user is able to navigate through events data', () => { - ClusterDashboardPagePo.navTo(); + ClusterDashboardPagePo.goTo('local'); clusterDashboard.waitForPage(undefined, 'cluster-events'); EventsPagePo.navTo(); events.waitForPage(); - const count = 500; + cy.getRancherResource('v1', 'events').then((resp: Cypress.Response) => { + // Why 500? there's a hardcoded figure to stops ui from storing more than 500 events ... + const count = resp.body.count < 500 ? resp.body.count : 500; - // pagination is visible - events.sortableTable().pagination().checkVisible(); + // Test break down if less than 400... + expect(count).to.be.greaterThan(400); - const loadingPo = new LoadingPo('.title .resource-loading-indicator'); + // pagination is visible + events.sortableTable().pagination().checkVisible(); - loadingPo.checkNotExists(); + const loadingPo = new LoadingPo('.title .resource-loading-indicator'); - // basic checks on navigation buttons - events.sortableTable().pagination().beginningButton().isDisabled(); - events.sortableTable().pagination().leftButton().isDisabled(); - events.sortableTable().pagination().rightButton().isEnabled(); - events.sortableTable().pagination().endButton().isEnabled(); + loadingPo.checkNotExists(); - // check text before navigation - events.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`1 - 100 of ${ count } Events`); - }); + // basic checks on navigation buttons + events.sortableTable().pagination().beginningButton().isDisabled(); + events.sortableTable().pagination().leftButton().isDisabled(); + events.sortableTable().pagination().rightButton().isEnabled(); + events.sortableTable().pagination().endButton().isEnabled(); - // navigate to next page - right button - events.sortableTable().pagination().rightButton().click(); + // check text before navigation + events.sortableTable().pagination().paginationText().then((el) => { + expect(el.trim()).to.eq(`1 - 100 of ${ count } Events`); + }); - // check text and buttons after navigation - events.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`101 - 200 of ${ count } Events`); - }); - events.sortableTable().pagination().beginningButton().isEnabled(); - events.sortableTable().pagination().leftButton().isEnabled(); + // navigate to next page - right button + events.sortableTable().pagination().rightButton().click(); - // navigate to first page - left button - events.sortableTable().pagination().leftButton().click(); + // check text and buttons after navigation + events.sortableTable().pagination().paginationText().then((el) => { + expect(el.trim()).to.eq(`101 - 200 of ${ count } Events`); + }); + events.sortableTable().pagination().beginningButton().isEnabled(); + events.sortableTable().pagination().leftButton().isEnabled(); - // check text and buttons after navigation - events.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`1 - 100 of ${ count } Events`); - }); - events.sortableTable().pagination().beginningButton().isDisabled(); - events.sortableTable().pagination().leftButton().isDisabled(); + // navigate to first page - left button + events.sortableTable().pagination().leftButton().click(); - // navigate to last page - end button - events.sortableTable().pagination().endButton().click(); + // check text and buttons after navigation + events.sortableTable().pagination().paginationText().then((el) => { + expect(el.trim()).to.eq(`1 - 100 of ${ count } Events`); + }); + events.sortableTable().pagination().beginningButton().isDisabled(); + events.sortableTable().pagination().leftButton().isDisabled(); - // check row count on last page - events.sortableTable().checkRowCount(false, 100); + // navigate to last page - end button + events.sortableTable().pagination().endButton().scrollIntoView() + .click(); - // check text after navigation - events.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`401 - ${ count } of ${ count } Events`); - }); + // check row count on last page + events.sortableTable().checkRowCount(false, 100); + + // check text after navigation + events.sortableTable().pagination().paginationText().then((el) => { + expect(el.trim()).to.eq(`401 - ${ count } of ${ count } Events`); + }); - // navigate to first page - beginning button - events.sortableTable().pagination().beginningButton().click(); + // navigate to first page - beginning button + events.sortableTable().pagination().beginningButton().click(); - // check text and buttons after navigation - events.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`1 - 100 of ${ count } Events`); + // check text and buttons after navigation + events.sortableTable().pagination().paginationText().then((el) => { + expect(el.trim()).to.eq(`1 - 100 of ${ count } Events`); + }); + events.sortableTable().pagination().beginningButton().isDisabled(); + events.sortableTable().pagination().leftButton().isDisabled(); }); - events.sortableTable().pagination().beginningButton().isDisabled(); - events.sortableTable().pagination().leftButton().isDisabled(); }); it('filter events', () => { @@ -157,6 +167,7 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, events.sortableTable().tableHeaderRow().checkSortOrder(11, 'down'); // event name should be visible on first page (sorted in ASC order) + events.sortableTable().tableHeaderRow().self().scrollIntoView(); events.sortableTable().rowElementWithPartialName(uniquePod).scrollIntoView().should('be.visible'); // sort by name in DESC order @@ -167,7 +178,8 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, events.sortableTable().rowElementWithPartialName(uniquePod).should('not.exist'); // navigate to last page - events.sortableTable().pagination().endButton().click(); + events.sortableTable().pagination().endButton().scrollIntoView() + .click(); // event name should be visible on last page (sorted in DESC order) events.sortableTable().rowElementWithPartialName(uniquePod).scrollIntoView().should('be.visible'); 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 e7e088ed2e9..c3da910c863 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 @@ -73,17 +73,23 @@ describe('CustomResourceDefinitions', { testIsolation: 'off', tags: ['@explorer' crdsPage.sortableTable().pagination().endButton().isEnabled(); // check text before navigation - crdsPage.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`1 - 10 of ${ count } CustomResourceDefinitions`); - }); + crdsPage.sortableTable().pagination().checkPaginationText( + crdsPage.productNav(), { + sideNameLabel: 'CustomResourceDefinitions', + expectedText: (count: number) => `1 - 10 of ${ count } CustomResourceDefinitions` + } + ); // navigate to next page - right button crdsPage.sortableTable().pagination().rightButton().click(); // check text and buttons after navigation - crdsPage.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`11 - 20 of ${ count } CustomResourceDefinitions`); - }); + crdsPage.sortableTable().pagination().checkPaginationText( + crdsPage.productNav(), { + sideNameLabel: 'CustomResourceDefinitions', + expectedText: (count: number) => `11 - 20 of ${ count } CustomResourceDefinitions` + } + ); crdsPage.sortableTable().pagination().beginningButton().isEnabled(); crdsPage.sortableTable().pagination().leftButton().isEnabled(); @@ -91,14 +97,19 @@ describe('CustomResourceDefinitions', { testIsolation: 'off', tags: ['@explorer' crdsPage.sortableTable().pagination().leftButton().click(); // check text and buttons after navigation - crdsPage.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`1 - 10 of ${ count } CustomResourceDefinitions`); - }); + crdsPage.sortableTable().pagination().checkPaginationText( + crdsPage.productNav(), { + sideNameLabel: 'CustomResourceDefinitions', + expectedText: (count: number) => `1 - 10 of ${ count } CustomResourceDefinitions` + } + ); + crdsPage.sortableTable().pagination().beginningButton().isDisabled(); crdsPage.sortableTable().pagination().leftButton().isDisabled(); // navigate to last page - end button - crdsPage.sortableTable().pagination().endButton().click(); + crdsPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // row count on last page let lastPageCount = count % 10; @@ -108,17 +119,23 @@ describe('CustomResourceDefinitions', { testIsolation: 'off', tags: ['@explorer' } // check text after navigation - crdsPage.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.contain(`${ count - (lastPageCount) + 1 } - ${ count } of ${ count } CustomResourceDefinitions`); - }); + crdsPage.sortableTable().pagination().checkPaginationText( + crdsPage.productNav(), { + sideNameLabel: 'CustomResourceDefinitions', + expectedText: (count: number) => `${ count - (lastPageCount) + 1 } - ${ count } of ${ count } CustomResourceDefinitions` + } + ); // navigate to first page - beginning button crdsPage.sortableTable().pagination().beginningButton().click(); // check text and buttons after navigation - crdsPage.sortableTable().pagination().paginationText().then((el) => { - expect(el.trim()).to.eq(`1 - 10 of ${ count } CustomResourceDefinitions`); - }); + crdsPage.sortableTable().pagination().checkPaginationText( + crdsPage.productNav(), { + sideNameLabel: 'CustomResourceDefinitions', + expectedText: (count: number) => `1 - 10 of ${ count } CustomResourceDefinitions` + } + ); crdsPage.sortableTable().pagination().beginningButton().isDisabled(); crdsPage.sortableTable().pagination().leftButton().isDisabled(); }); 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 766a398ec44..6d70587a112 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 @@ -31,10 +31,10 @@ describe('Roles', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, ( }); it('flat list: validate roles table', () => { - generateRolesDataSmall(); + generateRolesDataSmall('rolesDataSmall1'); rolesPage.goTo(); rolesPage.waitForPage(); - cy.wait('@rolesDataSmall'); + cy.wait('@rolesDataSmall1'); // check table headers are visible const expectedHeaders = ['State', 'Name', 'Namespace', 'Created At']; @@ -52,10 +52,12 @@ describe('Roles', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, ( }); it('group by namespace: validate roles table', () => { - generateRolesDataSmall(); + const ns = 'saddsfdsf'; + + generateRolesDataSmall('rolesDataSmall2', ns); rolesPage.goTo(); rolesPage.waitForPage(); - cy.wait('@rolesDataSmall'); + cy.wait('@rolesDataSmall2'); // group by namespace rolesPage.list().resourceTable().sortableTable().groupByButtons(1) @@ -73,10 +75,9 @@ describe('Roles', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] }, ( rolesPage.list().resourceTable().sortableTable().checkVisible(); rolesPage.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); rolesPage.list().resourceTable().sortableTable().noRowsShouldNotExist(); - rolesPage.list().resourceTable().sortableTable().groupElementWithName('Namespace: kube-system') + rolesPage.list().resourceTable().sortableTable().groupElementWithName(`Namespace: ${ ns }`) .scrollIntoView() .should('be.visible'); - rolesPage.list().resourceTable().sortableTable().checkRowCount(false, 2); }); after('clean up', () => { 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 a24e4939622..2fd6984c29a 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 @@ -36,6 +36,8 @@ describe('HorizontalPodAutoscalers', { testIsolation: 'off', tags: ['@explorer', horizontalPodAutoscalersPage.waitForPage(); cy.wait('@horizontalpodautoscalerDataSmall'); + horizontalPodAutoscalersPage.header().selectNamespaceFilterOption('All Namespaces'); + // check table headers are visible const expectedHeaders = ['State', 'Name', 'Workload', 'Minimum Replicas', 'Maximum Replicas', 'Current Replicas', 'Age']; @@ -57,6 +59,8 @@ describe('HorizontalPodAutoscalers', { testIsolation: 'off', tags: ['@explorer', horizontalPodAutoscalersPage.waitForPage(); cy.wait('@horizontalpodautoscalerDataSmall'); + horizontalPodAutoscalersPage.header().selectNamespaceFilterOption('All Namespaces'); + // group by namespace horizontalPodAutoscalersPage.list().resourceTable().sortableTable().groupByButtons(1) .click(); diff --git a/cypress/e2e/tests/pages/explorer2/cluster-tools.spec.ts b/cypress/e2e/tests/pages/explorer2/cluster-tools.spec.ts index ed14f09d585..b7918053ee1 100644 --- a/cypress/e2e/tests/pages/explorer2/cluster-tools.spec.ts +++ b/cypress/e2e/tests/pages/explorer2/cluster-tools.spec.ts @@ -1,7 +1,7 @@ import ClusterToolsPagePo from '@/cypress/e2e/po/pages/explorer/cluster-tools.po'; import ClusterDashboardPagePo from '@/cypress/e2e/po/pages/explorer/cluster-dashboard.po'; import { InstallChartPage } from '@/cypress/e2e/po/pages/explorer/charts/install-charts.po'; -import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; +// import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; const clusterTools = new ClusterToolsPagePo('local'); @@ -42,36 +42,36 @@ describe('Cluster Tools', { tags: ['@explorer2', '@adminUser'] }, () => { }); }); - it.skip('can edit chart successfully', () => { - // Note: this test fails due to https://github.com/rancher/dashboard/issues/9940 - // skipping this test until issue is resolved - clusterTools.goTo(); - clusterTools.waitForPage(); - clusterTools.editChart(0); + // it.skip('can edit chart successfully', () => { + // // Note: this test fails due to https://github.com/rancher/dashboard/issues/9940 + // // skipping this test until issue is resolved + // clusterTools.goTo(); + // clusterTools.waitForPage(); + // clusterTools.editChart(0); - const installChart = new InstallChartPage(); + // const installChart = new InstallChartPage(); - installChart.nextPage(); + // installChart.nextPage(); - cy.intercept('POST', 'v1/catalog.cattle.io.clusterrepos/rancher-charts?action=upgrade').as('chartUpdate'); - installChart.installChart(); - cy.wait('@chartUpdate').its('response.statusCode').should('eq', 201); - clusterTools.waitForPage(); - cy.contains('Connected'); - }); + // cy.intercept('POST', 'v1/catalog.cattle.io.clusterrepos/rancher-charts?action=upgrade').as('chartUpdate'); + // installChart.installChart(); + // cy.wait('@chartUpdate').its('response.statusCode').should('eq', 201); + // clusterTools.waitForPage(); + // cy.contains('Connected'); + // }); - it.skip('can uninstall chart successfully', () => { - // Note: this test fails due to https://github.com/rancher/dashboard/issues/9940 - // skipping this test until issue is resolved - clusterTools.goTo(); - clusterTools.waitForPage(); - clusterTools.deleteChart(0); + // it.skip('can uninstall chart successfully', () => { + // // Note: this test fails due to https://github.com/rancher/dashboard/issues/9940 + // // skipping this test until issue is resolved + // clusterTools.goTo(); + // clusterTools.waitForPage(); + // clusterTools.deleteChart(0); - const promptRemove = new PromptRemove(); + // const promptRemove = new PromptRemove(); - cy.intercept('POST', '/v1/catalog.cattle.io.apps/default/rancher-alerting-drivers?action=uninstall').as('chartUninstall'); - promptRemove.remove(); - cy.wait('@chartUninstall').its('response.statusCode').should('eq', 201); - cy.contains('Disconnected'); - }); + // cy.intercept('POST', '/v1/catalog.cattle.io.apps/default/rancher-alerting-drivers?action=uninstall').as('chartUninstall'); + // promptRemove.remove(); + // cy.wait('@chartUninstall').its('response.statusCode').should('eq', 201); + // cy.contains('Disconnected'); + // }); }); diff --git a/cypress/e2e/tests/pages/explorer2/namespace-picker.spec.ts b/cypress/e2e/tests/pages/explorer2/namespace-picker.spec.ts index 49f8712670b..a44cbf71800 100644 --- a/cypress/e2e/tests/pages/explorer2/namespace-picker.spec.ts +++ b/cypress/e2e/tests/pages/explorer2/namespace-picker.spec.ts @@ -37,6 +37,10 @@ describe('Namespace picker', { testIsolation: 'off' }, () => { workloadsPodPage.waitForPage(); cy.wait('@getPods'); + // group by namespace + workloadsPodPage.list().resourceTable().sortableTable().groupByButtons(1) + .click(); + // Filter by Namespace: Select 'cattle-fleet-system' namespacePicker.toggle(); namespacePicker.getOptions().find('#ns_cattle-fleet-system').should('exist'); @@ -187,38 +191,38 @@ describe('Namespace picker', { testIsolation: 'off' }, () => { namespacePicker.checkIcon().should('have.length', 1); }); - it.skip('newly created project/namespace appears in namespace picker', { tags: ['@explorer2', '@adminUser'] }, () => { - const projName = `project${ +new Date() }`; - const nsName = `namespace${ +new Date() }`; - - // get user id - cy.getRancherResource('v3', 'users?me=true').then((resp: Cypress.Response) => { - const userId = resp.body.data[0].id.trim(); - - // create project - cy.createProject(projName, 'local', userId).then((resp: Cypress.Response) => { - const projId = resp.body.id.trim(); - - // create ns - cy.createNamespaceInProject(nsName, projId); - - // check ns picker - namespacePicker.toggle(); - cy.contains(projName).should('be.visible'); - cy.contains(nsName).should('be.visible'); - - // delete project and ns - cy.deleteRancherResource('v1', 'namespaces', nsName); - cy.deleteRancherResource('v3', 'projects', projId); - - // check ns picker - cy.reload(); - namespacePicker.toggle(); - cy.contains(projName, { timeout: 10000 }).should('not.exist'); - cy.contains(nsName, { timeout: 10000 }).should('not.exist'); - }); - }); - }); + // it.skip('newly created project/namespace appears in namespace picker', { tags: ['@explorer2', '@adminUser'] }, () => { + // const projName = `project${ +new Date() }`; + // const nsName = `namespace${ +new Date() }`; + + // // get user id + // cy.getRancherResource('v3', 'users?me=true').then((resp: Cypress.Response) => { + // const userId = resp.body.data[0].id.trim(); + + // // create project + // cy.createProject(projName, 'local', userId).then((resp: Cypress.Response) => { + // const projId = resp.body.id.trim(); + + // // create ns + // cy.createNamespaceInProject(nsName, projId); + + // // check ns picker + // namespacePicker.toggle(); + // cy.contains(projName).should('be.visible'); + // cy.contains(nsName).should('be.visible'); + + // // delete project and ns + // cy.deleteRancherResource('v1', 'namespaces', nsName); + // cy.deleteRancherResource('v3', 'projects', projId); + + // // check ns picker + // cy.reload(); + // namespacePicker.toggle(); + // cy.contains(projName, { timeout: 10000 }).should('not.exist'); + // cy.contains(nsName, { timeout: 10000 }).should('not.exist'); + // }); + // }); + // }); after('clean up', () => { cy.updateNamespaceFilter('local', 'none', '{"local":["all://user"]}'); diff --git a/cypress/e2e/tests/pages/explorer2/project-namespace.spec.ts b/cypress/e2e/tests/pages/explorer2/project-namespace.spec.ts index 734aa1ead97..cb3d086a27d 100644 --- a/cypress/e2e/tests/pages/explorer2/project-namespace.spec.ts +++ b/cypress/e2e/tests/pages/explorer2/project-namespace.spec.ts @@ -107,38 +107,38 @@ describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => { }); // https://github.com/rancher/dashboard/issues/11881 - it.skip('displays the most recent error after resolving a single error in a form with multiple errors', () => { - projectsNamespacesPage.createProjectButtonClick(); - - // Create the first error - projectsNamespacesPage.name().set('test-1234'); - projectsNamespacesPage.tabResourceQuotas().click(); - projectsNamespacesPage.btnAddResource().click(); - projectsNamespacesPage.inputProjectLimit().set('50'); - projectsNamespacesPage.buttonSubmit().click(); - - // Create a second error - projectsNamespacesPage.tabContainerDefaultResourceLimit().click(); - projectsNamespacesPage.inputCpuReservation().set('1000'); - projectsNamespacesPage.inputMemoryReservation().set('128'); - projectsNamespacesPage.inputCpuLimit().set('200'); - projectsNamespacesPage.inputMemoryLimit().set('64'); - projectsNamespacesPage.buttonSubmit().click(); - - // Assert that there is only a single error message - projectsNamespacesPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota'); - projectsNamespacesPage.bannerError(0).should('have.length', 1); - projectsNamespacesPage.bannerError(1).should('have.length', 0); - - // resolve the first error - projectsNamespacesPage.tabResourceQuotas().click(); - projectsNamespacesPage.inputNamespaceDefaultLimit().set('50'); - projectsNamespacesPage.buttonSubmit().click(); - - // Click on Create again and assert that there is only a single error - projectsNamespacesPage.bannerError(0).should('be.visible').contains('admission webhook "rancher.cattle.io.projects.management.cattle.io" denied the request'); - projectsNamespacesPage.bannerError(0).should('have.length', 1); - projectsNamespacesPage.bannerError(1).should('have.length', 0); - }); + // it.skip('displays the most recent error after resolving a single error in a form with multiple errors', () => { + // projectsNamespacesPage.createProjectButtonClick(); + + // // Create the first error + // projectsNamespacesPage.name().set('test-1234'); + // projectsNamespacesPage.tabResourceQuotas().click(); + // projectsNamespacesPage.btnAddResource().click(); + // projectsNamespacesPage.inputProjectLimit().set('50'); + // projectsNamespacesPage.buttonSubmit().click(); + + // // Create a second error + // projectsNamespacesPage.tabContainerDefaultResourceLimit().click(); + // projectsNamespacesPage.inputCpuReservation().set('1000'); + // projectsNamespacesPage.inputMemoryReservation().set('128'); + // projectsNamespacesPage.inputCpuLimit().set('200'); + // projectsNamespacesPage.inputMemoryLimit().set('64'); + // projectsNamespacesPage.buttonSubmit().click(); + + // // Assert that there is only a single error message + // projectsNamespacesPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota'); + // projectsNamespacesPage.bannerError(0).should('have.length', 1); + // projectsNamespacesPage.bannerError(1).should('have.length', 0); + + // // resolve the first error + // projectsNamespacesPage.tabResourceQuotas().click(); + // projectsNamespacesPage.inputNamespaceDefaultLimit().set('50'); + // projectsNamespacesPage.buttonSubmit().click(); + + // // Click on Create again and assert that there is only a single error + // projectsNamespacesPage.bannerError(0).should('be.visible').contains('admission webhook "rancher.cattle.io.projects.management.cattle.io" denied the request'); + // projectsNamespacesPage.bannerError(0).should('have.length', 1); + // projectsNamespacesPage.bannerError(1).should('have.length', 0); + // }); }); }); diff --git a/cypress/e2e/tests/pages/explorer2/storage/persistent-volume-claims.spec.ts b/cypress/e2e/tests/pages/explorer2/storage/persistent-volume-claims.spec.ts index dd62d966c1c..ebd5bde6af6 100644 --- a/cypress/e2e/tests/pages/explorer2/storage/persistent-volume-claims.spec.ts +++ b/cypress/e2e/tests/pages/explorer2/storage/persistent-volume-claims.spec.ts @@ -14,10 +14,12 @@ describe('PersistentVolumeClaims', { testIsolation: 'off', tags: ['@explorer2', }); it('validate persistent volume claims table in empty state', () => { - persistentVolumeClaimsNoData(); + const tag = 'persistentvolumeclaimsNoData'; + + persistentVolumeClaimsNoData(tag); persistentVolumeClaimsPage.goTo(); persistentVolumeClaimsPage.waitForPage(); - cy.wait('@persistentvolumeclaimsNoData'); + cy.wait(`@${ tag }`); const expectedHeaders = ['State', 'Name', 'Namespace', 'Status', 'Volume', 'Capacity', 'Access Modes', 'Storage Class', 'VolumeAttributesClass', 'Volume Mode', 'Age']; @@ -31,10 +33,12 @@ describe('PersistentVolumeClaims', { testIsolation: 'off', tags: ['@explorer2', }); it('flat list: validate persistent volume claims table', () => { - generatePersistentVolumeClaimsDataSmall(); + const tag = 'persistentvolumeclaimsDataSmall'; + + generatePersistentVolumeClaimsDataSmall(tag); persistentVolumeClaimsPage.goTo(); persistentVolumeClaimsPage.waitForPage(); - cy.wait('@persistentvolumeclaimsDataSmall'); + cy.wait(`@${ tag }`); // check table headers are visible const expectedHeaders = ['State', 'Name', 'Namespace', 'Status', 'Volume', 'Capacity', 'Access Modes', 'Storage Class', 'VolumeAttributesClass', 'Volume Mode', 'Age']; @@ -51,11 +55,14 @@ describe('PersistentVolumeClaims', { testIsolation: 'off', tags: ['@explorer2', persistentVolumeClaimsPage.list().resourceTable().sortableTable().checkRowCount(false, 1); }); + // storage/persistent-volume-claims.spec.ts it('group by namespace: validate persistent volume claims table', () => { - generatePersistentVolumeClaimsDataSmall(); + const tag = 'persistentvolumeclaimsDataSmall'; + + generatePersistentVolumeClaimsDataSmall(tag); persistentVolumeClaimsPage.goTo(); persistentVolumeClaimsPage.waitForPage(); - cy.wait('@persistentvolumeclaimsDataSmall'); + cy.wait(`@${ tag }`); // group by namespace persistentVolumeClaimsPage.list().resourceTable().sortableTable().groupByButtons(1) diff --git a/cypress/e2e/tests/pages/explorer2/workloads/pods.spec.ts b/cypress/e2e/tests/pages/explorer2/workloads/pods.spec.ts index 4bae65e76e1..505038e8e81 100644 --- a/cypress/e2e/tests/pages/explorer2/workloads/pods.spec.ts +++ b/cypress/e2e/tests/pages/explorer2/workloads/pods.spec.ts @@ -1,9 +1,11 @@ -import { WorkloadsPodsListPagePo, WorkLoadsPodDetailsPagePo, WorkloadsPodsCreatePagePo } from '@/cypress/e2e/po/pages/explorer/workloads-pods.po'; +import { WorkloadsPodsListPagePo, WorkLoadsPodDetailsPagePo } from '@/cypress/e2e/po/pages/explorer/workloads-pods.po'; +// import { WorkloadsPodsListPagePo, WorkLoadsPodDetailsPagePo, WorkloadsPodsCreatePagePo } from '@/cypress/e2e/po/pages/explorer/workloads-pods.po'; import { createPodBlueprint, clonePodBlueprint } from '@/cypress/e2e/blueprints/explorer/workload-pods'; import PodPo from '@/cypress/e2e/po/components/workloads/pod.po'; -import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; +// import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; import HomePagePo from '@/cypress/e2e/po/pages/home.po'; import { generatePodsDataSmall } from '@/cypress/e2e/blueprints/explorer/workloads/pods/pods-get'; +import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po'; describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, () => { const workloadsPodPage = new WorkloadsPodsListPagePo('local'); @@ -13,16 +15,15 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, ( }); describe('List', { tags: ['@vai', '@adminUser'] }, () => { - const uniquePod = 'aaa-e2e-test-pod-name'; + let uniquePod = SortableTablePo.firstByDefaultName('pod'); const podNamesList = []; let nsName1: string; let nsName2: string; - let initialCount: number; + let rootResourceName: string; before('set up', () => { - cy.tableRowsPerPageAndNamespaceFilter(10, 'local', 'none', '{\"local\":[]}'); - cy.getRancherResource('v1', 'pods').then((resp: Cypress.Response) => { - initialCount = resp.body.count; + cy.getRootE2EResourceName().then((root) => { + rootResourceName = root; }); cy.createE2EResourceName('ns1').then((ns1) => { @@ -34,35 +35,39 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, ( let i = 0; while (i < 25) { - const podName = `e2e-${ Cypress._.uniqueId(Date.now().toString()) }`; + const podName = Cypress._.uniqueId(Date.now().toString()); - cy.createPod(nsName1, podName, 'nginx:alpine', false).then(() => { - podNamesList.push(`pod-${ podName }`); + cy.createPod(nsName1, podName, 'nginx:alpine', false, { createNameOptions: { prefixContext: true } }).then((resp) => { + podNamesList.push(resp.body.metadata.name); }); i++; } - }); - cy.createE2EResourceName('ns2').then((ns2) => { - nsName2 = ns2; + cy.createE2EResourceName('ns2').then((ns2) => { + nsName2 = ns2; - // create namespace - cy.createNamespace(nsName2); + // create namespace + cy.createNamespace(nsName2); - // create unique pod for filtering/sorting test - cy.createPod(nsName2, uniquePod, 'nginx:alpine'); + // create unique pod for filtering/sorting test + cy.createPod(nsName2, uniquePod, 'nginx:alpine', true, { createNameOptions: { prefixContext: true } }).then((resp) => { + uniquePod = resp.body.metadata.name; + }); + + cy.tableRowsPerPageAndNamespaceFilter(10, 'local', 'none', `{\"local\":[\"ns://${ nsName1 }\",\"ns://${ nsName2 }\"]}`); + }); }); }); it('pagination is visible and user is able to navigate through pods data', () => { - // check pods count - const count = initialCount + 26; + WorkloadsPodsListPagePo.goTo('local'); + workloadsPodPage.waitForPage(); - cy.waitForRancherResources('v1', 'pods', count).then((resp: Cypress.Response) => { - WorkloadsPodsListPagePo.navTo(); - workloadsPodPage.waitForPage(); + // check pods count + const count = podNamesList.length + 1; + cy.waitForRancherResources('v1', 'pods', count - 1, true).then((resp: Cypress.Response) => { // pagination is visible workloadsPodPage.sortableTable().pagination().checkVisible(); @@ -98,7 +103,8 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, ( workloadsPodPage.sortableTable().pagination().leftButton().isDisabled(); // navigate to last page - end button - workloadsPodPage.sortableTable().pagination().endButton().click(); + workloadsPodPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // row count on last page let lastPageCount = count % 10; @@ -128,12 +134,13 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, ( WorkloadsPodsListPagePo.navTo(); workloadsPodPage.waitForPage(); // use filter to only show test data - workloadsPodPage.sortableTable().filter('e2e-'); + workloadsPodPage.sortableTable().filter(rootResourceName); // check table is sorted by name in ASC order by default workloadsPodPage.sortableTable().tableHeaderRow().checkSortOrder(2, 'down'); // pod name should be visible on first page (sorted in ASC order) + workloadsPodPage.sortableTable().tableHeaderRow().self().scrollIntoView(); workloadsPodPage.sortableTable().rowElementWithName(podNamesList[0]).scrollIntoView().should('be.visible'); // sort by name in DESC order @@ -144,7 +151,8 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, ( workloadsPodPage.sortableTable().rowElementWithName(podNamesList[0]).should('not.exist'); // navigate to last page - workloadsPodPage.sortableTable().pagination().endButton().click(); + workloadsPodPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // pod name should be visible on last page (sorted in DESC order) workloadsPodPage.sortableTable().rowElementWithName(podNamesList[0]).scrollIntoView().should('be.visible'); @@ -166,10 +174,12 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, ( // filter by namespace workloadsPodPage.sortableTable().filter(nsName2); workloadsPodPage.sortableTable().checkRowCount(false, 1); - workloadsPodPage.sortableTable().rowElementWithName(`pod-${ uniquePod }`).should('be.visible'); + workloadsPodPage.sortableTable().rowElementWithName(uniquePod).should('be.visible'); }); it('pagination is hidden', () => { + cy.tableRowsPerPageAndNamespaceFilter(10, 'local', 'none', '{"local":[]}'); + // generate small set of pods data generatePodsDataSmall(); HomePagePo.goTo(); // this is needed here for the intercept to work @@ -271,57 +281,57 @@ describe('Pods', { testIsolation: 'off', tags: ['@explorer2', '@adminUser'] }, ( }); }); - describe.skip('[Vue3 Skip]: should delete pod', () => { - const podName = `pod-${ Date.now() }`; + // describe.skip('[Vue3 Skip]: should delete pod', () => { + // const podName = `pod-${ Date.now() }`; - beforeEach(() => { - workloadsPodPage.goTo(); - }); + // beforeEach(() => { + // workloadsPodPage.goTo(); + // }); - it('dialog should open/close as expected', () => { - const podCreatePage = new WorkloadsPodsCreatePagePo('local'); + // it('dialog should open/close as expected', () => { + // const podCreatePage = new WorkloadsPodsCreatePagePo('local'); - podCreatePage.goTo(); + // podCreatePage.goTo(); - podCreatePage.createWithUI(podName, 'nginx', 'default'); + // podCreatePage.createWithUI(podName, 'nginx', 'default'); - // Should be on the list view - const podsListPage = new WorkloadsPodsListPagePo('local'); + // // Should be on the list view + // const podsListPage = new WorkloadsPodsListPagePo('local'); - // Filter the list to just show the newly created pod - podsListPage.list().resourceTable().sortableTable().filter(podName); - podsListPage.list().resourceTable().sortableTable().checkRowCount(false, 1); + // // Filter the list to just show the newly created pod + // podsListPage.list().resourceTable().sortableTable().filter(podName); + // podsListPage.list().resourceTable().sortableTable().checkRowCount(false, 1); - // Open action menu and delete for the first item - podsListPage.list().resourceTable().sortableTable().rowActionMenuOpen(podName) - .getMenuItem('Delete') - .click(); + // // Open action menu and delete for the first item + // podsListPage.list().resourceTable().sortableTable().rowActionMenuOpen(podName) + // .getMenuItem('Delete') + // .click(); - let dialog = new PromptRemove(); + // let dialog = new PromptRemove(); - dialog.checkExists(); - dialog.checkVisible(); + // dialog.checkExists(); + // dialog.checkVisible(); - dialog.cancel(); - dialog.checkNotExists(); + // dialog.cancel(); + // dialog.checkNotExists(); - podsListPage.list().resourceTable().sortableTable().checkRowCount(false, 1); + // podsListPage.list().resourceTable().sortableTable().checkRowCount(false, 1); - // Open action menu and delete for the first item - podsListPage.list().resourceTable().sortableTable().rowActionMenuOpen(podName) - .getMenuItem('Delete') - .click(); + // // Open action menu and delete for the first item + // podsListPage.list().resourceTable().sortableTable().rowActionMenuOpen(podName) + // .getMenuItem('Delete') + // .click(); - dialog = new PromptRemove(); + // dialog = new PromptRemove(); - dialog.checkExists(); - dialog.checkVisible(); - dialog.remove(); - dialog.checkNotExists(); + // dialog.checkExists(); + // dialog.checkVisible(); + // dialog.remove(); + // dialog.checkNotExists(); - podsListPage.list().resourceTable().sortableTable().checkRowCount(true, 1, true); + // podsListPage.list().resourceTable().sortableTable().checkRowCount(true, 1, true); - podsListPage.list().resourceTable().sortableTable().resetFilter(); - }); - }); + // podsListPage.list().resourceTable().sortableTable().resetFilter(); + // }); + // }); }); diff --git a/cypress/e2e/tests/pages/extensions/extensions.spec.ts b/cypress/e2e/tests/pages/extensions/extensions.spec.ts index 1d656c58682..a8104f908f8 100644 --- a/cypress/e2e/tests/pages/extensions/extensions.spec.ts +++ b/cypress/e2e/tests/pages/extensions/extensions.spec.ts @@ -2,12 +2,12 @@ import ExtensionsPagePo from '@/cypress/e2e/po/pages/extensions.po'; import RepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po'; import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; -import { LoginPagePo } from '@/cypress/e2e/po/pages/login-page.po'; +// import { LoginPagePo } from '@/cypress/e2e/po/pages/login-page.po'; -const DISABLED_CACHE_EXTENSION_NAME = 'large-extension'; -const DISABLED_CACHE_EXTENSION_MENU_LABEL = 'Large-extension'; -const DISABLED_CACHE_EXTENSION_TITLE = 'Large extension demo (> 20mb) - cache testing'; -const UNAUTHENTICATED_EXTENSION_NAME = 'uk-locale'; +// const DISABLED_CACHE_EXTENSION_NAME = 'large-extension'; +// const DISABLED_CACHE_EXTENSION_MENU_LABEL = 'Large-extension'; +// const DISABLED_CACHE_EXTENSION_TITLE = 'Large extension demo (> 20mb) - cache testing'; +// const UNAUTHENTICATED_EXTENSION_NAME = 'uk-locale'; const EXTENSION_NAME = 'clock'; const UI_PLUGINS_PARTNERS_REPO_URL = 'https://github.com/rancher/partner-extensions'; const UI_PLUGINS_PARTNERS_REPO_NAME = 'partner-extensions'; @@ -246,227 +246,227 @@ describe('Extensions page', { tags: ['@extensions', '@adminUser'] }, () => { extensionsPo.extensionDetails().should('not.be.visible'); }); - it.skip('[Vue3 Skip]: Should install an extension', () => { - const extensionsPo = new ExtensionsPagePo(); - - extensionsPo.goTo(); - - extensionsPo.extensionTabAvailableClick(); - - // click on install button on card - extensionsPo.extensionCardInstallClick(EXTENSION_NAME); - extensionsPo.extensionInstallModal().should('be.visible'); - - // select version and click install - extensionsPo.installModalSelectVersionClick(2); - extensionsPo.installModalInstallClick(); + // it.skip('[Vue3 Skip]: Should install an extension', () => { + // const extensionsPo = new ExtensionsPagePo(); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // extensionsPo.goTo(); - // make sure extension card is in the installed tab - extensionsPo.extensionTabInstalledClick(); - extensionsPo.extensionCardClick(EXTENSION_NAME); - extensionsPo.extensionDetailsTitle().should('contain', EXTENSION_NAME); - extensionsPo.extensionDetailsCloseClick(); - }); - - it.skip('[Vue3 Skip]: Should not display installed extensions within the available tab', () => { - const extensionsPo = new ExtensionsPagePo(); + // extensionsPo.extensionTabAvailableClick(); - extensionsPo.goTo(); + // // click on install button on card + // extensionsPo.extensionCardInstallClick(EXTENSION_NAME); + // extensionsPo.extensionInstallModal().should('be.visible'); - // check for installed extension in "installed" tab - extensionsPo.extensionTabInstalledClick(); - extensionsPo.extensionCard(EXTENSION_NAME).should('be.visible'); + // // select version and click install + // extensionsPo.installModalSelectVersionClick(2); + // extensionsPo.installModalInstallClick(); - // check for installed extension in "available" tab - extensionsPo.extensionTabAvailableClick(); - extensionsPo.extensionCard(EXTENSION_NAME).should('not.exist'); - }); + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); - it.skip('[Vue3 Skip]: Should update an extension version', () => { - const extensionsPo = new ExtensionsPagePo(); + // // make sure extension card is in the installed tab + // extensionsPo.extensionTabInstalledClick(); + // extensionsPo.extensionCardClick(EXTENSION_NAME); + // extensionsPo.extensionDetailsTitle().should('contain', EXTENSION_NAME); + // extensionsPo.extensionDetailsCloseClick(); + // }); - extensionsPo.goTo(); + // it.skip('[Vue3 Skip]: Should not display installed extensions within the available tab', () => { + // const extensionsPo = new ExtensionsPagePo(); - extensionsPo.extensionTabInstalledClick(); + // extensionsPo.goTo(); - // click on update button on card - extensionsPo.extensionCardUpdateClick(EXTENSION_NAME); - extensionsPo.installModalInstallClick(); + // // check for installed extension in "installed" tab + // extensionsPo.extensionTabInstalledClick(); + // extensionsPo.extensionCard(EXTENSION_NAME).should('be.visible'); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // // check for installed extension in "available" tab + // extensionsPo.extensionTabAvailableClick(); + // extensionsPo.extensionCard(EXTENSION_NAME).should('not.exist'); + // }); - // make sure extension card is not available anymore on the updates tab - // since we installed the latest version - extensionsPo.extensionTabUpdatesClick(); - extensionsPo.extensionCard(EXTENSION_NAME).should('not.exist'); - }); + // it.skip('[Vue3 Skip]: Should update an extension version', () => { + // const extensionsPo = new ExtensionsPagePo(); - it.skip('[Vue3 Skip]: Should rollback an extension version', () => { - const extensionsPo = new ExtensionsPagePo(); + // extensionsPo.goTo(); - extensionsPo.goTo(); + // extensionsPo.extensionTabInstalledClick(); - extensionsPo.extensionTabInstalledClick(); + // // click on update button on card + // extensionsPo.extensionCardUpdateClick(EXTENSION_NAME); + // extensionsPo.installModalInstallClick(); - // click on the rollback button on card - // this will rollback to the immediate previous version - extensionsPo.extensionCardRollbackClick(EXTENSION_NAME); - extensionsPo.installModalInstallClick(); + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // // make sure extension card is not available anymore on the updates tab + // // since we installed the latest version + // extensionsPo.extensionTabUpdatesClick(); + // extensionsPo.extensionCard(EXTENSION_NAME).should('not.exist'); + // }); - // make sure extension card is on the updates tab - extensionsPo.extensionTabUpdatesClick(); - extensionsPo.extensionCard(EXTENSION_NAME).should('be.visible'); - }); + // it.skip('[Vue3 Skip]: Should rollback an extension version', () => { + // const extensionsPo = new ExtensionsPagePo(); - it.skip('[Vue3 Skip]: An extension larger than 20mb, which will trigger chacheState disabled, should install and work fine', () => { - const extensionsPo = new ExtensionsPagePo(); + // extensionsPo.goTo(); - extensionsPo.goTo(); + // extensionsPo.extensionTabInstalledClick(); - extensionsPo.extensionTabAvailableClick(); + // // click on the rollback button on card + // // this will rollback to the immediate previous version + // extensionsPo.extensionCardRollbackClick(EXTENSION_NAME); + // extensionsPo.installModalInstallClick(); - // click on install button on card - extensionsPo.extensionCardInstallClick(DISABLED_CACHE_EXTENSION_NAME); - extensionsPo.extensionInstallModal().should('be.visible'); + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); - // click install - extensionsPo.installModalInstallClick(); + // // make sure extension card is on the updates tab + // extensionsPo.extensionTabUpdatesClick(); + // extensionsPo.extensionCard(EXTENSION_NAME).should('be.visible'); + // }); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // it.skip('[Vue3 Skip]: An extension larger than 20mb, which will trigger chacheState disabled, should install and work fine', () => { + // const extensionsPo = new ExtensionsPagePo(); - // make sure extension card is in the installed tab - extensionsPo.extensionTabInstalledClick(); - extensionsPo.extensionCardClick(DISABLED_CACHE_EXTENSION_NAME); - extensionsPo.extensionDetailsTitle().should('contain', DISABLED_CACHE_EXTENSION_NAME); - extensionsPo.extensionDetailsCloseClick(); + // extensionsPo.goTo(); - // check if extension is working fine - BurgerMenuPo.burgerMenuNavToMenubyLabel(DISABLED_CACHE_EXTENSION_MENU_LABEL); - cy.get('h1').should('have.text', DISABLED_CACHE_EXTENSION_TITLE); - }); + // extensionsPo.extensionTabAvailableClick(); - it.skip('[Vue3 Skip]: Should respect authentication when importing extension scripts', () => { - const extensionsPo = new ExtensionsPagePo(); + // // click on install button on card + // extensionsPo.extensionCardInstallClick(DISABLED_CACHE_EXTENSION_NAME); + // extensionsPo.extensionInstallModal().should('be.visible'); - extensionsPo.goTo(); + // // click install + // extensionsPo.installModalInstallClick(); - extensionsPo.extensionTabAvailableClick(); + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); - // Install unauthenticated extension - extensionsPo.extensionCardInstallClick(UNAUTHENTICATED_EXTENSION_NAME); - extensionsPo.extensionInstallModal().should('be.visible'); - extensionsPo.installModalInstallClick(); + // // make sure extension card is in the installed tab + // extensionsPo.extensionTabInstalledClick(); + // extensionsPo.extensionCardClick(DISABLED_CACHE_EXTENSION_NAME); + // extensionsPo.extensionDetailsTitle().should('contain', DISABLED_CACHE_EXTENSION_NAME); + // extensionsPo.extensionDetailsCloseClick(); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // // check if extension is working fine + // BurgerMenuPo.burgerMenuNavToMenubyLabel(DISABLED_CACHE_EXTENSION_MENU_LABEL); + // cy.get('h1').should('have.text', DISABLED_CACHE_EXTENSION_TITLE); + // }); - // make sure both extensions have been imported - extensionsPo.extensionScriptImport(UNAUTHENTICATED_EXTENSION_NAME).should('exist'); - extensionsPo.extensionScriptImport(EXTENSION_NAME).should('exist'); + // it.skip('[Vue3 Skip]: Should respect authentication when importing extension scripts', () => { + // const extensionsPo = new ExtensionsPagePo(); - cy.logout(); + // extensionsPo.goTo(); - // make sure only the unauthenticated extension has been imported after logout - const loginPage = new LoginPagePo(); + // extensionsPo.extensionTabAvailableClick(); - loginPage.goTo(); - loginPage.waitForPage(); - loginPage.extensionScriptImport(UNAUTHENTICATED_EXTENSION_NAME).should('exist'); - loginPage.extensionScriptImport(EXTENSION_NAME).should('not.exist'); + // // Install unauthenticated extension + // extensionsPo.extensionCardInstallClick(UNAUTHENTICATED_EXTENSION_NAME); + // extensionsPo.extensionInstallModal().should('be.visible'); + // extensionsPo.installModalInstallClick(); - // make sure both extensions have been imported after logging in again - cy.login(undefined, undefined, false); - extensionsPo.goTo(); - extensionsPo.waitForPage(); - extensionsPo.waitForTitle(); - extensionsPo.extensionScriptImport(UNAUTHENTICATED_EXTENSION_NAME).should('exist'); - extensionsPo.extensionScriptImport(EXTENSION_NAME).should('exist'); - }); + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); - it.skip('[Vue3 Skip]: Should uninstall extensions', () => { - // Because we logged out in the previous test this one will also have to use an uncached login - cy.login(undefined, undefined, false); - const extensionsPo = new ExtensionsPagePo(); + // // make sure both extensions have been imported + // extensionsPo.extensionScriptImport(UNAUTHENTICATED_EXTENSION_NAME).should('exist'); + // extensionsPo.extensionScriptImport(EXTENSION_NAME).should('exist'); - extensionsPo.goTo(); + // cy.logout(); - extensionsPo.extensionTabInstalledClick(); + // // make sure only the unauthenticated extension has been imported after logout + // const loginPage = new LoginPagePo(); - // click on uninstall button on card - extensionsPo.extensionCardUninstallClick(EXTENSION_NAME); - extensionsPo.extensionUninstallModal().should('be.visible'); - extensionsPo.uninstallModaluninstallClick(); - extensionsPo.extensionReloadBanner().should('be.visible'); + // loginPage.goTo(); + // loginPage.waitForPage(); + // loginPage.extensionScriptImport(UNAUTHENTICATED_EXTENSION_NAME).should('exist'); + // loginPage.extensionScriptImport(EXTENSION_NAME).should('not.exist'); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // // make sure both extensions have been imported after logging in again + // cy.login(undefined, undefined, false); + // extensionsPo.goTo(); + // extensionsPo.waitForPage(); + // extensionsPo.waitForTitle(); + // extensionsPo.extensionScriptImport(UNAUTHENTICATED_EXTENSION_NAME).should('exist'); + // extensionsPo.extensionScriptImport(EXTENSION_NAME).should('exist'); + // }); - // make sure extension card is in the available tab - extensionsPo.extensionTabAvailableClick(); - extensionsPo.extensionCardClick(EXTENSION_NAME); - extensionsPo.extensionDetailsTitle().should('contain', EXTENSION_NAME); - }); + // it.skip('[Vue3 Skip]: Should uninstall extensions', () => { + // // Because we logged out in the previous test this one will also have to use an uncached login + // cy.login(undefined, undefined, false); + // const extensionsPo = new ExtensionsPagePo(); - it.skip('[Vue3 Skip]: Should uninstall unathenticated extensions', () => { - // Because we logged out in the previous test this one will also have to use an uncached login - cy.login(undefined, undefined, false); - const extensionsPo = new ExtensionsPagePo(); + // extensionsPo.goTo(); - extensionsPo.goTo(); + // extensionsPo.extensionTabInstalledClick(); - extensionsPo.extensionTabInstalledClick(); + // // click on uninstall button on card + // extensionsPo.extensionCardUninstallClick(EXTENSION_NAME); + // extensionsPo.extensionUninstallModal().should('be.visible'); + // extensionsPo.uninstallModaluninstallClick(); + // extensionsPo.extensionReloadBanner().should('be.visible'); - // click on uninstall button on card - extensionsPo.extensionCardUninstallClick(UNAUTHENTICATED_EXTENSION_NAME); - extensionsPo.extensionUninstallModal().should('be.visible'); - extensionsPo.uninstallModaluninstallClick(); - extensionsPo.extensionReloadBanner().should('be.visible'); + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // // make sure extension card is in the available tab + // extensionsPo.extensionTabAvailableClick(); + // extensionsPo.extensionCardClick(EXTENSION_NAME); + // extensionsPo.extensionDetailsTitle().should('contain', EXTENSION_NAME); + // }); - // make sure extension card is in the available tab - extensionsPo.extensionTabAvailableClick(); - extensionsPo.extensionCardClick(UNAUTHENTICATED_EXTENSION_NAME); - extensionsPo.extensionDetailsTitle().should('contain', UNAUTHENTICATED_EXTENSION_NAME); - }); + // it.skip('[Vue3 Skip]: Should uninstall unathenticated extensions', () => { + // // Because we logged out in the previous test this one will also have to use an uncached login + // cy.login(undefined, undefined, false); + // const extensionsPo = new ExtensionsPagePo(); - it.skip('[Vue3 Skip]: Should uninstall un-cached extensions', () => { - // Because we logged out in the previous test this one will also have to use an uncached login - cy.login(undefined, undefined, false); - const extensionsPo = new ExtensionsPagePo(); + // extensionsPo.goTo(); - extensionsPo.goTo(); + // extensionsPo.extensionTabInstalledClick(); - extensionsPo.extensionTabInstalledClick(); + // // click on uninstall button on card + // extensionsPo.extensionCardUninstallClick(UNAUTHENTICATED_EXTENSION_NAME); + // extensionsPo.extensionUninstallModal().should('be.visible'); + // extensionsPo.uninstallModaluninstallClick(); + // extensionsPo.extensionReloadBanner().should('be.visible'); + + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); + + // // make sure extension card is in the available tab + // extensionsPo.extensionTabAvailableClick(); + // extensionsPo.extensionCardClick(UNAUTHENTICATED_EXTENSION_NAME); + // extensionsPo.extensionDetailsTitle().should('contain', UNAUTHENTICATED_EXTENSION_NAME); + // }); + + // it.skip('[Vue3 Skip]: Should uninstall un-cached extensions', () => { + // // Because we logged out in the previous test this one will also have to use an uncached login + // cy.login(undefined, undefined, false); + // const extensionsPo = new ExtensionsPagePo(); - // click on uninstall button on card - extensionsPo.extensionCardUninstallClick(DISABLED_CACHE_EXTENSION_NAME); - extensionsPo.extensionUninstallModal().should('be.visible'); - extensionsPo.uninstallModaluninstallClick(); + // extensionsPo.goTo(); + + // extensionsPo.extensionTabInstalledClick(); - // let's check the extension reload banner and reload the page - extensionsPo.extensionReloadBanner().should('be.visible'); - extensionsPo.extensionReloadClick(); + // // click on uninstall button on card + // extensionsPo.extensionCardUninstallClick(DISABLED_CACHE_EXTENSION_NAME); + // extensionsPo.extensionUninstallModal().should('be.visible'); + // extensionsPo.uninstallModaluninstallClick(); - // make sure extension card is in the available tab - extensionsPo.extensionTabAvailableClick(); - extensionsPo.extensionCardClick(DISABLED_CACHE_EXTENSION_NAME); - extensionsPo.extensionDetailsTitle().should('contain', DISABLED_CACHE_EXTENSION_NAME); - }); + // // let's check the extension reload banner and reload the page + // extensionsPo.extensionReloadBanner().should('be.visible'); + // extensionsPo.extensionReloadClick(); + + // // make sure extension card is in the available tab + // extensionsPo.extensionTabAvailableClick(); + // extensionsPo.extensionCardClick(DISABLED_CACHE_EXTENSION_NAME); + // extensionsPo.extensionDetailsTitle().should('contain', DISABLED_CACHE_EXTENSION_NAME); + // }); }); diff --git a/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts b/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts index e4bb4685a03..d74342d9722 100644 --- a/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts +++ b/cypress/e2e/tests/pages/fleet/advanced/workspaces.spec.ts @@ -2,6 +2,7 @@ import { FleetWorkspaceListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cat import FleetWorkspaceDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.fleetworkspace.po'; import { generateFleetWorkspacesDataSmall } from '@/cypress/e2e/blueprints/fleet/workspaces-get'; import HomePagePo from '~/cypress/e2e/po/pages/home.po'; +import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po'; const defaultWorkspace = 'fleet-default'; const workspaceNameList = []; @@ -70,7 +71,7 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, }); }); - const uniqueWorkspaceName = 'aaa-e2e-test-name'; + let uniqueWorkspaceName = SortableTablePo.firstByDefaultName('workspace'); before('set up', () => { cy.getRancherResource('v1', 'management.cattle.io.fleetworkspaces').then((resp: Cypress.Response) => { @@ -80,10 +81,10 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, let i = 0; while (i < 25) { - const workspaceName = `e2e-${ Cypress._.uniqueId(Date.now().toString()) }`; + const workspaceName = Cypress._.uniqueId(Date.now().toString()); const workspaceDesc = `e2e-desc-${ Cypress._.uniqueId(Date.now().toString()) }`; - cy.createFleetWorkspace(workspaceName, workspaceDesc, false).then((resp: Cypress.Response) => { + cy.createFleetWorkspace(workspaceName, workspaceDesc, false, { createNameOptions: { prefixContext: true } }).then((resp: Cypress.Response) => { const wsId = resp.body.id; workspaceNameList.push(wsId); @@ -93,9 +94,11 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, } // create one more for sorting test - cy.createFleetWorkspace(uniqueWorkspaceName).then((resp: Cypress.Response) => { + cy.createFleetWorkspace(uniqueWorkspaceName, undefined, true, { createNameOptions: { prefixContext: true } }).then((resp: Cypress.Response) => { const wsId = resp.body.id; + uniqueWorkspaceName = resp.body.name; + workspaceNameList.push(wsId); }); cy.tableRowsPerPageAndNamespaceFilter(10, 'local', 'none', '{\"local\":[]}'); @@ -148,7 +151,8 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, fleetWorkspacesPage.sortableTable().pagination().leftButton().isDisabled(); // navigate to last page - end button - fleetWorkspacesPage.sortableTable().pagination().endButton().click(); + fleetWorkspacesPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // check row count on last page fleetWorkspacesPage.sortableTable().checkRowCount(false, count - 20); @@ -193,10 +197,12 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, fleetWorkspacesPage.sortableTable().tableHeaderRow().checkSortOrder(2, 'down'); // workspace name should be visible on first page (sorted in ASC order) + fleetWorkspacesPage.sortableTable().tableHeaderRow().self().scrollIntoView(); fleetWorkspacesPage.sortableTable().rowElementWithName(uniqueWorkspaceName).scrollIntoView().should('be.visible'); // navigate to last page - fleetWorkspacesPage.sortableTable().pagination().endButton().click(); + fleetWorkspacesPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // workspace name should be NOT visible on last page (sorted in ASC order) fleetWorkspacesPage.sortableTable().rowElementWithName(uniqueWorkspaceName).should('not.exist'); @@ -209,7 +215,8 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, fleetWorkspacesPage.sortableTable().rowElementWithName(uniqueWorkspaceName).should('not.exist'); // navigate to last page - fleetWorkspacesPage.sortableTable().pagination().endButton().click(); + fleetWorkspacesPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // workspace name should be visible on last page (sorted in DESC order) fleetWorkspacesPage.sortableTable().rowElementWithName(uniqueWorkspaceName).scrollIntoView().should('be.visible'); diff --git a/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts b/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts index dcdc0719741..6c5f6bf5700 100644 --- a/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts +++ b/cypress/e2e/tests/pages/fleet/gitrepo.spec.ts @@ -139,7 +139,7 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ( prefPage.languageDropdownMenu().clickOptionWithLabel('English'); cy.wait('@prefUpdateEnUs').then(({ response }) => { expect(response?.statusCode).to.eq(200); - expect(response?.body.data).to.have.property('locale', 'en-us'); + expect(response?.body.data).to.have.property('locale', 'en-us'); // Flake: This can sometimes be zh-hans.....?! }); prefPage.languageDropdownMenu().isClosed(); }) diff --git a/cypress/e2e/tests/pages/global-settings/settings.spec.ts b/cypress/e2e/tests/pages/global-settings/settings.spec.ts index f156c4c9386..907491d4963 100644 --- a/cypress/e2e/tests/pages/global-settings/settings.spec.ts +++ b/cypress/e2e/tests/pages/global-settings/settings.spec.ts @@ -7,11 +7,13 @@ import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/clu import * as path from 'path'; import * as jsyaml from 'js-yaml'; import { settings } from '@/cypress/e2e/blueprints/global_settings/settings-data'; +import UserMenuPo from '@/cypress/e2e/po/side-bars/user-menu.po'; const settingsPage = new SettingsPagePo('local'); const accountPage = new AccountPagePo(); const createKeyPage = new CreateKeyPagePo(); const clusterList = new ClusterManagerListPagePo(); +const userMenu = new UserMenuPo(); describe('Settings', { testIsolation: 'off' }, () => { before(() => { @@ -223,6 +225,9 @@ describe('Settings', { testIsolation: 'off' }, () => { }); it('can update auth-token-max-ttl-minutes', { tags: ['@globalSettings', '@adminUser'] }, () => { + userMenu.getMenuItem('Account & API Keys').should('be.visible'); // Flaky test. Check required menu item visible (and not hidden later on due to content of test) + userMenu.self().click(); + // Update setting SettingsPagePo.navTo(); settingsPage.editSettingsByLabel('auth-token-max-ttl-minutes'); diff --git a/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts b/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts index ab9558aeb24..c54c3c24cdb 100644 --- a/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts +++ b/cypress/e2e/tests/pages/manager/cluster-manager.spec.ts @@ -375,8 +375,8 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs clusterList.sortableTable().rowElementWithName(rke1CustomName).should('exist'); }); - it.skip('can create new snapshots', () => { - }); + // it.skip('can create new snapshots', () => { + // }); it('can show snapshots list', () => { clusterList.goToClusterListAndGetClusterDetails(rke1CustomName).then((cluster) => { @@ -432,8 +432,8 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs }); }); - it.skip('can delete snapshots', () => { - }); + // it.skip('can delete snapshots', () => { + // }); it('can delete cluster', () => { clusterList.goTo(); diff --git a/cypress/e2e/tests/pages/manager/kontainer-drivers.spec.ts b/cypress/e2e/tests/pages/manager/kontainer-drivers.spec.ts index 6b2c85b0117..513aecd2981 100644 --- a/cypress/e2e/tests/pages/manager/kontainer-drivers.spec.ts +++ b/cypress/e2e/tests/pages/manager/kontainer-drivers.spec.ts @@ -177,8 +177,8 @@ describe('Kontainer Drivers', { testIsolation: 'off', tags: ['@manager', '@admin it('can deactivate drivers in bulk', () => { KontainerDriversPagePo.navTo(); driversPage.waitForPage(); - driversPage.list().details(oracleDriver, 1).should('contain', 'Active'); - driversPage.list().details(linodeDriver, 1).should('contain', 'Active'); + driversPage.list().details(oracleDriver, 1).scrollIntoView().should('contain', 'Active'); + driversPage.list().details(linodeDriver, 1).scrollIntoView().should('contain', 'Active'); driversPage.list().resourceTable().sortableTable().rowSelectCtlWithName(oracleDriver) .set(); driversPage.list().resourceTable().sortableTable().rowSelectCtlWithName(linodeDriver) diff --git a/cypress/e2e/tests/pages/manager/mock-responses.ts b/cypress/e2e/tests/pages/manager/mock-responses.ts index 6335ee40bbf..cc3f81878f3 100644 --- a/cypress/e2e/tests/pages/manager/mock-responses.ts +++ b/cypress/e2e/tests/pages/manager/mock-responses.ts @@ -1,3 +1,5 @@ +import { CYPRESS_SAFE_RESOURCE_REVISION } from '@/cypress/e2e/blueprints/blueprint.utils'; + export function nodeDriveResponse(addCloudCredential: boolean, driver: string): any { return { type: 'collection', @@ -29,7 +31,7 @@ export function nodeDriveResponse(addCloudCredential: boolean, driver: string): }, { toId: `${ driver }config`, toType: 'management.cattle.io.dynamicschema', rel: 'owner', state: 'active', message: 'Resource is current' }], - resourceVersion: '3117786', + resourceVersion: CYPRESS_SAFE_RESOURCE_REVISION, state: { error: false, message: '', name: 'active', transitioning: false }, diff --git a/cypress/e2e/tests/pages/manager/node-drivers.spec.ts b/cypress/e2e/tests/pages/manager/node-drivers.spec.ts index 1b38a5e0211..e9c6e1ce559 100644 --- a/cypress/e2e/tests/pages/manager/node-drivers.spec.ts +++ b/cypress/e2e/tests/pages/manager/node-drivers.spec.ts @@ -208,39 +208,39 @@ describe.skip('Node Drivers', { testIsolation: 'off', tags: ['@manager', '@admin createCluster.gridElementExistanceByName(openStackDriver, 'exist'); }); - it.skip('can deactivate drivers in bulk', () => { - // Skipping this test until issue is resolved https://github.com/rancher/dashboard/issues/10718 - NodeDriversPagePo.navTo(); - driversPage.waitForPage(); - driversPage.list().details(oracleDriver, 1).should('contain', 'Active'); - driversPage.list().details(openStackDriver, 1).should('contain', 'Active'); - driversPage.list().resourceTable().sortableTable().rowSelectCtlWithName(oracleDriver) - .set(); - driversPage.list().resourceTable().sortableTable().rowSelectCtlWithName(openStackDriver) - .set(); - driversPage.list().resourceTable().sortableTable().bulkActionDropDownOpen(); - driversPage.list().resourceTable().sortableTable().bulkActionDropDownButton('Deactivate') - .click(); - - cy.intercept('POST', '/v3/nodeDrivers/oci?action=deactivate').as('deactivateOracleDriver'); - cy.intercept('POST', '/v3/nodeDrivers/openstack?action=deactivate').as('deactivateopenStackDriver'); - - const deactivateDialog = new DeactivateDriverDialogPo(); - - deactivateDialog.deactivate(); - cy.wait('@deactivateopenStackDriver').its('response.statusCode').should('eq', 200); - cy.wait('@deactivateOracleDriver').its('response.statusCode').should('eq', 200); - driversPage.list().details(oracleDriver, 1).should('contain', 'Inactive'); - driversPage.list().details(openStackDriver, 1).should('contain', 'Inactive'); - - // check options on cluster create page - ClusterManagerListPagePo.navTo(); - clusterList.waitForPage(); - clusterList.createCluster(); - createCluster.waitForPage(); - createCluster.gridElementExistanceByName(oracleDriver, 'not.exist'); - createCluster.gridElementExistanceByName(openStackDriver, 'not.exist'); - }); + // it.skip('can deactivate drivers in bulk', () => { + // // Skipping this test until issue is resolved https://github.com/rancher/dashboard/issues/10718 + // NodeDriversPagePo.navTo(); + // driversPage.waitForPage(); + // driversPage.list().details(oracleDriver, 1).should('contain', 'Active'); + // driversPage.list().details(openStackDriver, 1).should('contain', 'Active'); + // driversPage.list().resourceTable().sortableTable().rowSelectCtlWithName(oracleDriver) + // .set(); + // driversPage.list().resourceTable().sortableTable().rowSelectCtlWithName(openStackDriver) + // .set(); + // driversPage.list().resourceTable().sortableTable().bulkActionDropDownOpen(); + // driversPage.list().resourceTable().sortableTable().bulkActionDropDownButton('Deactivate') + // .click(); + + // cy.intercept('POST', '/v3/nodeDrivers/oci?action=deactivate').as('deactivateOracleDriver'); + // cy.intercept('POST', '/v3/nodeDrivers/openstack?action=deactivate').as('deactivateopenStackDriver'); + + // const deactivateDialog = new DeactivateDriverDialogPo(); + + // deactivateDialog.deactivate(); + // cy.wait('@deactivateopenStackDriver').its('response.statusCode').should('eq', 200); + // cy.wait('@deactivateOracleDriver').its('response.statusCode').should('eq', 200); + // driversPage.list().details(oracleDriver, 1).should('contain', 'Inactive'); + // driversPage.list().details(openStackDriver, 1).should('contain', 'Inactive'); + + // // check options on cluster create page + // ClusterManagerListPagePo.navTo(); + // clusterList.waitForPage(); + // clusterList.createCluster(); + // createCluster.waitForPage(); + // createCluster.gridElementExistanceByName(oracleDriver, 'not.exist'); + // createCluster.gridElementExistanceByName(openStackDriver, 'not.exist'); + // }); it('can delete drivers in bulk', () => { NodeDriversPagePo.navTo(); 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 24cfc871159..d88d4c8c505 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 @@ -181,7 +181,8 @@ describe.skip('Account and API Keys', { testIsolation: 'off' }, () => { accountPage.sortableTable().pagination().leftButton().isDisabled(); // navigate to last page - end button - accountPage.sortableTable().pagination().endButton().click(); + accountPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // row count on last page let lastPageCount = count % 10; @@ -243,7 +244,8 @@ describe.skip('Account and API Keys', { testIsolation: 'off' }, () => { accountPage.sortableTable().rowElementWithName(uniqueTokenDesc).scrollIntoView().should('be.visible'); // navigate to last page - accountPage.sortableTable().pagination().endButton().click(); + accountPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // token description should be NOT visible on last page (sorted in ASC order) accountPage.sortableTable().rowElementWithName(uniqueTokenDesc).should('not.exist'); @@ -256,7 +258,8 @@ describe.skip('Account and API Keys', { testIsolation: 'off' }, () => { accountPage.sortableTable().rowElementWithName(uniqueTokenDesc).should('not.exist'); // navigate to last page - accountPage.sortableTable().pagination().endButton().click(); + accountPage.sortableTable().pagination().endButton().scrollIntoView() + .click(); // token description should be visible on last page (sorted in DESC order) accountPage.sortableTable().rowElementWithName(uniqueTokenDesc).scrollIntoView().should('be.visible'); diff --git a/cypress/e2e/tests/pages/user-menu/preferences.spec.ts b/cypress/e2e/tests/pages/user-menu/preferences.spec.ts index 73547881e5d..e04f856e9a6 100644 --- a/cypress/e2e/tests/pages/user-menu/preferences.spec.ts +++ b/cypress/e2e/tests/pages/user-menu/preferences.spec.ts @@ -16,8 +16,8 @@ const repoListPage = new RepositoriesPagePo('_', 'manager'); const repoList = repoListPage.list(); // const clusterManagerPage = new ClusterManagerListPagePo('_'); -const VIM = 'Vim'; -const NORMAL_HUMAN = 'Normal human'; +// const VIM = 'Vim'; +// const NORMAL_HUMAN = 'Normal human'; const RESOURCE_FOR_CREATE_YAML = 'resourcequota'; @@ -104,58 +104,58 @@ describe('User can update their preferences', () => { } }); - it.skip('[Vue3 Skip]: Can select login landing page', { tags: ['@userMenu', '@adminUser'] }, () => { - /* - Select each radio button and verify its highlighted - Validate http request's payload & response contain correct values per selection - Verify user is landing on correct page after login - Verify selection is preserved after logout/login - */ - - const landingPageOptions = [ - { - index: '0', value: '"home"', page: '/home' - }, - { - index: '1', value: '"last-visited"', page: 'c/_/manager/provisioning.cattle.io.cluster' - }, - { // This option only works when there is an existing local cluster - index: '2', value: '{\"name\":\"c-cluster\",\"params\":{\"cluster\":\"local\"}}', page: '/explore' - }, - ]; - - prefPage.goTo(); - prefPage.landingPageRadioBtn().checkVisible(); - landingPageOptions.forEach((key) => { - cy.intercept('PUT', 'v1/userpreferences/*').as(`prefUpdate${ key.value }`); - prefPage.landingPageRadioBtn().set(parseInt(key.index)); - cy.wait(`@prefUpdate${ key.value }`).then(({ request, response }) => { - expect(response?.statusCode).to.eq(200); - expect(request.body.data).to.have.property('after-login-route', key.value); - expect(response?.body.data).to.have.property('after-login-route', key.value); - }); - prefPage.landingPageRadioBtn().isChecked(parseInt(key.index)); - - // NOTE: Ideally we'd like to verify user is landing on correct page after login however there are issues with the login command - - // if key is 1, navigate to cluster manager page and then do validations, else just do validations - // if (parseInt(key.index) === 1) { - // cy.intercept('PUT', 'v1/userpreferences/*').as('userPref'); - // clusterManagerPage.goTo(); - // clusterManagerPage.list().checkVisible(); - // cy.wait('@userPref').its('response.statusCode').should('eq', 200); - // } - - // userMenu.toggle(); - // userMenu.isOpen(); - // userMenu.clickMenuItem('Log Out'); - // cy.login(); - // cy.visit(`${ Cypress.config().baseUrl }`); - // cy.url().should('include', value[1]); - // prefPage.goTo(); - // prefPage.landingPageRadioBtn().isChecked(key); - }); - }); + // it.skip('[Vue3 Skip]: Can select login landing page', { tags: ['@userMenu', '@adminUser'] }, () => { + // /* + // Select each radio button and verify its highlighted + // Validate http request's payload & response contain correct values per selection + // Verify user is landing on correct page after login + // Verify selection is preserved after logout/login + // */ + + // const landingPageOptions = [ + // { + // index: '0', value: '"home"', page: '/home' + // }, + // { + // index: '1', value: '"last-visited"', page: 'c/_/manager/provisioning.cattle.io.cluster' + // }, + // { // This option only works when there is an existing local cluster + // index: '2', value: '{\"name\":\"c-cluster\",\"params\":{\"cluster\":\"local\"}}', page: '/explore' + // }, + // ]; + + // prefPage.goTo(); + // prefPage.landingPageRadioBtn().checkVisible(); + // landingPageOptions.forEach((key) => { + // cy.intercept('PUT', 'v1/userpreferences/*').as(`prefUpdate${ key.value }`); + // prefPage.landingPageRadioBtn().set(parseInt(key.index)); + // cy.wait(`@prefUpdate${ key.value }`).then(({ request, response }) => { + // expect(response?.statusCode).to.eq(200); + // expect(request.body.data).to.have.property('after-login-route', key.value); + // expect(response?.body.data).to.have.property('after-login-route', key.value); + // }); + // prefPage.landingPageRadioBtn().isChecked(parseInt(key.index)); + + // // NOTE: Ideally we'd like to verify user is landing on correct page after login however there are issues with the login command + + // // if key is 1, navigate to cluster manager page and then do validations, else just do validations + // // if (parseInt(key.index) === 1) { + // // cy.intercept('PUT', 'v1/userpreferences/*').as('userPref'); + // // clusterManagerPage.goTo(); + // // clusterManagerPage.list().checkVisible(); + // // cy.wait('@userPref').its('response.statusCode').should('eq', 200); + // // } + + // // userMenu.toggle(); + // // userMenu.isOpen(); + // // userMenu.clickMenuItem('Log Out'); + // // cy.login(); + // // cy.visit(`${ Cypress.config().baseUrl }`); + // // cy.url().should('include', value[1]); + // // prefPage.goTo(); + // // prefPage.landingPageRadioBtn().isChecked(key); + // }); + // }); it('Can select date format', { tags: ['@userMenu', '@adminUser', '@standardUser'] }, () => { /* @@ -426,31 +426,31 @@ describe('User can update their preferences', () => { yamlEditor.keyboardMappingIndicator().checkNotExists(); }); - it.skip('[Vue3 Skip]: does show any indicator for non-default keyboard mapping', () => { - prefPage.goTo(); - prefPage.keymapButtons().checkVisible(); + // it.skip('[Vue3 Skip]: does show any indicator for non-default keyboard mapping', () => { + // prefPage.goTo(); + // prefPage.keymapButtons().checkVisible(); - prefPage.keymapButtons().set(VIM); - prefPage.keymapButtons().isSelected(VIM); + // prefPage.keymapButtons().set(VIM); + // prefPage.keymapButtons().isSelected(VIM); - const yamlEditor = new ResourceYamlEditorPagePo(RESOURCE_FOR_CREATE_YAML); + // const yamlEditor = new ResourceYamlEditorPagePo(RESOURCE_FOR_CREATE_YAML); - yamlEditor.goTo(); - yamlEditor.waitForPage(); + // yamlEditor.goTo(); + // yamlEditor.waitForPage(); - yamlEditor.keyboardMappingIndicator().checkExists(); - yamlEditor.keyboardMappingIndicator().checkVisible(); + // yamlEditor.keyboardMappingIndicator().checkExists(); + // yamlEditor.keyboardMappingIndicator().checkVisible(); - yamlEditor.keyboardMappingIndicator().showTooltip(); - yamlEditor.keyboardMappingIndicator().getTooltipContent().should('be.visible'); - yamlEditor.keyboardMappingIndicator().getTooltipContent().contains('Key mapping: Vim'); + // yamlEditor.keyboardMappingIndicator().showTooltip(); + // yamlEditor.keyboardMappingIndicator().getTooltipContent().should('be.visible'); + // yamlEditor.keyboardMappingIndicator().getTooltipContent().contains('Key mapping: Vim'); - // Reset keyboard mapping - prefPage.goTo(); - prefPage.keymapButtons().checkVisible(); + // // Reset keyboard mapping + // prefPage.goTo(); + // prefPage.keymapButtons().checkVisible(); - prefPage.keymapButtons().set(NORMAL_HUMAN); - }); + // prefPage.keymapButtons().set(NORMAL_HUMAN); + // }); }); it('Can select a Helm Charts option', { tags: ['@userMenu', '@adminUser', '@standardUser'] }, () => { diff --git a/cypress/e2e/tests/pages/users-and-auth/azuread.spec.ts b/cypress/e2e/tests/pages/users-and-auth/azuread.spec.ts index 2d1e23108ad..22f6bede189 100644 --- a/cypress/e2e/tests/pages/users-and-auth/azuread.spec.ts +++ b/cypress/e2e/tests/pages/users-and-auth/azuread.spec.ts @@ -9,10 +9,10 @@ const tenantId = '564b6f53-ebf4-43c3-8077-44c56a44990a'; const applicationId = '18cca356-170e-4bd9-a4a4-2e349855f96b'; const appSecret = 'test'; const groupMembershipFilter = 'test'; -const defaultEndpoint = 'https://login.microsoftonline.com/'; -const defaultAuthEndpoint = 'https://login.microsoftonline.com/564b6f53-ebf4-43c3-8077-44c56a44990a/oauth2/v2.0/authorize'; -const defaultTokenEndpoint = 'https://login.microsoftonline.com/564b6f53-ebf4-43c3-8077-44c56a44990a/oauth2/v2.0/token'; -const defaultGraphEndpoint = 'https://graph.microsoft.com'; +// const defaultEndpoint = 'https://login.microsoftonline.com/'; +// const defaultAuthEndpoint = 'https://login.microsoftonline.com/564b6f53-ebf4-43c3-8077-44c56a44990a/oauth2/v2.0/authorize'; +// const defaultTokenEndpoint = 'https://login.microsoftonline.com/564b6f53-ebf4-43c3-8077-44c56a44990a/oauth2/v2.0/token'; +// const defaultGraphEndpoint = 'https://graph.microsoft.com'; const endpoint = 'https://login.test.com/'; const authEndpoint = 'https://login.test.com/564b6f53-ebf4-43c3-8077-44c56a44990a/oauth2/v2.0/authorize'; const tokenEndpoint = 'https://login.test.com/564b6f53-ebf4-43c3-8077-44c56a44990a/oauth2/v2.0/token'; @@ -35,29 +35,29 @@ describe('AzureAD', { tags: ['@adminUser', '@usersAndAuths'] }, () => { azureadPo.mastheadTitle().should('include', `AzureAD`); }); - it.skip('[Vue3 Skip]: sends correct request to create standard Azure AD', () => { - cy.intercept('POST', 'v3/azureADConfigs/azuread?action=configureTest', (req) => { - expect(req.body.tenantId).to.equal(tenantId); - expect(req.body.applicationId).to.equal(applicationId); - expect(req.body.applicationSecret).to.equal(appSecret); - expect(req.body.endpoint).to.equal(defaultEndpoint); - expect(req.body.authEndpoint).to.equal(defaultAuthEndpoint); - expect(req.body.tokenEndpoint).to.equal(defaultTokenEndpoint); - expect(req.body.graphEndpoint).to.equal(defaultGraphEndpoint); + // it.skip('[Vue3 Skip]: sends correct request to create standard Azure AD', () => { + // cy.intercept('POST', 'v3/azureADConfigs/azuread?action=configureTest', (req) => { + // expect(req.body.tenantId).to.equal(tenantId); + // expect(req.body.applicationId).to.equal(applicationId); + // expect(req.body.applicationSecret).to.equal(appSecret); + // expect(req.body.endpoint).to.equal(defaultEndpoint); + // expect(req.body.authEndpoint).to.equal(defaultAuthEndpoint); + // expect(req.body.tokenEndpoint).to.equal(defaultTokenEndpoint); + // expect(req.body.graphEndpoint).to.equal(defaultGraphEndpoint); - req.reply(mockStatusCode, mockBody); - }).as('configureTest'); + // req.reply(mockStatusCode, mockBody); + // }).as('configureTest'); - // save should be disabled before values are filled - azureadPo.saveButton().expectToBeDisabled(); - azureadPo.enterTenantId(tenantId); - azureadPo.enterApplicationId(applicationId); - azureadPo.enterApplicationSecret(appSecret); - // save should be enabled after values are filled - azureadPo.saveButton().expectToBeEnabled(); - azureadPo.save(); - cy.wait('@configureTest'); - }); + // // save should be disabled before values are filled + // azureadPo.saveButton().expectToBeDisabled(); + // azureadPo.enterTenantId(tenantId); + // azureadPo.enterApplicationId(applicationId); + // azureadPo.enterApplicationSecret(appSecret); + // // save should be enabled after values are filled + // azureadPo.saveButton().expectToBeEnabled(); + // azureadPo.save(); + // cy.wait('@configureTest'); + // }); it('sends correct request to create custom Azure AD', () => { cy.intercept('POST', 'v3/azureADConfigs/azuread?action=configureTest', (req) => { 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 4344a64530d..e0e99abe59a 100644 --- a/cypress/e2e/tests/pages/users-and-auth/roles.spec.ts +++ b/cypress/e2e/tests/pages/users-and-auth/roles.spec.ts @@ -7,6 +7,7 @@ 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 { BLANK_CLUSTER } from '@shell/store/store-types.js'; +import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po'; const roles = new RolesPo(BLANK_CLUSTER); const usersPo = new UsersPo(BLANK_CLUSTER); @@ -266,7 +267,7 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { }); describe('List', { testIsolation: 'off', tags: ['@vai', '@adminUser'] }, () => { - const uniqueRoleName = 'aaa-e2e-test-name'; + let uniqueRoleName = SortableTablePo.firstByDefaultName('role'); const globalRolesIdsList = []; const rolesList = roles.list('GLOBAL'); const paginatedRoleTab = roles.paginatedTab('GLOBAL'); @@ -282,9 +283,9 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { let i = 0; while (i < 25) { - const globalRoleName = `e2e-${ Cypress._.uniqueId(Date.now().toString()) }`; + const globalRoleName = Cypress._.uniqueId(Date.now().toString()); - cy.createGlobalRole(globalRoleName, ['events.k8s.io'], [], ['events'], ['get'], false, false).then((resp: Cypress.Response) => { + cy.createGlobalRole(globalRoleName, ['events.k8s.io'], [], ['events'], ['get'], false, false, { createNameOptions: { prefixContext: true } }).then((resp: Cypress.Response) => { const roleId = resp.body.id; globalRolesIdsList.push(roleId); @@ -294,9 +295,11 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { } // create one more for sorting test - cy.createGlobalRole(uniqueRoleName, ['events.k8s.io'], [], ['events'], ['get'], false).then((resp: Cypress.Response) => { + cy.createGlobalRole(uniqueRoleName, ['events.k8s.io'], [], ['events'], ['get'], false, true, { createNameOptions: { prefixContext: true } }).then((resp: Cypress.Response) => { const roleId = resp.body.id; + uniqueRoleName = resp.body.name; + globalRolesIdsList.push(roleId); }); cy.tableRowsPerPageAndNamespaceFilter(10, 'local', 'none', '{\"local\":[]}'); @@ -333,6 +336,8 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { roles.waitForPage(); // check table is sorted by name in ASC order by default + rolesList.resourceTable().sortableTable().tableHeaderRow().self() + .scrollIntoView(); rolesList.resourceTable().sortableTable().tableHeaderRow() .checkSortOrder(3, 'down'); @@ -347,7 +352,7 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { .should('be.visible'); // navigate to last page - paginatedRoleTab.endButton().click(); + paginatedRoleTab.endButton().scrollIntoView().click(); // global role should NOT be visible on last page (sorted in ASC order) rolesList.resourceTable().sortableTable().rowElementWithName(uniqueRoleName) @@ -364,7 +369,7 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { .should('not.exist'); // navigate to last page - paginatedRoleTab.endButton().click(); + paginatedRoleTab.endButton().scrollIntoView().click(); // global role should be visible on last page (sorted in DESC order) rolesList.resourceTable().sortableTable().rowElementWithName(uniqueRoleName) @@ -417,7 +422,7 @@ describe('Roles Templates', { tags: ['@usersAndAuths', '@adminUser'] }, () => { paginatedRoleTab.leftButton().isDisabled(); // navigate to last page - end button - paginatedRoleTab.endButton().click(); + paginatedRoleTab.endButton().scrollIntoView().click(); // row count on last page let lastPageCount = count % 10; 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 e245df0d4ce..10961998e21 100644 --- a/cypress/e2e/tests/pages/users-and-auth/users.spec.ts +++ b/cypress/e2e/tests/pages/users-and-auth/users.spec.ts @@ -5,6 +5,7 @@ import * as jsyaml from 'js-yaml'; import * as path from 'path'; import { generateUsersDataSmall } from '@/cypress/e2e/blueprints/users/users-get'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; +import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po'; const usersPo = new UsersPo('_'); const userCreate = usersPo.createEdit(); @@ -265,7 +266,8 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { }); describe('List', { testIsolation: 'off', tags: ['@vai', '@adminUser'] }, () => { - const uniqueUserName = 'aaa-e2e-test-name'; + let uniqueUserName = SortableTablePo.firstByDefaultName('user'); + const userIdsList = []; let initialCount; @@ -280,7 +282,7 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { let i = 0; while (i < 25) { - const userName = `e2e-${ Cypress._.uniqueId(Date.now().toString()) }`; + const userName = Cypress._.uniqueId(Date.now().toString()); cy.createUser({ username: userName }).then((resp: Cypress.Response) => { const userId = resp.body.id; @@ -292,9 +294,10 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { } // create one more for sorting test - cy.createUser({ username: uniqueUserName }).then((resp: Cypress.Response) => { + cy.createUser({ username: uniqueUserName }, { createNameOptions: { prefixContext: true } }).then((resp: Cypress.Response) => { const userId = resp.body.id; + uniqueUserName = resp.body.username; userIdsList.push(userId); }); }); @@ -372,6 +375,7 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { // navigate to last page - end button usersPo.list().resourceTable().sortableTable().pagination() .endButton() + .scrollIntoView() .click(); // row count on last page @@ -439,12 +443,17 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { .checkSortOrder(3, 'down'); // user name should be visible on first page (sorted in ASC order) + usersPo.list().resourceTable().sortableTable().tableHeaderRow() + .self() + .scrollIntoView(); usersPo.list().resourceTable().sortableTable().rowElementWithName(uniqueUserName) + .scrollIntoView() .should('be.visible'); // navigate to last page usersPo.list().resourceTable().sortableTable().pagination() .endButton() + .scrollIntoView() .click(); // user name should NOT be visible on last page (sorted in ASC order) @@ -464,6 +473,7 @@ describe('Users', { tags: ['@usersAndAuths', '@adminUser'] }, () => { // navigate to last page usersPo.list().resourceTable().sortableTable().pagination() .endButton() + .scrollIntoView() .click(); // user name should be visible on last page (sorted in DESC order) diff --git a/cypress/e2e/tests/setup/rancher-setup.spec.ts b/cypress/e2e/tests/setup/rancher-setup.spec.ts index 3d4c4d7a897..8e584e895a7 100644 --- a/cypress/e2e/tests/setup/rancher-setup.spec.ts +++ b/cypress/e2e/tests/setup/rancher-setup.spec.ts @@ -107,7 +107,8 @@ describe('Rancher setup', { tags: ['@adminUserSetup', '@standardUserSetup', '@se clusterId: 'local', projectName: 'Default', role: 'project-member', - } - }); + }, + password: Cypress.env('password') + }, { createNameOptions: { onlyContext: true } }); }); }); diff --git a/cypress/globals.d.ts b/cypress/globals.d.ts index 85951bc2f50..8d5b99566de 100644 --- a/cypress/globals.d.ts +++ b/cypress/globals.d.ts @@ -16,7 +16,8 @@ export type CreateUserParams = { clusterId: string, projectName: string, role: string, - } + }, + password?: string, } export type CreateAmazonRke2ClusterParams = { @@ -54,6 +55,12 @@ export type CreateAmazonRke2ClusterWithoutMachineConfigParams = { namespace: string, } } + +export interface CreateResourceNameOptions { + onlyContext?: boolean + prefixContext?: boolean +} + declare global { // eslint-disable-next-line no-unused-vars namespace Cypress { @@ -64,9 +71,10 @@ declare global { login(username?: string, password?: string, cacheSession?: boolean): Chainable; logout(): Chainable; byLabel(label: string): Chainable; - createE2EResourceName(context: string): Chainable; + getRootE2EResourceName(): Chainable; + createE2EResourceName(context: string, options?: CreateResourceNameOptions): Chainable; - createUser(params: CreateUserParams): Chainable; + createUser(params: CreateUserParams, options?: { createNameOptions?: CreateResourceNameOptions }): Chainable; setGlobalRoleBinding(userId: string, role: string): Chainable; setClusterRoleBinding(clusterId: string, userPrincipalId: string, role: string): Chainable; setProjectRoleBinding(clusterId: string, userPrincipalId: string, projectName: string, role: string): Chainable; @@ -74,10 +82,10 @@ declare global { createProject(projName: string, clusterId: string, userId: string): Chainable; createNamespaceInProject(nsName: string, projId: string): Chainable; createNamespace(nsName: string): Chainable; - createPod(nsName: string, podName: string, image: string, failOnStatusCode?: boolean): Chainable; + createPod(nsName: string, podName: string, image: string, failOnStatusCode?: boolean, options?: { createNameOptions?: CreateResourceNameOptions }): Chainable; createToken(description: string, ttl: number, failOnStatusCode?: boolean, clusterId?: string): Chainable; - createGlobalRole(name: string, apiGroups: string[], resourceNames: string[], resources: string[], verbs: string[], newUserDefault: boolean, failOnStatusCode?: boolean): Chainable; - createFleetWorkspace(name: string, description?: string, failOnStatusCode?: boolean): Chainable; + createGlobalRole(name: string, apiGroups: string[], resourceNames: string[], resources: string[], verbs: string[], newUserDefault: boolean, failOnStatusCode?: boolean, options?: { createNameOptions?: CreateResourceNameOptions }): Chainable; + createFleetWorkspace(name: string, description?: string, failOnStatusCode?: boolean, options?: { createNameOptions?: CreateResourceNameOptions }): Chainable; createAwsCloudCredentials(nsName: string, cloudCredName: string, defaultRegion: string, accessKey: string, secretKey: string): Chainable; createAmazonMachineConfig(instanceType: string, region: string, vpcId: string, zone: string, type: string, clusterName: string, namespace: string): Chainable; createAmazonRke2Cluster(params: CreateAmazonRke2ClusterParams): Chainable; @@ -86,11 +94,12 @@ declare global { getRancherResource(prefix: 'v3' | 'v1', resourceType: string, resourceId?: string, expectedStatusCode?: number): Chainable; setRancherResource(prefix: 'v3' | 'v1', resourceType: string, resourceId: string, body: any): Chainable; createRancherResource(prefix: 'v3' | 'v1', resourceType: string, body: any): Chainable; - waitForRancherResources(prefix: 'v3' | 'v1', resourceType: string, expectedResourcesTotal: number): Chainable; + waitForRancherResource(prefix: 'v3' | 'v1', resourceType: string, resourceId: string, testFn: (resp: any) => boolean, retries?: number): Chainable; + waitForRancherResources(prefix: 'v3' | 'v1', resourceType: string, expectedResourcesTotal: number, greaterThan: boolean): Chainable; deleteRancherResource(prefix: 'v3' | 'v1' | 'k8s', resourceType: string, resourceId: string, failOnStatusCode?: boolean): Chainable; deleteNodeTemplate(nodeTemplateId: string, timeout?: number, failOnStatusCode?: boolean) - tableRowsPerPageAndNamespaceFilter(rows: number, cluster: string, groupBy: string, namespacefilter: string) + tableRowsPerPageAndNamespaceFilter(rows: number, cluster: string, groupBy: string, namespacefilter: string, interation?: number) /** * update namespace filter @@ -98,7 +107,7 @@ declare global { * @param groupBy to update list view to 'flat list', 'group by namespaces', or 'group by node' ('none', 'metadata.namespace', or 'role') * @param namespaceFilter to filter by 'only user namespaces', 'all namespace', etc. ('{"local":["all://user"]}', '{\"local\":[]}', etc.) */ - updateNamespaceFilter(clusterName: string, groupBy:string, namespaceFilter: string): Chainable; + updateNamespaceFilter(clusterName: string, groupBy:string, namespaceFilter: string, iteration?: number): Chainable; /** * Wrapper for cy.get() to simply define the data-testid value that allows you to pass a matcher to find the element. diff --git a/cypress/support/commands/commands.ts b/cypress/support/commands/commands.ts index 75c014a57df..9d0ecee30bc 100644 --- a/cypress/support/commands/commands.ts +++ b/cypress/support/commands/commands.ts @@ -61,13 +61,24 @@ Cypress.Commands.add('iFrame', () => { .then((body) => cy.wrap(body)); }); +const runTimestamp = +new Date(); + +/** + * Get root resource name + */ +Cypress.Commands.add('getRootE2EResourceName', () => { + return cy.wrap(`e2e-test-${ runTimestamp }`); +}); + /** * Create resource name */ -const runTimestamp = +new Date(); +Cypress.Commands.add('createE2EResourceName', (context, options = { prefixContext: false, onlyContext: false }) => { + if (options?.onlyContext) { + return cy.wrap(context); + } -Cypress.Commands.add('createE2EResourceName', (context) => { - return cy.wrap(`e2e-test-${ runTimestamp }-${ context }`); + return cy.getRootE2EResourceName().then((root) => options?.prefixContext ? `${ context }-${ root }` : `${ root }-${ context }`); }); // See: https://stackoverflow.com/questions/74785083/how-can-i-get-a-custom-css-variable-from-any-element-cypress diff --git a/cypress/support/commands/rancher-api-commands.ts b/cypress/support/commands/rancher-api-commands.ts index 26ffc50f7fd..70a09fdb084 100644 --- a/cypress/support/commands/rancher-api-commands.ts +++ b/cypress/support/commands/rancher-api-commands.ts @@ -64,27 +64,30 @@ Cypress.Commands.add('login', ( /** * Create user via api request */ -Cypress.Commands.add('createUser', (params: CreateUserParams) => { +Cypress.Commands.add('createUser', (params: CreateUserParams, options = { }) => { const { - username, globalRole, clusterRole, projectRole + username, globalRole, clusterRole, projectRole, password } = params; - return cy.request({ - method: 'POST', - url: `${ Cypress.env('api') }/v3/users`, - failOnStatusCode: false, - headers: { - 'x-api-csrf': token.value, - Accept: 'application/json' - }, - body: { - type: 'user', - enabled: true, - mustChangePassword: false, - username, - password: Cypress.env('password') - } - }) + return cy.createE2EResourceName(username, options?.createNameOptions) + .then((e2eName) => { + return cy.request({ + method: 'POST', + url: `${ Cypress.env('api') }/v3/users`, + failOnStatusCode: false, + headers: { + 'x-api-csrf': token.value, + Accept: 'application/json' + }, + body: { + type: 'user', + enabled: true, + mustChangePassword: false, + username: e2eName, + password: password || Cypress.env('password') + } + }); + }) .then((resp) => { if (resp.status === 422 && resp.body.message === 'Username is already in use.') { cy.log('User already exists. Skipping user creation'); @@ -110,6 +113,10 @@ Cypress.Commands.add('createUser', (params: CreateUserParams) => { return cy.setProjectRoleBinding(clusterId, userPrincipalId, projectName, role); } + }) + .then(() => { + // return response of original user + return resp; }); } } @@ -295,36 +302,41 @@ Cypress.Commands.add('createNamespace', (nsName) => { /** * Create pod */ -Cypress.Commands.add('createPod', (nsName, podName, image, failOnStatusCode = true) => { - return cy.request({ - method: 'POST', - url: `${ Cypress.env('api') }/v1/pods`, - headers: { - 'x-api-csrf': token.value, - Accept: 'application/json' - }, - failOnStatusCode, - body: { - type: 'pod', - metadata: { - namespace: nsName, labels: { 'workload.user.cattle.io/workloadselector': `pod-${ nsName }-pod-${ podName }` }, name: `pod-${ podName }`, annotations: {} - }, - spec: { - selector: { matchLabels: { 'workload.user.cattle.io/workloadselector': `pod-${ nsName }-pod-${ podName }` } }, - containers: [{ - imagePullPolicy: 'Always', name: 'container-0', _init: false, volumeMounts: [], env: [], envFrom: [], image: `${ image }`, __active: true - }], - initContainers: [], - imagePullSecrets: [], - volumes: [], - affinity: {} - } - } - }) +Cypress.Commands.add('createPod', (nsName, podName, image, failOnStatusCode = true, options = { }) => { + return cy.createE2EResourceName(podName, options?.createNameOptions) + .then((e2eName) => { + return cy.request({ + method: 'POST', + url: `${ Cypress.env('api') }/v1/pods`, + headers: { + 'x-api-csrf': token.value, + Accept: 'application/json' + }, + failOnStatusCode, + body: { + type: 'pod', + metadata: { + namespace: nsName, labels: { 'workload.user.cattle.io/workloadselector': `${ e2eName }` }, name: `${ e2eName }`, annotations: {} + }, + spec: { + selector: { matchLabels: { 'workload.user.cattle.io/workloadselector': `${ e2eName }` } }, + containers: [{ + imagePullPolicy: 'Always', name: 'container-0', _init: false, volumeMounts: [], env: [], envFrom: [], image: `${ image }`, __active: true + }], + initContainers: [], + imagePullSecrets: [], + volumes: [], + affinity: {} + } + } + }); + }) .then((resp) => { if (failOnStatusCode) { expect(resp.status).to.eq(201); } + + return resp; }); }); @@ -446,6 +458,8 @@ Cypress.Commands.add('setRancherResource', (prefix, resourceType, resourceId, bo }) .then((resp) => { expect(resp.status).to.eq(200); + + return resp; }); }); @@ -488,7 +502,39 @@ Cypress.Commands.add('createRancherResource', (prefix, resourceType, body) => { }); }); -Cypress.Commands.add('waitForRancherResources', (prefix, resourceType, expectedResourcesTotal) => { +Cypress.Commands.add('waitForRancherResource', (prefix, resourceType, resourceId, testFn, retries = 20) => { + const url = `${ Cypress.env('api') }/${ prefix }/${ resourceType }/${ resourceId }`; + + const retry = () => { + cy.request({ + method: 'GET', + url, + headers: { + 'x-api-csrf': token.value, + Accept: 'application/json' + }, + }) + .then((resp) => { + if (!testFn(resp)) { + retries = retries - 1; + if (retries === 0) { + cy.log(`waitForRancherResource: Failed to wait for updated state for ${ url }`); + + return false; + } + cy.wait(1500); // eslint-disable-line cypress/no-unnecessary-waiting + + return retry(); + } + + return true; + }); + }; + + return retry(); +}); + +Cypress.Commands.add('waitForRancherResources', (prefix, resourceType, expectedResourcesTotal, greaterThan) => { const url = `${ Cypress.env('api') }/${ prefix }/${ resourceType }`; let retries = 20; @@ -502,14 +548,19 @@ Cypress.Commands.add('waitForRancherResources', (prefix, resourceType, expectedR }, }) .then((resp) => { - if (resp.body.count === expectedResourcesTotal) return resp; - else { - retries = retries - 1; - if (retries === 0) return resp; - // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(3000); - retry(); + if (greaterThan) { + if (resp.body.count > expectedResourcesTotal) { + return resp; + } + } else if (resp.body.count === expectedResourcesTotal) { + return resp; } + + retries = retries - 1; + if (retries === 0) return resp; + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(1000); + retry(); }); }; @@ -807,14 +858,66 @@ Cypress.Commands.add('createAmazonMachineConfig', (instanceType, region, vpcId, }); // update resource list view preference -Cypress.Commands.add('updateNamespaceFilter', (clusterName: string, groupBy:string, namespaceFilter: string) => { +Cypress.Commands.add('updateNamespaceFilter', (clusterName: string, groupBy:string, namespaceFilter: string, iteration = 0) => { return cy.getRancherResource('v3', 'users?me=true').then((resp: Cypress.Response) => { const userId = resp.body.data[0].id.trim(); - cy.setRancherResource('v1', 'userpreferences', userId, groupByPayload(userId, clusterName, groupBy, namespaceFilter)); + const payload = groupByPayload(userId, clusterName, groupBy, namespaceFilter); + + cy.log(`updateNamespaceFilter: /v1/userpreferences/${ userId }. Payload: ${ JSON.stringify(payload) }`); + + cy.setRancherResource('v1', 'userpreferences', userId, payload).then(() => { + return cy.waitForRancherResource('v1', 'userpreferences', userId, (resp: any) => compare(resp?.body, payload), 5) + .then((res) => { + if (res) { + cy.log(`updateNamespaceFilter: Success!`); + } else { + if (iteration < 3) { + cy.log(`updateNamespaceFilter: Failed! Going to retry...`); + + return cy.updateNamespaceFilter(clusterName, groupBy, namespaceFilter, iteration + 1); + } + + cy.log(`updateNamespaceFilter: Failed! Giving up...`); + + return Promise.reject(new Error('updateNamespaceFilter failed')); + } + }); + }); }); }); +const compare = (core, subset) => { + const entries = Object.entries(subset); + let result = true; + + for (let i = 0; i < entries.length; i++) { + const [key, subsetValue] = entries[i]; + const coreValue = core[key]; + + if (typeof subsetValue === 'object') { + if (!compare(coreValue, subsetValue)) { + cy.log(`Compare Failed: Key: "${ key }"`); + + result = false; + break; + } + } else if (subsetValue !== coreValue) { + cy.log(`Compare Failed: Key: "${ key }". Comparison "${ subsetValue }" !== "` + `${ coreValue }"`); + + result = false; + break; + } + } + + if (!result) { + cy.log(`Compare Failed: Result: Actual State ${ JSON.stringify(core) }`); + cy.log(`Compare Failed: Result: Expected Sub-state ${ JSON.stringify(subset) }`); + } + + return result; +}; + /** * Create token (API Keys) */ @@ -839,63 +942,75 @@ Cypress.Commands.add('createToken', (description: string, ttl = 3600000, failOnS if (failOnStatusCode) { expect(resp.status).to.eq(201); } + + return resp; }); }); /** * Create global role */ -Cypress.Commands.add('createGlobalRole', (name, apiGroups: string[], resourceNames: string[], resources: string[], verbs: string[], newUserDefault = false, failOnStatusCode = true) => { - return cy.request({ - method: 'POST', - url: `${ Cypress.env('api') }/v3/globalroles`, - headers: { - 'x-api-csrf': token.value, - Accept: 'application/json' - }, - failOnStatusCode, - body: { - type: 'globalRole', - name, - rules: [{ - apiGroups, - resourceNames, - resources, - verbs - }], - newUserDefault - } - }) +Cypress.Commands.add('createGlobalRole', (name, apiGroups: string[], resourceNames: string[], resources: string[], verbs: string[], newUserDefault = false, failOnStatusCode = true, options = { }) => { + return cy.createE2EResourceName(name, options?.createNameOptions) + .then((e2eName) => { + return cy.request({ + method: 'POST', + url: `${ Cypress.env('api') }/v3/globalroles`, + headers: { + 'x-api-csrf': token.value, + Accept: 'application/json' + }, + failOnStatusCode, + body: { + type: 'globalRole', + name: e2eName, + rules: [{ + apiGroups, + resourceNames, + resources, + verbs + }], + newUserDefault + } + }); + }) .then((resp) => { if (failOnStatusCode) { expect(resp.status).to.eq(201); } + + return resp; }); }); /** * Create fleet workspace */ -Cypress.Commands.add('createFleetWorkspace', (name: string, description?: string, failOnStatusCode = true) => { - return cy.request({ - method: 'POST', - url: `${ Cypress.env('api') }/v3/fleetworkspaces`, - headers: { - 'x-api-csrf': token.value, - Accept: 'application/json' - }, - failOnStatusCode, - body: { - type: 'fleetworkspace', - name, - annotations: { 'field.cattle.io/description': description }, - labels: {} - } - }) +Cypress.Commands.add('createFleetWorkspace', (name: string, description?: string, failOnStatusCode = true, options = { }) => { + return cy.createE2EResourceName(name, options?.createNameOptions) + .then((e2eName) => { + return cy.request({ + method: 'POST', + url: `${ Cypress.env('api') }/v3/fleetworkspaces`, + headers: { + 'x-api-csrf': token.value, + Accept: 'application/json' + }, + failOnStatusCode, + body: { + type: 'fleetworkspace', + name: e2eName, + annotations: { 'field.cattle.io/description': description }, + labels: {} + } + }); + }) .then((resp) => { if (failOnStatusCode) { expect(resp.status).to.eq(201); } + + return resp; }); }); @@ -909,11 +1024,10 @@ Cypress.Commands.add('fetchRevision', () => { }); }); -Cypress.Commands.add('tableRowsPerPageAndNamespaceFilter', (rows: number, clusterName: string, groupBy: string, namespaceFilter: string) => { +Cypress.Commands.add('tableRowsPerPageAndNamespaceFilter', (rows: number, clusterName: string, groupBy: string, namespaceFilter: string, iteration = 0) => { return cy.getRancherResource('v3', 'users?me=true').then((resp: Cypress.Response) => { const userId = resp.body.data[0].id.trim(); - - cy.setRancherResource('v1', `userpreferences`, userId, { + const payload = { id: `${ userId }`, type: 'userpreference', data: { @@ -922,6 +1036,27 @@ Cypress.Commands.add('tableRowsPerPageAndNamespaceFilter', (rows: number, cluste 'group-by': groupBy, 'ns-by-cluster': namespaceFilter } + }; + + cy.log(`tableRowsPerPageAndNamespaceFilter: /v1/userpreferences/${ userId }. Payload: ${ JSON.stringify(payload) }`); + + cy.setRancherResource('v1', 'userpreferences', userId, payload).then(() => { + return cy.waitForRancherResource('v1', 'userpreferences', userId, (resp: any) => compare(resp?.body, payload)) + .then((res) => { + if (res) { + cy.log(`tableRowsPerPageAndNamespaceFilter: Success!`); + } else { + if (iteration < 3) { + cy.log(`tableRowsPerPageAndNamespaceFilter: Failed! Going to retry...`); + + return cy.tableRowsPerPageAndNamespaceFilter(rows, clusterName, groupBy, namespaceFilter, iteration + 1); + } + + cy.log(`tableRowsPerPageAndNamespaceFilter: Failed! Giving up...`); + + return Promise.reject(new Error('tableRowsPerPageAndNamespaceFilter failed')); + } + }); }); }); }); diff --git a/cypress/support/utils/settings-utils.ts b/cypress/support/utils/settings-utils.ts index bc7e519ca93..8d0faaa2136 100644 --- a/cypress/support/utils/settings-utils.ts +++ b/cypress/support/utils/settings-utils.ts @@ -1,8 +1,6 @@ /** - * There's a small amount of mgmt settings that are public and will be returned when the user in unauthed. This represents that number. - * - * It doesn't need to be exact but should always be equal or more than the actual amount - * (tests will check that the pre-authed setting count is less than this, and the post-authed count is greater than) + * There's a small amount of mgmt settings that are public and will be returned when the user in unauthed. When logged in there will be more. * + * This number is used to check that after log in we get all settings by checking that unauthed setting count is lower and authed settings count is at or greater than */ export const PARTIAL_SETTING_THRESHOLD = 13;