mirror of https://github.com/rancher/dashboard.git
Cluster management (#10161)
* actions on cluster tests * initial iteration for cluster drivers tests * node drivers tests * rke templates tests * cloud credentials tests and initial node templates tests * completed node templates tests * pod security admissions and policy templates * MachineDeployments MachineSets and Machines tests * repositories tests * filter out tests with @jenkins tag
This commit is contained in:
parent
af5731a0b8
commit
b189f8efb0
|
|
@ -74,7 +74,7 @@ jobs:
|
|||
run: |
|
||||
yarn e2e:prod
|
||||
env:
|
||||
GREP_TAGS: ${{ matrix.role.tag }}Setup+${{ matrix.features[0] }} ${{ matrix.role.tag }}Setup+${{ matrix.features[1] || matrix.features[0] }}
|
||||
GREP_TAGS: ${{ matrix.role.tag }}Setup+${{ matrix.features[0] }} --@jenkins ${{ matrix.role.tag }}Setup+${{ matrix.features[1] || matrix.features[0] }} --@jenkins
|
||||
TEST_USERNAME: admin
|
||||
TEST_ONLY: setup
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ jobs:
|
|||
[ "$BUILD_DASHBOARD" != "false" ] || exit 0
|
||||
env:
|
||||
TEST_SKIP: setup
|
||||
GREP_TAGS: ${{ matrix.role.tag }}+${{ matrix.features[0] }} ${{ matrix.role.tag }}+${{ matrix.features[1] || matrix.features[0] }}
|
||||
GREP_TAGS: ${{ matrix.role.tag }}+${{ matrix.features[0] }} --@jenkins ${{ matrix.role.tag }}+${{ matrix.features[1] || matrix.features[0] }} --@jenkins
|
||||
TEST_USERNAME: ${{ matrix.role.username }}
|
||||
|
||||
- name: Upload screenshots
|
||||
|
|
|
|||
|
|
@ -80,7 +80,9 @@ export default defineConfig({
|
|||
username,
|
||||
password: process.env.CATTLE_BOOTSTRAP_PASSWORD || process.env.TEST_PASSWORD,
|
||||
bootstrapPassword: process.env.CATTLE_BOOTSTRAP_PASSWORD,
|
||||
grepTags: process.env.GREP_TAGS
|
||||
grepTags: process.env.GREP_TAGS,
|
||||
awsAccessKey: process.env.AWS_ACCESS_KEY_ID,
|
||||
awsSecretKey: process.env.AWS_SECRET_ACCESS_KEY
|
||||
},
|
||||
e2e: {
|
||||
fixturesFolder: 'cypress/e2e/blueprints',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
apiVersion: cluster.x-k8s.io/v1beta1
|
||||
kind: MachineDeployment
|
||||
metadata:
|
||||
creationTimestamp: '2023-12-07T18:14:50Z'
|
||||
generation: 1
|
||||
labels:
|
||||
cluster.x-k8s.io/cluster-name: local
|
||||
managedFields:
|
||||
- apiVersion: cluster.x-k8s.io/v1beta1
|
||||
fieldsType: FieldsV1
|
||||
fieldsV1:
|
||||
f:spec:
|
||||
.: {}
|
||||
f:clusterName: {}
|
||||
f:selector: {}
|
||||
f:template:
|
||||
.: {}
|
||||
f:metadata: {}
|
||||
f:spec:
|
||||
.: {}
|
||||
f:clusterName: {}
|
||||
manager: rancher
|
||||
operation: Update
|
||||
time: '2023-12-07T18:14:50Z'
|
||||
name: e2e-machinedeployment-name-1701972886077
|
||||
namespace: default
|
||||
resourceVersion: '22851'
|
||||
uid: f5bf052d-7bbf-483a-a20a-b2f6e48d1e15
|
||||
spec:
|
||||
clusterName: local
|
||||
minReadySeconds: 0
|
||||
progressDeadlineSeconds: 600
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
cluster.x-k8s.io/cluster-name: local
|
||||
cluster.x-k8s.io/deployment-name: e2e-machinedeployment-name-1701972886077
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
type: RollingUpdate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
cluster.x-k8s.io/cluster-name: local
|
||||
cluster.x-k8s.io/deployment-name: e2e-machinedeployment-name-1701972886077
|
||||
spec:
|
||||
bootstrap: {}
|
||||
clusterName: local
|
||||
infrastructureRef: {}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
apiVersion: cluster.x-k8s.io/v1beta1
|
||||
kind: MachineDeployment
|
||||
metadata:
|
||||
name: e2etest
|
||||
namespace: default
|
||||
# annotations: key: string
|
||||
# labels: key: string
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:# key: string
|
||||
# matchExpressions:
|
||||
# - key: string
|
||||
# operator: string
|
||||
# values:
|
||||
# - string
|
||||
template:
|
||||
metadata:
|
||||
labels:# key: string
|
||||
# annotations: key: string
|
||||
# generateName: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# ownerReferences:
|
||||
# - apiVersion: string
|
||||
# blockOwnerDeletion: boolean
|
||||
# controller: boolean
|
||||
# kind: string
|
||||
# name: string
|
||||
# uid: string
|
||||
spec:
|
||||
# bootstrap:
|
||||
# configRef:
|
||||
# apiVersion: string
|
||||
# fieldPath: string
|
||||
# kind: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# resourceVersion: string
|
||||
# uid: string
|
||||
# data: string
|
||||
# dataSecretName: string
|
||||
clusterName: local
|
||||
# failureDomain: string
|
||||
# infrastructureRef:
|
||||
# apiVersion: string
|
||||
# fieldPath: string
|
||||
# kind: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# resourceVersion: string
|
||||
# uid: string
|
||||
# nodeDrainTimeout: string
|
||||
# providerID: string
|
||||
# version: string
|
||||
clusterName: local
|
||||
# minReadySeconds: int
|
||||
# paused: boolean
|
||||
# progressDeadlineSeconds: int
|
||||
# replicas: int
|
||||
# revisionHistoryLimit: int
|
||||
# strategy:
|
||||
# type: string
|
||||
# rollingUpdate:
|
||||
# maxSurge: json
|
||||
# maxUnavailable: json
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
apiVersion: cluster.x-k8s.io/v1beta1
|
||||
kind: MachineSet
|
||||
metadata:
|
||||
creationTimestamp: '2023-12-06T23:41:44Z'
|
||||
generation: 3
|
||||
labels:
|
||||
cluster.x-k8s.io/cluster-name: local
|
||||
managedFields:
|
||||
- apiVersion: cluster.x-k8s.io/v1beta1
|
||||
fieldsType: FieldsV1
|
||||
fieldsV1:
|
||||
f:spec:
|
||||
.: {}
|
||||
f:clusterName: {}
|
||||
f:replicas: {}
|
||||
f:selector: {}
|
||||
f:template:
|
||||
.: {}
|
||||
f:metadata: {}
|
||||
f:spec:
|
||||
.: {}
|
||||
f:clusterName: {}
|
||||
manager: rancher
|
||||
operation: Update
|
||||
time: '2023-12-06T23:46:28Z'
|
||||
name: e2e-machine-name-1701906098950
|
||||
namespace: default
|
||||
resourceVersion: '647485'
|
||||
uid: 98380f64-0706-4522-8dc2-b91a7f012dcf
|
||||
spec:
|
||||
clusterName: local
|
||||
deletePolicy: Random
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
cluster.x-k8s.io/set-name: e2e-machine-name-1701906098950
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
cluster.x-k8s.io/set-name: e2e-machine-name-1701906098950
|
||||
spec:
|
||||
bootstrap: {}
|
||||
clusterName: local
|
||||
infrastructureRef: {}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
apiVersion: cluster.x-k8s.io/v1beta1
|
||||
kind: MachineSet
|
||||
metadata:
|
||||
name: e2etest
|
||||
namespace: default
|
||||
# annotations: key: string
|
||||
# labels: key: string
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:# key: string
|
||||
# matchExpressions:
|
||||
# - key: string
|
||||
# operator: string
|
||||
# values:
|
||||
# - string
|
||||
template:
|
||||
metadata:
|
||||
labels:# key: string
|
||||
# annotations: key: string
|
||||
# generateName: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# ownerReferences:
|
||||
# - apiVersion: string
|
||||
# blockOwnerDeletion: boolean
|
||||
# controller: boolean
|
||||
# kind: string
|
||||
# name: string
|
||||
# uid: string
|
||||
spec:
|
||||
bootstrap:
|
||||
# configRef:
|
||||
# apiVersion: string
|
||||
# fieldPath: string
|
||||
# kind: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# resourceVersion: string
|
||||
# uid: string
|
||||
# data: string
|
||||
dataSecretName: secretName
|
||||
clusterName: local
|
||||
# failureDomain: string
|
||||
# infrastructureRef:
|
||||
# apiVersion: string
|
||||
# fieldPath: string
|
||||
# kind: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# resourceVersion: string
|
||||
# uid: string
|
||||
# nodeDrainTimeout: string
|
||||
# providerID: string
|
||||
# version: string
|
||||
clusterName: local
|
||||
# deletePolicy: string
|
||||
# minReadySeconds: int
|
||||
# replicas: int
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
apiVersion: cluster.x-k8s.io/v1beta1
|
||||
kind: Machine
|
||||
metadata:
|
||||
creationTimestamp: '2023-12-06T22:21:54Z'
|
||||
generation: 1
|
||||
labels:
|
||||
cluster.x-k8s.io/cluster-name: local
|
||||
managedFields:
|
||||
- apiVersion: cluster.x-k8s.io/v1beta1
|
||||
fieldsType: FieldsV1
|
||||
fieldsV1:
|
||||
f:spec:
|
||||
.: {}
|
||||
f:bootstrap:
|
||||
.: {}
|
||||
f:dataSecretName: {}
|
||||
f:clusterName: {}
|
||||
f:infrastructureRef: {}
|
||||
manager: rancher
|
||||
operation: Update
|
||||
time: '2023-12-06T22:21:54Z'
|
||||
name: e2e-machine-name-1701901308645
|
||||
namespace: default
|
||||
resourceVersion: '609444'
|
||||
uid: 7d61939a-b44a-4113-a7d1-9db2eda08811
|
||||
spec:
|
||||
bootstrap:
|
||||
dataSecretName: secretname
|
||||
clusterName: local
|
||||
infrastructureRef:
|
||||
namespace: default
|
||||
resourceVersion: abc123
|
||||
nodeDeletionTimeout: 10s
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
apiVersion: cluster.x-k8s.io/v1beta1
|
||||
kind: Machine
|
||||
metadata:
|
||||
name: string
|
||||
namespace: default
|
||||
# annotations: key: string
|
||||
# labels: key: string
|
||||
spec:
|
||||
bootstrap:
|
||||
# configRef:
|
||||
# apiVersion: string
|
||||
# fieldPath: string
|
||||
# kind: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# resourceVersion: string
|
||||
# uid: string
|
||||
# data: string
|
||||
dataSecretName: secretname
|
||||
clusterName: local
|
||||
# failureDomain: string
|
||||
# infrastructureRef:
|
||||
# apiVersion: string
|
||||
# fieldPath: string
|
||||
# kind: string
|
||||
# name: string
|
||||
# namespace: string
|
||||
# resourceVersion: string
|
||||
# uid: string
|
||||
# nodeDrainTimeout: string
|
||||
# providerID: string
|
||||
# version: string
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
export const createPayloadData = {
|
||||
id: 'e2e-pod-security-admission-1705617529465',
|
||||
type: 'management.cattle.io.podsecurityadmissionconfigurationtemplate',
|
||||
apiVersion: 'management.cattle.io/v3',
|
||||
configuration: {
|
||||
defaults: {
|
||||
audit: 'baseline', 'audit-version': 'latest', enforce: 'privileged', 'enforce-version': 'latest', warn: 'restricted', 'warn-version': 'latest'
|
||||
},
|
||||
exemptions: {
|
||||
usernames: ['admin', 'user'], runtimeClasses: ['myclass1', 'myclass2'], namespaces: ['ingress-nginx', 'kube-system']
|
||||
}
|
||||
},
|
||||
kind: 'PodSecurityAdmissionConfigurationTemplate',
|
||||
metadata: {
|
||||
fields: ['e2e-pod-security-admission-1705617529465', '18s'], name: 'e2e-pod-security-admission-1705617529465', resourceVersion: '831667'
|
||||
},
|
||||
description: 'e2e-pod-security-admission-1705617529465-description'
|
||||
};
|
||||
|
||||
export const updatePayloadData = {
|
||||
id: 'e2e-pod-security-admission-1705628550961',
|
||||
type: 'management.cattle.io.podsecurityadmissionconfigurationtemplate',
|
||||
apiVersion: 'management.cattle.io/v3',
|
||||
configuration: {
|
||||
defaults: {
|
||||
audit: 'baseline', 'audit-version': 'v1.25', enforce: 'privileged', 'enforce-version': 'v1.25', warn: 'restricted', 'warn-version': 'v1.25'
|
||||
},
|
||||
exemptions: {
|
||||
usernames: ['admin1', 'user1'], runtimeClasses: ['myclass3', 'myclass4'], namespaces: ['cattle-system', 'cattle-epinio-system']
|
||||
}
|
||||
},
|
||||
kind: 'PodSecurityAdmissionConfigurationTemplate',
|
||||
metadata: {
|
||||
fields: ['e2e-pod-security-admission-1705628550961', '7s'], name: 'e2e-pod-security-admission-1705628550961', resourceVersion: '938739'
|
||||
},
|
||||
description: 'e2e-pod-security-admission-1705628550961-description-edit'
|
||||
};
|
||||
|
|
@ -8,4 +8,8 @@ export default class ResourceListMastheadPo extends ComponentPo {
|
|||
title() {
|
||||
return this.self().get('.title h1').invoke('text');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.self().find('[data-testid="masthead-create-yaml"]').click();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import ComponentPo from '@/cypress/e2e/po/components/component.po';
|
||||
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
|
||||
|
||||
export default class CruResourcePo extends ComponentPo {
|
||||
selectSubType(groupIndex: number, itemIndex: number) {
|
||||
|
|
@ -6,4 +7,20 @@ export default class CruResourcePo extends ComponentPo {
|
|||
.eq(groupIndex).find('.item')
|
||||
.eq(itemIndex);
|
||||
}
|
||||
|
||||
selectSubTypeByIndex(index: number) {
|
||||
return this.self().find('.subtypes-container > div')
|
||||
.eq(index);
|
||||
}
|
||||
|
||||
saveOrCreate(): AsyncButtonPo {
|
||||
return new AsyncButtonPo('[data-testid="form-save"]', this.self());
|
||||
}
|
||||
|
||||
saveAndWaitForRequests(method: string, url: string) {
|
||||
cy.intercept(method, url).as('request');
|
||||
this.saveOrCreate().click();
|
||||
|
||||
return cy.wait('@request', { timeout: 10000 });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po';
|
||||
|
||||
export default class EmberAccordionPo extends EmberComponentPo {
|
||||
private headerSelector: string;
|
||||
private contentSelector: string;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po';
|
||||
|
||||
export default class EmberCheckboxInputPo extends EmberComponentPo {
|
||||
/**
|
||||
* Click on the checkbox input button
|
||||
* @returns
|
||||
*/
|
||||
set(): Cypress.Chainable {
|
||||
return this.input().click({ force: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the checkbox input button from a given container
|
||||
* @returns
|
||||
*/
|
||||
private input(): Cypress.Chainable {
|
||||
return this.self().find('.ember-checkbox');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import EmberAccordionPo from '@/cypress/e2e/po/components/ember/ember-accordion.po';
|
||||
import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po';
|
||||
import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po';
|
||||
|
||||
export default class EmberAddPodSecurityTemplatePo extends EmberComponentPo {
|
||||
templateName(): EmberInputPo {
|
||||
return new EmberInputPo('[data-testid="form-name-description__name"]');
|
||||
}
|
||||
|
||||
templateDescription(): EmberInputPo {
|
||||
return new EmberInputPo('.ember-text-area');
|
||||
}
|
||||
|
||||
addDescription() {
|
||||
this.self().find('div > a.btn', 'Add a Description').click();
|
||||
}
|
||||
|
||||
accordion() {
|
||||
return new EmberAccordionPo('.accordion-wrapper');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.self().find('button.btn').contains('Create').click();
|
||||
}
|
||||
|
||||
save() {
|
||||
return this.self().find('button.btn').contains('Save').click();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po';
|
||||
import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po';
|
||||
|
||||
export default class EmberFormRkeTemplatesPo extends EmberComponentPo {
|
||||
templateDetails(index): EmberInputPo {
|
||||
return new EmberInputPo(`.horizontal-form .row:nth-of-type(1) input:nth-child(${ index })`);
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.self().contains('[data-testid="save-cancel-rke1"] button', 'Create').click();
|
||||
}
|
||||
|
||||
save() {
|
||||
return this.self().contains('[data-testid="save-cancel-rke1"] button', 'Save').click();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po';
|
||||
import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po';
|
||||
|
||||
export default class EmberModalClusterDriverPo extends EmberModalPo {
|
||||
formInput(index: number) {
|
||||
return new EmberInputPo(`.modal-open .inline-form:nth-of-type(${ index }) input`);
|
||||
}
|
||||
|
||||
addDomainButton() {
|
||||
this.self().find('button').contains('Add Domain').click();
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.self().find('button').contains('Create').click();
|
||||
}
|
||||
|
||||
save() {
|
||||
return this.self().find('button').contains('Save').click();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po';
|
||||
import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po';
|
||||
|
||||
export default class EmberModalNodeDriverPo extends EmberModalPo {
|
||||
formInput(index: number) {
|
||||
return new EmberInputPo(`.modal-open .inline-form:nth-of-type(${ index }) input`);
|
||||
}
|
||||
|
||||
addDomainButton() {
|
||||
this.self().find('button').contains('Add Domain').click();
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.self().find('button').contains('Create').click();
|
||||
}
|
||||
|
||||
save() {
|
||||
return this.self().find('button').contains('Save').click();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import EmberAccordionPo from '@/cypress/e2e/po/components/ember/ember-accordion.po';
|
||||
import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po';
|
||||
import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po';
|
||||
|
||||
export default class EmberModalAddNodeTemplatePo extends EmberModalPo {
|
||||
serviceProviderOptions(label: string) {
|
||||
return this.self().contains('.nav-box-item', new RegExp(` ${ label } `));
|
||||
}
|
||||
|
||||
nextButton(label: string) {
|
||||
return this.self().contains('.btn', label, { timeout: 10000 });
|
||||
}
|
||||
|
||||
accordion() {
|
||||
return new EmberAccordionPo('');
|
||||
}
|
||||
|
||||
checkOption(value: string) {
|
||||
return this.self().find('.form-control').contains(value).click();
|
||||
}
|
||||
|
||||
templateName(): EmberInputPo {
|
||||
return new EmberInputPo('[data-testid="form-name-description__name"]');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.self().find('button').contains('Create').click();
|
||||
}
|
||||
|
||||
save() {
|
||||
return this.self().find('button').contains('Save').click();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,4 +4,12 @@ export default class EmberModalPo extends EmberComponentPo {
|
|||
constructor() {
|
||||
super('.modal-open');
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
return this.self().contains('.btn', 'Deactivate').click();
|
||||
}
|
||||
|
||||
delete() {
|
||||
return this.self().contains('.btn', 'Delete').click();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po';
|
||||
|
||||
export default class EmberSelectPo extends EmberComponentPo {
|
||||
getMenuItem(label: string, index = 0) {
|
||||
return this.self().eq(index).contains(label);
|
||||
}
|
||||
|
||||
selectMenuItemByLabel(label: string, index = 0) {
|
||||
return this.self().eq(index).contains(label).click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Select an <option> within a <select> using cy.select() command.
|
||||
* @param index
|
||||
* @param option
|
||||
* @returns
|
||||
*/
|
||||
selectMenuItemByOption(option: string, index = 0) {
|
||||
return this.self().eq(index).select(option);
|
||||
}
|
||||
|
||||
checkOptionSelected(label: string, index = 0) {
|
||||
return this.self().eq(index).should('contain.text', label);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
import EmberComponentPo from '@/cypress/e2e/po/components/ember/ember-component.po';
|
||||
import EmberSelectPo from '@/cypress/e2e/po/components/ember/ember-select.po';
|
||||
|
||||
export default class EmberSortableTablePo extends EmberComponentPo {
|
||||
/**
|
||||
* Get main row with name
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
rowWithName(name: string) {
|
||||
return this.self().contains('.main-row', new RegExp(` ${ name } `));
|
||||
}
|
||||
|
||||
/**
|
||||
* Open row action menu for main row with name
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
rowActionMenuOpen(name: string) {
|
||||
return this.rowWithName(name).find('.ember-basic-dropdown-trigger').click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get state of main row with name
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
state(name: string) {
|
||||
return this.rowWithName(name).find('.state');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get group row with name
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
groupRowWithName(name: string) {
|
||||
return this.self().contains('.group-row', new RegExp(` ${ name } `));
|
||||
}
|
||||
|
||||
/**
|
||||
* Open row action menu for group row with name
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
groupRowActionMenuOpen(name: string) {
|
||||
return this.groupRowWithName(name).find('.ember-basic-dropdown-trigger').click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get row for a given group with group and main row name
|
||||
* @param groupRowName
|
||||
* @param mainRowName
|
||||
* @returns
|
||||
*/
|
||||
rowWithinGroupByName(groupRowName: string, mainRowName: string) {
|
||||
return this.self()
|
||||
.contains('.group-row', new RegExp(` ${ groupRowName } `))
|
||||
.siblings('tr.main-row')
|
||||
.contains(mainRowName);
|
||||
}
|
||||
|
||||
bulkActions(label: string) {
|
||||
return cy.iFrame().contains('.bulk-actions', label);
|
||||
}
|
||||
|
||||
actionMenu(): EmberSelectPo {
|
||||
return new EmberSelectPo('.ember-basic-dropdown-content');
|
||||
}
|
||||
}
|
||||
|
|
@ -21,15 +21,20 @@ export default class LabeledInputPo extends ComponentPo {
|
|||
/**
|
||||
* Type value in the input
|
||||
* @param value Value to be typed
|
||||
* @param secret Pass in true to hide sensitive data from logs
|
||||
* @returns
|
||||
*/
|
||||
set(value: string): Cypress.Chainable {
|
||||
set(value: string, secret?: boolean): Cypress.Chainable {
|
||||
this.input().should('be.visible');
|
||||
this.input().focus();
|
||||
this.input().clear();
|
||||
|
||||
if (secret) {
|
||||
return this.input().type(value, { log: false });
|
||||
} else {
|
||||
return this.input().type(value);
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
return this.input().clear();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
import ComponentPo from '@/cypress/e2e/po/components/component.po';
|
||||
import { CypressChainable } from '@/cypress/e2e/po/po.types';
|
||||
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
|
||||
|
||||
export default class ResourceYamlPo extends ComponentPo {
|
||||
constructor(parent: CypressChainable) {
|
||||
super(parent.find('.resource-yaml'));
|
||||
}
|
||||
|
||||
saveOrCreate(): AsyncButtonPo {
|
||||
return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import CruResourcePo from '@/cypress/e2e/po/components/cru-resource.po';
|
||||
|
||||
export default class BaseCloudCredentialsPo extends PagePo {
|
||||
private static createPath(clusterId: string, id?: string ) {
|
||||
const root = `/c/${ clusterId }/manager/cloudCredential`;
|
||||
|
||||
return id ? `${ root }/${ id }` : `${ root }/create`;
|
||||
}
|
||||
|
||||
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
throw new Error('invalid');
|
||||
}
|
||||
|
||||
constructor(clusterId = 'local', id?: string) {
|
||||
super(BaseCloudCredentialsPo.createPath(clusterId, id));
|
||||
}
|
||||
|
||||
cloudServiceOptions(): CruResourcePo {
|
||||
return new CruResourcePo('[data-testid="cru-form"]');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
|
||||
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
|
||||
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
|
||||
import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po';
|
||||
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po';
|
||||
|
||||
export default class ChartRepositoriesCreateEditPo extends PagePo {
|
||||
private static createPath(clusterId: string, product: 'apps' | 'manager', repoName?: string ) {
|
||||
const root = `/c/${ clusterId }/${ product }/catalog.cattle.io.clusterrepo`;
|
||||
|
||||
return repoName ? `${ root }/${ repoName }` : `${ root }/create`;
|
||||
}
|
||||
|
||||
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
throw new Error('invalid');
|
||||
}
|
||||
|
||||
constructor(clusterId = 'local', product: 'apps' | 'manager', id?: string) {
|
||||
super(ChartRepositoriesCreateEditPo.createPath(clusterId, product, id));
|
||||
}
|
||||
|
||||
nameNsDescription() {
|
||||
return new NameNsDescription(this.self());
|
||||
}
|
||||
|
||||
gitRepoUrl(): LabeledInputPo {
|
||||
return LabeledInputPo.byLabel(this.self(), 'Git Repo URL');
|
||||
}
|
||||
|
||||
gitBranch(): LabeledInputPo {
|
||||
return LabeledInputPo.byLabel(this.self(), 'Git Branch');
|
||||
}
|
||||
|
||||
authentication(): LabeledSelectPo {
|
||||
return new LabeledSelectPo('.vs__dropdown-toggle');
|
||||
}
|
||||
|
||||
repoRadioBtn(): RadioGroupInputPo {
|
||||
return new RadioGroupInputPo('[data-testid="clusterrepo-radio-input"]');
|
||||
}
|
||||
|
||||
saveCreateForm(): AsyncButtonPo {
|
||||
return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self());
|
||||
}
|
||||
|
||||
saveAndWaitForRequests(method: string, url: string) {
|
||||
cy.intercept(method, url).as('request');
|
||||
this.saveCreateForm().click();
|
||||
|
||||
return cy.wait('@request', { timeout: 10000 });
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
|
||||
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
|
||||
import BaseCloudCredentialsPo from '@/cypress/e2e/po/edit/base-cloud-credentials.po';
|
||||
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po';
|
||||
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
|
||||
export default class AmazonCloudCredentialsCreateEditPo extends BaseCloudCredentialsPo {
|
||||
nameNsDescription() {
|
||||
return new NameNsDescription(this.self());
|
||||
}
|
||||
|
||||
accessKey(): LabeledInputPo {
|
||||
return LabeledInputPo.byLabel(this.self(), 'Access Key');
|
||||
}
|
||||
|
||||
secretKey(): LabeledInputPo {
|
||||
return LabeledInputPo.byLabel(this.self(), 'Secret Key');
|
||||
}
|
||||
|
||||
defaultRegion(): LabeledSelectPo {
|
||||
return new LabeledSelectPo('.vs__dropdown-toggle');
|
||||
}
|
||||
|
||||
saveCreateForm(): ResourceDetailPo {
|
||||
return new ResourceDetailPo(this.self());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
|
||||
export default class MachineDeploymentsCreateEditPo extends PagePo {
|
||||
private static createPath(clusterId: string, nsName?: string, machineSetName?: string ) {
|
||||
const root = `/c/${ clusterId }/manager/cluster.x-k8s.io.machinedeployment`;
|
||||
|
||||
return nsName && machineSetName ? `${ root }/${ nsName }/${ machineSetName }` : `${ root }/create`;
|
||||
}
|
||||
|
||||
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
throw new Error('invalid');
|
||||
}
|
||||
|
||||
constructor(clusterId = 'local', nsName?: string, machineSetName?: string) {
|
||||
super(MachineDeploymentsCreateEditPo.createPath(clusterId, nsName, machineSetName));
|
||||
}
|
||||
|
||||
saveCreateForm(): ResourceDetailPo {
|
||||
return new ResourceDetailPo(this.self());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
|
||||
export default class MachineSetsCreateEditPo extends PagePo {
|
||||
private static createPath(clusterId: string, nsName?: string, machineSetName?: string ) {
|
||||
const root = `/c/${ clusterId }/manager/cluster.x-k8s.io.machineset`;
|
||||
|
||||
return nsName && machineSetName ? `${ root }/${ nsName }/${ machineSetName }` : `${ root }/create`;
|
||||
}
|
||||
|
||||
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
throw new Error('invalid');
|
||||
}
|
||||
|
||||
constructor(clusterId = 'local', nsName?: string, machineSetName?: string) {
|
||||
super(MachineSetsCreateEditPo.createPath(clusterId, nsName, machineSetName));
|
||||
}
|
||||
|
||||
saveCreateForm(): ResourceDetailPo {
|
||||
return new ResourceDetailPo(this.self());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
|
||||
|
||||
export default class MachinesCreateEditPo extends PagePo {
|
||||
private static createPath(clusterId: string, nsName?: string, machineName?: string ) {
|
||||
const root = `/c/${ clusterId }/manager/cluster.x-k8s.io.machine`;
|
||||
|
||||
return nsName && machineName ? `${ root }/${ nsName }/${ machineName }` : `${ root }/create`;
|
||||
}
|
||||
|
||||
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
throw new Error('invalid');
|
||||
}
|
||||
|
||||
constructor(clusterId = 'local', nsName?: string, machineName?: string) {
|
||||
super(MachinesCreateEditPo.createPath(clusterId, nsName, machineName));
|
||||
}
|
||||
|
||||
saveCreateForm(): ResourceDetailPo {
|
||||
return new ResourceDetailPo(this.self());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po';
|
||||
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
|
||||
import InputPo from '@/cypress/e2e/po/components/input.po';
|
||||
import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po';
|
||||
export default class PodSecurityAdmissionsCreateEditPo extends PagePo {
|
||||
private static createPath(clusterId: string, id?: string ) {
|
||||
const root = `/c/${ clusterId }/manager/management.cattle.io.podsecurityadmissionconfigurationtemplate`;
|
||||
|
||||
return id ? `${ root }/${ id }` : `${ root }/create`;
|
||||
}
|
||||
|
||||
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
throw new Error('invalid');
|
||||
}
|
||||
|
||||
constructor(clusterId = 'local', id?: string) {
|
||||
super(PodSecurityAdmissionsCreateEditPo.createPath(clusterId, id));
|
||||
}
|
||||
|
||||
nameNsDescription() {
|
||||
return new NameNsDescription(this.self());
|
||||
}
|
||||
|
||||
psaControlLevel(itemRow: number, optionIndex: number) {
|
||||
const selectMode = new LabeledSelectPo(`[data-testid="pod-security-admission--psaControl-${ itemRow }-level"]`, this.self());
|
||||
|
||||
selectMode.toggle();
|
||||
selectMode.clickOption(optionIndex);
|
||||
}
|
||||
|
||||
psaControlVersion(itemRow: number, text: string) {
|
||||
const setVersion = new InputPo(`[data-testid="pod-security-admission--psaControl-${ itemRow }-version"]`, this.self());
|
||||
|
||||
setVersion.set(text);
|
||||
}
|
||||
|
||||
setExemptionsCheckbox(optionIndex: number) {
|
||||
const setExemptionsCheckbox = new CheckboxInputPo(`[data-testid="pod-security-admission--psaExemptionsControl-${ optionIndex }-active"]`);
|
||||
|
||||
setExemptionsCheckbox.set();
|
||||
}
|
||||
|
||||
setExemptionsInput(optionIndex: number, text: string) {
|
||||
const setExemptionsInputbox = new InputPo(`[data-testid="pod-security-admission--psaExemptionsControl-${ optionIndex }-value"]`);
|
||||
|
||||
setExemptionsInputbox.set(text);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import ClusterManagerCreatePagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create.po';
|
||||
import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po';
|
||||
import ClusterManagerCreateRKE1PagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke1.po';
|
||||
import EmberAccordionPo from '@/cypress/e2e/po/components/ember/ember-accordion.po';
|
||||
import EmberFormMembersPo from '@/cypress/e2e/po/components/ember/ember-form-members.po';
|
||||
import EmberCheckboxInputPo from '@/cypress/e2e/po/components/ember/ember-checkbox-input.po';
|
||||
import EmberSelectPo from '@/cypress/e2e/po/components/ember/ember-select.po';
|
||||
|
||||
/**
|
||||
* Create page for an RKE1 amazonec2 cluster
|
||||
*/
|
||||
export default class ClusterManagerCreateRke1Amazonec2PagePo extends ClusterManagerCreateRKE1PagePo {
|
||||
static url = `${ ClusterManagerCreatePagePo.url }/create?type=amazonec2`
|
||||
static goTo(): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return PagePo.goTo(ClusterManagerCreateRke1Amazonec2PagePo.url);
|
||||
}
|
||||
|
||||
goToAmazonec2ClusterCreation(): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return PagePo.goTo(`${ ClusterManagerCreatePagePo.url }?type=amazonec2`);
|
||||
}
|
||||
|
||||
clusterName(): EmberInputPo {
|
||||
return new EmberInputPo('[data-testid="form-name-description__name"]');
|
||||
}
|
||||
|
||||
memberRoles(): EmberAccordionPo {
|
||||
return new EmberAccordionPo('cru-cluster__members');
|
||||
}
|
||||
|
||||
memberRolesFormMembers(): EmberFormMembersPo {
|
||||
return new EmberFormMembersPo('[data-testid="cru-cluster__members__form"]') ;
|
||||
}
|
||||
|
||||
clusterTemplateCheckbox(): EmberCheckboxInputPo {
|
||||
return new EmberCheckboxInputPo('.cluster-template-select');
|
||||
}
|
||||
|
||||
nodeTemplateDropdown(): EmberSelectPo {
|
||||
return new EmberSelectPo('.main-row .new-select > select');
|
||||
}
|
||||
|
||||
rkeTemplateAndRevisionDropdown(): EmberSelectPo {
|
||||
return new EmberSelectPo('.new-select > select');
|
||||
}
|
||||
|
||||
selectedOption(): EmberSelectPo {
|
||||
return new EmberSelectPo('.new-select > select option:selected');
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import EmberInputPo from '@/cypress/e2e/po/components/ember/ember-input.po';
|
|||
import ClusterManagerCreateRKE1PagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke1.po';
|
||||
import EmberAccordionPo from '@/cypress/e2e/po/components/ember/ember-accordion.po';
|
||||
import EmberFormMembersPo from '@/cypress/e2e/po/components/ember/ember-form-members.po';
|
||||
import EmberCheckboxInputPo from '@/cypress/e2e/po/components/ember/ember-checkbox-input.po';
|
||||
import EmberSelectPo from '@/cypress/e2e/po/components/ember/ember-select.po';
|
||||
|
||||
/**
|
||||
* Create page for an RKE1 custom cluster
|
||||
|
|
@ -32,6 +34,18 @@ export default class ClusterManagerCreateRke1CustomPagePo extends ClusterManager
|
|||
return new EmberFormMembersPo('[data-testid="cru-cluster__members__form"]') ;
|
||||
}
|
||||
|
||||
clusterTemplateCheckbox(): EmberCheckboxInputPo {
|
||||
return new EmberCheckboxInputPo('.cluster-template-select');
|
||||
}
|
||||
|
||||
rkeTemplateAndRevisionDropdown(): EmberSelectPo {
|
||||
return new EmberSelectPo('.new-select > select');
|
||||
}
|
||||
|
||||
selectedOption(): EmberSelectPo {
|
||||
return new EmberSelectPo('.new-select > select option:selected');
|
||||
}
|
||||
|
||||
// Roles Page
|
||||
|
||||
nodeCommand(): EmberAccordionPo {
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
||||
|
||||
/**
|
||||
* List component for catalog.cattle.io.clusterrepo resources
|
||||
*/
|
||||
export default class RepoListPo extends BaseResourceList {
|
||||
actionMenu(repoName: string) {
|
||||
return this.resourceTable().sortableTable().rowActionMenuOpen(repoName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
||||
|
||||
/**
|
||||
* List component for catalog.cattle.io.clusterrepo resources
|
||||
*/
|
||||
export default class ChartRepositoriesListPo extends BaseResourceList {
|
||||
actionMenu(repoName: string) {
|
||||
return this.resourceTable().sortableTable().rowActionMenuOpen(repoName);
|
||||
}
|
||||
|
||||
openBulkActionDropdown() {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownOpen();
|
||||
}
|
||||
|
||||
bulkActionButton(name: string) {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownButton(name);
|
||||
}
|
||||
|
||||
details(name: string, index: number) {
|
||||
return this.resourceTable().sortableTable().rowWithName(name).column(index);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
||||
|
||||
export default class CloudCredentialsListPo extends BaseResourceList {
|
||||
details(name: string, index: number) {
|
||||
return this.resourceTable().sortableTable().rowWithName(name).column(index);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
||||
|
||||
export default class MachineDeploymentsListPo extends BaseResourceList {
|
||||
openBulkActionDropdown() {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownOpen();
|
||||
}
|
||||
|
||||
bulkActionButton(name: string) {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownButton(name);
|
||||
}
|
||||
|
||||
details(name: string, index: number) {
|
||||
return this.resourceTable().sortableTable().rowWithName(name).column(index);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
||||
|
||||
export default class MachineSetsListPo extends BaseResourceList {
|
||||
openBulkActionDropdown() {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownOpen();
|
||||
}
|
||||
|
||||
bulkActionButton(name: string) {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownButton(name);
|
||||
}
|
||||
|
||||
details(name: string, index: number) {
|
||||
return this.resourceTable().sortableTable().rowWithName(name).column(index);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
||||
|
||||
export default class MachinesListPo extends BaseResourceList {
|
||||
details(name: string, index: number) {
|
||||
return this.resourceTable().sortableTable().rowWithName(name).column(index);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
||||
|
||||
export default class PodSecurityAdmissionListPo extends BaseResourceList {
|
||||
details(name: string, index: number) {
|
||||
return this.resourceTable().sortableTable().rowWithName(name).column(index);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,18 @@ import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
|
|||
* List component for provisioning.cattle.io.cluster resources
|
||||
*/
|
||||
export default class ProvClusterListPo extends BaseResourceList {
|
||||
openBulkActionDropdown() {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownOpen();
|
||||
}
|
||||
|
||||
bulkActionButton(name: string) {
|
||||
return this.resourceTable().sortableTable().bulkActionDropDownButton(name);
|
||||
}
|
||||
|
||||
downloadKubeConfig() {
|
||||
return cy.getId('sortable-table-downloadKubeConfig');
|
||||
}
|
||||
|
||||
state(clusterName: string) {
|
||||
return this.resourceTable().sortableTable().rowWithName(clusterName).column(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import ChartRepositoriesListPo from '@/cypress/e2e/po/lists/chart-repositories.po';
|
||||
import ChartRepositoriesCreateEditPo from '@/cypress/e2e/po/edit/chart-repositories.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
|
||||
/**
|
||||
* List page for catalog.cattle.io.clusterrepo resources
|
||||
*/
|
||||
export default class ChartRepositoriesPagePo extends PagePo {
|
||||
private static createPath(clusterId: string, product: 'apps' | 'manager') {
|
||||
return `/c/${ clusterId }/${ product }/catalog.cattle.io.clusterrepo`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string, product: 'apps' | 'manager'): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(ChartRepositoriesPagePo.createPath(clusterId, product));
|
||||
}
|
||||
|
||||
constructor(private clusterId = 'local', private product: 'apps' | 'manager') {
|
||||
super(ChartRepositoriesPagePo.createPath(clusterId, product));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('Advanced').click();
|
||||
sideNav.navToSideMenuEntryByLabel('Repositories');
|
||||
}
|
||||
|
||||
createEditRepositories(repoName? : string): ChartRepositoriesCreateEditPo {
|
||||
return new ChartRepositoriesCreateEditPo(this.clusterId, this.product, repoName);
|
||||
}
|
||||
|
||||
list(): ChartRepositoriesListPo {
|
||||
return new ChartRepositoriesListPo('[data-testid="app-cluster-repo-list"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method
|
||||
*/
|
||||
sortableTable() {
|
||||
return this.list().resourceTable().sortableTable();
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.list().masthead().actions().contains('Create')
|
||||
.click();
|
||||
}
|
||||
|
||||
waitForGoTo(endpoint: string) {
|
||||
const interceptName = `validateGoTo${ Date.now() }`;
|
||||
|
||||
cy.intercept('GET', endpoint).as(interceptName);
|
||||
this.goTo();
|
||||
cy.wait(`@${ interceptName }`, { timeout: 15000 }).its('response.statusCode').should('eq', 200);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import CloudCredentialsCreateEditPo from '@/cypress/e2e/po/edit/cloud-credentials-amazon.po';
|
||||
import CloudCredentialsListPo from '@/cypress/e2e/po/lists/cloud-credentials-list.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
|
||||
export default class CloudCredentialsPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/cloudCredential`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(CloudCredentialsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(private clusterId = 'local') {
|
||||
super(CloudCredentialsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.navToSideMenuEntryByLabel('Cloud Credentials');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.list().masthead().actions().contains('Create')
|
||||
.click();
|
||||
}
|
||||
|
||||
createEditCloudCreds(id?: string): CloudCredentialsCreateEditPo {
|
||||
return new CloudCredentialsCreateEditPo(this.clusterId, id);
|
||||
}
|
||||
|
||||
list(): CloudCredentialsListPo {
|
||||
return new CloudCredentialsListPo('[data-testid="cluster-list-container"]');
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ export default class ClusterManagerListPagePo extends PagePo {
|
|||
}
|
||||
|
||||
static navTo() {
|
||||
BurgerMenuPo.toggle();
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import CodeMirrorPo from '@/cypress/e2e/po/components/code-mirror.po';
|
||||
import MachineDeploymentsCreateEditPo from '@/cypress/e2e/po/edit/machine-deployments.po';
|
||||
import MachineDeploymentsListPo from '@/cypress/e2e/po/lists/machine-deployments-list.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
export default class MachineDeploymentsPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/cluster.x-k8s.io.machinedeployment`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(MachineDeploymentsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(private clusterId = 'local') {
|
||||
super(MachineDeploymentsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('Advanced').click();
|
||||
sideNav.navToSideMenuEntryByLabel('MachineDeployments');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.list().masthead().actions().contains('Create from YAML')
|
||||
.click();
|
||||
}
|
||||
|
||||
createEditMachineDeployment(nsName?: string, machineSetName?: string): MachineDeploymentsCreateEditPo {
|
||||
return new MachineDeploymentsCreateEditPo(this.clusterId, nsName, machineSetName);
|
||||
}
|
||||
|
||||
list(): MachineDeploymentsListPo {
|
||||
return new MachineDeploymentsListPo('[data-testid="cluster-list-container"]');
|
||||
}
|
||||
|
||||
yamlEditor(): CodeMirrorPo {
|
||||
return CodeMirrorPo.bySelector(this.self(), '[data-testid="yaml-editor-code-mirror"]');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import CodeMirrorPo from '@/cypress/e2e/po/components/code-mirror.po';
|
||||
import MachineSetsCreateEditPo from '@/cypress/e2e/po/edit/machine-sets.po';
|
||||
import MachineSetsListPo from '@/cypress/e2e/po/lists/machine-set-list.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
|
||||
export default class MachineSetsPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/cluster.x-k8s.io.machineset`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(MachineSetsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(private clusterId = 'local') {
|
||||
super(MachineSetsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('Advanced').click();
|
||||
sideNav.navToSideMenuEntryByLabel('MachineSets');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.list().masthead().actions().contains('Create from YAML')
|
||||
.click();
|
||||
}
|
||||
|
||||
createEditMachineSet(nsName?: string, machineSetName?: string): MachineSetsCreateEditPo {
|
||||
return new MachineSetsCreateEditPo(this.clusterId, nsName, machineSetName);
|
||||
}
|
||||
|
||||
list(): MachineSetsListPo {
|
||||
return new MachineSetsListPo('[data-testid="cluster-list-container"]');
|
||||
}
|
||||
|
||||
yamlEditor(): CodeMirrorPo {
|
||||
return CodeMirrorPo.bySelector(this.self(), '[data-testid="yaml-editor-code-mirror"]');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import MachinesCreateEditPo from '@/cypress/e2e/po/edit/machines.po';
|
||||
import MachinesListPo from '@/cypress/e2e/po/lists/machines-list.po';
|
||||
import CodeMirrorPo from '@/cypress/e2e/po/components/code-mirror.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
|
||||
export default class MachinesPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/cluster.x-k8s.io.machine`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(MachinesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(private clusterId = 'local') {
|
||||
super(MachinesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('Advanced').click();
|
||||
sideNav.navToSideMenuEntryByLabel('Machines');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.list().masthead().actions().contains('Create from YAML')
|
||||
.click();
|
||||
}
|
||||
|
||||
createEditMachines(nsName?: string, machineName?: string): MachinesCreateEditPo {
|
||||
return new MachinesCreateEditPo(this.clusterId, nsName, machineName);
|
||||
}
|
||||
|
||||
list(): MachinesListPo {
|
||||
return new MachinesListPo('[data-testid="cluster-list-container"]');
|
||||
}
|
||||
|
||||
yamlEditor(): CodeMirrorPo {
|
||||
return CodeMirrorPo.bySelector(this.self(), '[data-testid="yaml-editor-code-mirror"]');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import EmberSortableTablePo from '@/cypress/e2e/po/components/ember/ember-sortable-table.po';
|
||||
import EmberModalAddNodeTemplatePo from '@/cypress/e2e/po/components/ember/ember-modal-add-node-template.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
|
||||
export default class NodeTemplatesPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/pages/node-templates`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(NodeTemplatesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(clusterId: string) {
|
||||
super(NodeTemplatesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('RKE1 Configuration').click();
|
||||
sideNav.navToSideMenuEntryByLabel('Node Templates');
|
||||
}
|
||||
|
||||
addNodeTemplateModal(): EmberModalAddNodeTemplatePo {
|
||||
return new EmberModalAddNodeTemplatePo();
|
||||
}
|
||||
|
||||
list(): EmberSortableTablePo {
|
||||
return new EmberSortableTablePo('.sortable-table');
|
||||
}
|
||||
|
||||
addTemplate() {
|
||||
return cy.iFrame().contains('.right-buttons .btn', 'Add Template');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import PodSecurityAdmissionsCreateEditPo from '@/cypress/e2e/po/edit/pod-security-admissions.po';
|
||||
import PodSecurityAdmissionListPo from '@/cypress/e2e/po/lists/pod-security-admissions-list.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
export default class PodSecurityAdmissionsPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/management.cattle.io.podsecurityadmissionconfigurationtemplate`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(PodSecurityAdmissionsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(private clusterId = 'local') {
|
||||
super(PodSecurityAdmissionsPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('Advanced').click();
|
||||
sideNav.navToSideMenuEntryByLabel('Pod Security Admissions');
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.list().masthead().actions().contains('Create')
|
||||
.click();
|
||||
}
|
||||
|
||||
createPodSecurityAdmissionForm(id? : string): PodSecurityAdmissionsCreateEditPo {
|
||||
return new PodSecurityAdmissionsCreateEditPo(this.clusterId, id);
|
||||
}
|
||||
|
||||
list(): PodSecurityAdmissionListPo {
|
||||
return new PodSecurityAdmissionListPo('[data-testid="cluster-list-container"]');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import EmberSortableTablePo from '@/cypress/e2e/po/components/ember/ember-sortable-table.po';
|
||||
import EmberSelectPo from '@/cypress/e2e/po/components/ember/ember-select.po';
|
||||
import EmberAddPodSecurityTemplatePo from '@/cypress/e2e/po/components/ember/ember-form-pod-security-template.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
|
||||
export default class PodSecurityPoliciesTemplatesPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/pages/pod-security-policies`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(PodSecurityPoliciesTemplatesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(clusterId: string) {
|
||||
super(PodSecurityPoliciesTemplatesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('Advanced').click();
|
||||
sideNav.navToSideMenuEntryByLabel('Pod Security Policy Templates');
|
||||
}
|
||||
|
||||
addPodSecurityTemplateForm(): EmberAddPodSecurityTemplatePo {
|
||||
return new EmberAddPodSecurityTemplatePo('.container');
|
||||
}
|
||||
|
||||
list(): EmberSortableTablePo {
|
||||
return new EmberSortableTablePo('.sortable-table');
|
||||
}
|
||||
|
||||
addPolicyTemplate() {
|
||||
return cy.iFrame().contains('.right-buttons .btn', 'Add Policy Template');
|
||||
}
|
||||
|
||||
bulkActions(label: string) {
|
||||
return cy.iFrame().contains('.bulk-actions', label);
|
||||
}
|
||||
|
||||
actionMenu(): EmberSelectPo {
|
||||
return new EmberSelectPo('.ember-basic-dropdown-content');
|
||||
}
|
||||
|
||||
// details view
|
||||
|
||||
templateDescription(label: string) {
|
||||
return cy.iFrame().contains('.banner-message p', label);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import EmberSortableTablePo from '@/cypress/e2e/po/components/ember/ember-sortable-table.po';
|
||||
import EmberSelectPo from '@/cypress/e2e/po/components/ember/ember-select.po';
|
||||
import EmberModalClusterDriverPo from '@/cypress/e2e/po/components/ember/ember-modal-add-edit-cluster-driver.po';
|
||||
import EmberModalNodeDriverPo from '@/cypress/e2e/po/components/ember/ember-modal-add-edit-node-driver.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
export default class RkeDriversPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/pages/rke-drivers`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(RkeDriversPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(clusterId: string) {
|
||||
super(RkeDriversPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.navToSideMenuEntryByLabel('Drivers');
|
||||
}
|
||||
|
||||
list(): EmberSortableTablePo {
|
||||
return new EmberSortableTablePo('table.grid.sortable-table');
|
||||
}
|
||||
|
||||
refreshKubMetadata() {
|
||||
return cy.iFrame().contains('.right-buttons .btn', 'Refresh Kubernetes Metadata');
|
||||
}
|
||||
|
||||
addClusterDriver() {
|
||||
return cy.iFrame().contains('.right-buttons .btn', 'Add Cluster Driver');
|
||||
}
|
||||
|
||||
addNodeDriver() {
|
||||
return cy.iFrame().contains('.right-buttons .btn', 'Add Node Driver');
|
||||
}
|
||||
|
||||
createEditClusterDriver(): EmberModalClusterDriverPo {
|
||||
return new EmberModalClusterDriverPo();
|
||||
}
|
||||
|
||||
createEditNodeDriver(): EmberModalNodeDriverPo {
|
||||
return new EmberModalNodeDriverPo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tab by name
|
||||
* @param tabName Cluster Drivers or Node Drivers
|
||||
* @returns
|
||||
*/
|
||||
tabs(tabName: string) {
|
||||
return cy.iFrame().contains('.tab-nav li', tabName);
|
||||
}
|
||||
|
||||
actionMenu(): EmberSelectPo {
|
||||
return new EmberSelectPo('.ember-basic-dropdown-content');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import EmberSortableTablePo from '@/cypress/e2e/po/components/ember/ember-sortable-table.po';
|
||||
import EmberSelectPo from '@/cypress/e2e/po/components/ember/ember-select.po';
|
||||
import EmberFormRkeTemplatesPo from '@/cypress/e2e/po/components/ember/ember-form-rke-templates.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
|
||||
export default class RkeTemplatesPagePo extends PagePo {
|
||||
private static createPath(clusterId: string) {
|
||||
return `/c/${ clusterId }/manager/pages/rke-templates`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(RkeTemplatesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
constructor(clusterId: string) {
|
||||
super(RkeTemplatesPagePo.createPath(clusterId));
|
||||
}
|
||||
|
||||
static navTo() {
|
||||
const sideNav = new ProductNavPo();
|
||||
|
||||
BurgerMenuPo.burgerMenuNavToMenubyLabel('Cluster Management');
|
||||
sideNav.groups().contains('RKE1 Configuration').click();
|
||||
sideNav.navToSideMenuEntryByLabel('RKE Templates');
|
||||
}
|
||||
|
||||
addTemplate() {
|
||||
return cy.iFrame().contains('.right-buttons .btn', 'Add Template');
|
||||
}
|
||||
|
||||
groupRow(): EmberSortableTablePo {
|
||||
return new EmberSortableTablePo('table.sortable-table .group-row');
|
||||
}
|
||||
|
||||
mainRow(): EmberSortableTablePo {
|
||||
return new EmberSortableTablePo('table.sortable-table .main-row');
|
||||
}
|
||||
|
||||
actionMenu(): EmberSelectPo {
|
||||
return new EmberSelectPo('.ember-basic-dropdown-content');
|
||||
}
|
||||
|
||||
form(): EmberFormRkeTemplatesPo {
|
||||
return new EmberFormRkeTemplatesPo('form.horizontal-form');
|
||||
}
|
||||
}
|
||||
|
|
@ -4,9 +4,9 @@ import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
|
|||
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
|
||||
import ActionMenuPo from '@/cypress/e2e/po/components/action-menu.po';
|
||||
import NameNsDescriptionPo from '@/cypress/e2e/po/components/name-ns-description.po';
|
||||
import ReposListPagePo from '@/cypress/e2e/po/pages/repositories.po';
|
||||
import AppClusterRepoEditPo from '@/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po';
|
||||
import RepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
|
||||
import BannersPo from '@/cypress/e2e/po/components/banners.po';
|
||||
import ChartRepositoriesCreateEditPo from '@/cypress/e2e/po/edit/chart-repositories.po';
|
||||
|
||||
export default class ExtensionsPagePo extends PagePo {
|
||||
static url = '/c/local/uiplugins'
|
||||
|
|
@ -90,25 +90,26 @@ export default class ExtensionsPagePo extends PagePo {
|
|||
this.manageReposClick();
|
||||
|
||||
// create a new clusterrepo
|
||||
const appRepoList = new ReposListPagePo('local', 'apps');
|
||||
const appRepoList = new RepositoriesPagePo('local', 'apps');
|
||||
|
||||
appRepoList.waitForPage();
|
||||
appRepoList.waitForGoTo('/v1/catalog.cattle.io.clusterrepos?exclude=metadata.managedFields');
|
||||
appRepoList.create();
|
||||
|
||||
const appRepoCreate = new AppClusterRepoEditPo('local', 'create');
|
||||
const appRepoCreate = new ChartRepositoriesCreateEditPo('local', 'apps');
|
||||
|
||||
appRepoCreate.waitForPage();
|
||||
|
||||
// fill the form
|
||||
appRepoCreate.selectRadioOptionGitRepo(1);
|
||||
appRepoCreate.repoRadioBtn().set(1);
|
||||
appRepoCreate.nameNsDescription().name().self().scrollIntoView()
|
||||
.should('be.visible');
|
||||
appRepoCreate.nameNsDescription().name().set(name);
|
||||
appRepoCreate.enterGitRepoName(repo);
|
||||
appRepoCreate.enterGitBranchName(branch);
|
||||
appRepoCreate.gitRepoUrl().set(repo);
|
||||
appRepoCreate.gitBranch().set(branch);
|
||||
|
||||
// save it
|
||||
return appRepoCreate.save();
|
||||
return appRepoCreate.saveAndWaitForRequests('POST', '/v1/catalog.cattle.io.clusterrepos');
|
||||
}
|
||||
|
||||
// ------------------ extension card ------------------
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
import SimpleBoxPo from '~/cypress/e2e/po/components/simple-box.po';
|
||||
import SimpleBoxPo from '@/cypress/e2e/po/components/simple-box.po';
|
||||
|
||||
const burgerMenu = new BurgerMenuPo();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
import PagePo from '@/cypress/e2e/po/pages/page.po';
|
||||
import RepoListPo from '@/cypress/e2e/po/lists/catalog.cattle.io.clusterrepo.po';
|
||||
|
||||
/**
|
||||
* List page for catalog.cattle.io.clusterrepo resources
|
||||
*/
|
||||
export default class ReposListPagePo extends PagePo {
|
||||
private static createPath(clusterId: string, product: 'apps' | 'manager') {
|
||||
return `/c/${ clusterId }/${ product }/catalog.cattle.io.clusterrepo`;
|
||||
}
|
||||
|
||||
static goTo(clusterId: string, product: 'apps' | 'manager'): Cypress.Chainable<Cypress.AUTWindow> {
|
||||
return super.goTo(ReposListPagePo.createPath(clusterId, product));
|
||||
}
|
||||
|
||||
constructor(clusterId: string, product: 'apps' | 'manager') {
|
||||
super(ReposListPagePo.createPath(clusterId, product));
|
||||
}
|
||||
|
||||
list(): RepoListPo {
|
||||
return new RepoListPo('[data-testid="app-cluster-repo-list"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method
|
||||
*/
|
||||
sortableTable() {
|
||||
return this.list().resourceTable().sortableTable();
|
||||
}
|
||||
|
||||
create() {
|
||||
return this.list().masthead().actions().eq(0)
|
||||
.click();
|
||||
}
|
||||
|
||||
waitForGoTo(endpoint: string) {
|
||||
const interceptName = `validateGoTo${ Date.now() }`;
|
||||
|
||||
cy.intercept('GET', endpoint).as(interceptName);
|
||||
this.goTo();
|
||||
cy.wait(`@${ interceptName }`, { timeout: 15000 }).its('response.statusCode').should('eq', 200);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import ReposListPagePo from '@/cypress/e2e/po/pages/repositories.po';
|
||||
import ReposListPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
|
||||
import AppClusterRepoEditPo from '@/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po';
|
||||
|
||||
describe('Apps/Repositories', { tags: ['@explorer', '@adminUser'] }, () => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import ExtensionsPagePo from '@/cypress/e2e/po/pages/extensions.po';
|
||||
import ReposListPagePo from '@/cypress/e2e/po/pages/repositories.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';
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ describe('Extensions page', { tags: ['@extensions', '@adminUser'] }, () => {
|
|||
extensionsPo.addReposModal().should('not.exist');
|
||||
|
||||
// go to repos list page
|
||||
const appRepoList = new ReposListPagePo('local', 'apps');
|
||||
const appRepoList = new RepositoriesPagePo('local', 'apps');
|
||||
|
||||
appRepoList.goTo();
|
||||
appRepoList.waitForPage();
|
||||
|
|
@ -96,7 +96,7 @@ describe('Extensions page', { tags: ['@extensions', '@adminUser'] }, () => {
|
|||
}
|
||||
});
|
||||
|
||||
const appRepoList = new ReposListPagePo('local', 'apps');
|
||||
const appRepoList = new RepositoriesPagePo('local', 'apps');
|
||||
|
||||
// Ensure that the banner should be shown (by confirming that a required repo isn't there)
|
||||
appRepoList.goTo();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import ExtensionsPagePo from '@/cypress/e2e/po/pages/extensions.po';
|
||||
import { ChartsPage } from '@/cypress/e2e/po/pages/charts.po';
|
||||
import ReposListPagePo from '@/cypress/e2e/po/pages/repositories.po';
|
||||
import RepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
|
||||
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
|
||||
import KubewardenExtensionPo from '@/cypress/e2e/po/pages/extensions/kubewarden.po';
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ describe('Kubewarden Extension', { tags: ['@extensions', '@adminUser'] }, () =>
|
|||
chartsPage.waitForPage();
|
||||
chartsPage.self().getId('charts-header-title').invoke('text').should('contain', 'Charts');
|
||||
|
||||
const appRepoList: ReposListPagePo = new ReposListPagePo('local', 'apps');
|
||||
const appRepoList: RepositoriesPagePo = new RepositoriesPagePo('local', 'apps');
|
||||
|
||||
appRepoList.goTo();
|
||||
appRepoList.waitForPage();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
|
||||
import CloudCredentialsPagePo from '@/cypress/e2e/po/pages/cluster-manager/cloud-credentials.po';
|
||||
|
||||
// will only run this in jenkins pipeline where cloud credentials are stored
|
||||
describe('Cloud Credentials', { testIsolation: 'off', tags: ['@manager', '@jenkins', '@adminUser', '@standardUser'] }, () => {
|
||||
const cloudCredentialsPage = new CloudCredentialsPagePo('_');
|
||||
let cloudcredentialId = '';
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('cloudCredential').as('cloudCredentialName');
|
||||
});
|
||||
|
||||
it('can see error when authentication fails', function() {
|
||||
CloudCredentialsPagePo.navTo();
|
||||
cloudCredentialsPage.waitForPage();
|
||||
cloudCredentialsPage.create();
|
||||
cloudCredentialsPage.createEditCloudCreds().waitForPage();
|
||||
cloudCredentialsPage.createEditCloudCreds().cloudServiceOptions().selectSubTypeByIndex(0).click();
|
||||
cloudCredentialsPage.createEditCloudCreds().nameNsDescription().name().set(this.cloudCredentialName);
|
||||
cloudCredentialsPage.createEditCloudCreds().nameNsDescription().description().set(`${ this.cloudCredentialName }-description`);
|
||||
cloudCredentialsPage.createEditCloudCreds().accessKey().set(Cypress.env('awsAccessKey'));
|
||||
cloudCredentialsPage.createEditCloudCreds().secretKey().set(`${ Cypress.env('awsSecretKey') }abc`, true);
|
||||
cloudCredentialsPage.createEditCloudCreds().defaultRegion().checkOptionSelected('us-west-2');
|
||||
cloudCredentialsPage.createEditCloudCreds().saveCreateForm().cruResource().saveOrCreate()
|
||||
.click();
|
||||
cy.contains('Authentication test failed, please check your credentials').should('be.visible');
|
||||
});
|
||||
|
||||
it('can create aws cloud credentials', function() {
|
||||
CloudCredentialsPagePo.navTo();
|
||||
cloudCredentialsPage.create();
|
||||
cloudCredentialsPage.createEditCloudCreds().waitForPage();
|
||||
cloudCredentialsPage.createEditCloudCreds().cloudServiceOptions().selectSubTypeByIndex(0).click();
|
||||
cloudCredentialsPage.createEditCloudCreds().waitForPage('type=aws');
|
||||
cloudCredentialsPage.createEditCloudCreds().nameNsDescription().name().set(this.cloudCredentialName);
|
||||
cloudCredentialsPage.createEditCloudCreds().nameNsDescription().description().set(`${ this.cloudCredentialName }-description`);
|
||||
cloudCredentialsPage.createEditCloudCreds().accessKey().set(Cypress.env('awsAccessKey'));
|
||||
cloudCredentialsPage.createEditCloudCreds().secretKey().set(Cypress.env('awsSecretKey'), true);
|
||||
cloudCredentialsPage.createEditCloudCreds().defaultRegion().checkOptionSelected('us-west-2');
|
||||
cloudCredentialsPage.createEditCloudCreds().saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials')
|
||||
.then((req) => {
|
||||
cloudcredentialId = req.response?.body.id;
|
||||
});
|
||||
cloudCredentialsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cloudCredentialsPage.list().details(this.cloudCredentialName, 2).should('be.visible');
|
||||
});
|
||||
|
||||
it('can edit cloud credentials', function() {
|
||||
CloudCredentialsPagePo.navTo();
|
||||
cloudCredentialsPage.list().actionMenu(this.cloudCredentialName).getMenuItem('Edit Config').click();
|
||||
cloudCredentialsPage.createEditCloudCreds(cloudcredentialId).waitForPage('mode=edit');
|
||||
cloudCredentialsPage.createEditCloudCreds().nameNsDescription().description().set(`${ this.cloudCredentialName }-description-edit`);
|
||||
cloudCredentialsPage.createEditCloudCreds().secretKey().set(Cypress.env('awsSecretKey'), true);
|
||||
cloudCredentialsPage.createEditCloudCreds().saveCreateForm().cruResource().saveAndWaitForRequests('PUT', '/v3/cloudCredentials/**');
|
||||
cloudCredentialsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cloudCredentialsPage.list().details(`${ this.cloudCredentialName }-description-edit`, 3).should('be.visible');
|
||||
});
|
||||
|
||||
it('can clone cloud credentials', function() {
|
||||
CloudCredentialsPagePo.navTo();
|
||||
cloudCredentialsPage.list().actionMenu(`${ this.cloudCredentialName }-description-edit`).getMenuItem('Clone').click();
|
||||
cloudCredentialsPage.createEditCloudCreds(cloudcredentialId).waitForPage('mode=clone');
|
||||
cloudCredentialsPage.createEditCloudCreds().nameNsDescription().name().set(`${ this.cloudCredentialName }-clone`);
|
||||
cloudCredentialsPage.createEditCloudCreds().accessKey().set(Cypress.env('awsAccessKey'));
|
||||
cloudCredentialsPage.createEditCloudCreds().secretKey().set(Cypress.env('awsSecretKey'), true);
|
||||
cloudCredentialsPage.createEditCloudCreds().defaultRegion().checkOptionSelected('us-west-2');
|
||||
cloudCredentialsPage.createEditCloudCreds().saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials');
|
||||
cloudCredentialsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cloudCredentialsPage.list().details(`${ this.cloudCredentialName }-clone`, 1).should('be.visible');
|
||||
cloudCredentialsPage.list().details(`${ this.cloudCredentialName }-description-edit`, 3).should('be.visible');
|
||||
});
|
||||
|
||||
it('can delete cloud credentials', function() {
|
||||
CloudCredentialsPagePo.navTo();
|
||||
|
||||
// delete clone cloud credential
|
||||
cloudCredentialsPage.list().actionMenu(`${ this.cloudCredentialName }-clone`).getMenuItem('Delete').click();
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', '/v3/cloudCredentials/**').as('deleteCloudCred');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteCloudCred');
|
||||
cloudCredentialsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(`${ this.cloudCredentialName }-clone`).should('not.exist');
|
||||
});
|
||||
|
||||
it('can delete cloud credentials via bulk actions', function() {
|
||||
CloudCredentialsPagePo.navTo();
|
||||
|
||||
// delete original cloud credential
|
||||
cloudCredentialsPage.list().resourceTable().sortableTable().rowSelectCtlWithName(this.cloudCredentialName)
|
||||
.set();
|
||||
cloudCredentialsPage.list().resourceTable().sortableTable().deleteButton()
|
||||
.click();
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', '/v3/cloudCredentials/**').as('deleteCloudCred');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteCloudCred');
|
||||
cloudCredentialsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(this.cloudCredentialName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -18,7 +18,7 @@ import ClusterManagerCreateRke1CustomPagePo from '@/cypress/e2e/po/edit/provisio
|
|||
import Shell from '@/cypress/e2e/po/components/shell.po';
|
||||
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
|
||||
import { snapshot } from '@/cypress/e2e/blueprints/manager/cluster-snapshots';
|
||||
|
||||
import HomePagePo from '@/cypress/e2e/po/pages/home.po';
|
||||
// At some point these will come from somewhere central, then we can make tools to remove resources from this or all runs
|
||||
const runTimestamp = +new Date();
|
||||
const runPrefix = `e2e-test-${ runTimestamp }`;
|
||||
|
|
@ -394,6 +394,20 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
|
|||
});
|
||||
});
|
||||
|
||||
it('can navigate to Cluster Management Page', () => {
|
||||
HomePagePo.goTo();
|
||||
const burgerMenu = new BurgerMenuPo();
|
||||
|
||||
BurgerMenuPo.toggle();
|
||||
const clusterManagementNavItem = burgerMenu.links().contains(`Cluster Management`);
|
||||
|
||||
clusterManagementNavItem.should('exist');
|
||||
clusterManagementNavItem.click();
|
||||
const clusterList = new ClusterManagerListPagePo('_');
|
||||
|
||||
clusterList.waitForPage();
|
||||
});
|
||||
|
||||
it(`can navigate to local cluster's explore product`, () => {
|
||||
const clusterName = 'local';
|
||||
const clusterDashboard = new ClusterDashboardPagePo(clusterName);
|
||||
|
|
@ -404,6 +418,48 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
|
|||
clusterDashboard.waitForPage(undefined, 'cluster-events');
|
||||
});
|
||||
|
||||
it('can download YAML via bulk actions', () => {
|
||||
// Delete downloads directory. Need a fresh start to avoid conflicting file names
|
||||
cy.deleteDownloadsFolder();
|
||||
|
||||
ClusterManagerListPagePo.navTo();
|
||||
clusterList.list().resourceTable().sortableTable().rowElementWithName('local')
|
||||
.click();
|
||||
clusterList.list().openBulkActionDropdown();
|
||||
clusterList.list().bulkActionButton('Download YAML').click();
|
||||
const downloadedFilename = path.join(downloadsFolder, `local.yaml`);
|
||||
|
||||
cy.readFile(downloadedFilename).then((buffer) => {
|
||||
const obj: any = jsyaml.load(buffer);
|
||||
|
||||
// Basic checks on the downloaded YAML
|
||||
expect(obj.apiVersion).to.equal('provisioning.cattle.io/v1');
|
||||
expect(obj.metadata.name).to.equal('local');
|
||||
expect(obj.kind).to.equal('Cluster');
|
||||
});
|
||||
});
|
||||
|
||||
it('can download KubeConfig via bulk actions', () => {
|
||||
// Delete downloads directory. Need a fresh start to avoid conflicting file names
|
||||
cy.deleteDownloadsFolder();
|
||||
|
||||
ClusterManagerListPagePo.navTo();
|
||||
clusterList.list().resourceTable().sortableTable().rowElementWithName('local')
|
||||
.click();
|
||||
clusterList.list().openBulkActionDropdown();
|
||||
clusterList.list().bulkActionButton('Download KubeConfig').click();
|
||||
const downloadedFilename = path.join(downloadsFolder, 'local.yaml');
|
||||
|
||||
cy.readFile(downloadedFilename).then((buffer) => {
|
||||
const obj: any = jsyaml.load(buffer);
|
||||
|
||||
// Basic checks on the downloaded YAML
|
||||
expect(obj.apiVersion).to.equal('v1');
|
||||
expect(obj.clusters[0].name).to.equal('local');
|
||||
expect(obj.kind).to.equal('Config');
|
||||
});
|
||||
});
|
||||
|
||||
it('can connect to kubectl shell', () => {
|
||||
ClusterManagerListPagePo.navTo();
|
||||
clusterList.list().actionMenu('local').getMenuItem('Kubectl Shell').click();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
import RkeDriversPagePo from '@/cypress/e2e/po/pages/cluster-manager/rke-drivers.po';
|
||||
import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po';
|
||||
|
||||
describe('Drivers', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
const driversPage = new RkeDriversPagePo('_');
|
||||
const emberModal = new EmberModalPo();
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1440, 900);
|
||||
});
|
||||
|
||||
describe('Cluster Drivers', () => {
|
||||
it('can refresh kubernetes metadata', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.waitForPage();
|
||||
cy.intercept('POST', '/v3/kontainerdrivers?action=refresh').as('refresh');
|
||||
driversPage.refreshKubMetadata().click({ force: true });
|
||||
cy.wait('@refresh').its('response.statusCode').should('eq', 200);
|
||||
});
|
||||
|
||||
it('can create a cluster driver', () => {
|
||||
// see https://github.com/rancher-plugins/kontainer-engine-driver-example/releases for lsit of example drivers
|
||||
const downloadUrl = 'https://github.com/rancher-plugins/kontainer-engine-driver-example/releases/download/v0.2.3/kontainer-engine-driver-example-copy1-linux-amd64';
|
||||
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.addClusterDriver().click();
|
||||
driversPage.createEditClusterDriver().formInput(2).set(downloadUrl);
|
||||
cy.intercept('POST', '/v3/kontainerdriver').as('createDriver');
|
||||
driversPage.createEditClusterDriver().create();
|
||||
cy.wait('@createDriver').its('response.statusCode').should('eq', 201);
|
||||
driversPage.list().state('Example').should('contain.text', 'Active');
|
||||
});
|
||||
|
||||
it('can edit a cluster driver', () => {
|
||||
// see https://github.com/rancher-plugins/kontainer-engine-driver-example/releases for list of example drivers
|
||||
const downloadUrl = 'https://github.com/rancher-plugins/kontainer-engine-driver-example/releases/download/v0.2.3/kontainer-engine-driver-example-copy2-linux-amd64';
|
||||
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.list().rowActionMenuOpen(`Example`);
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Edit`);
|
||||
driversPage.createEditClusterDriver().formInput(2).set(downloadUrl);
|
||||
cy.intercept('PUT', '/v3/kontainerDrivers/*').as('updateDriver');
|
||||
driversPage.createEditClusterDriver().save();
|
||||
cy.wait('@updateDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Example').should('contain.text', 'Active');
|
||||
});
|
||||
|
||||
it('can deactivate a cluster driver', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.list().rowActionMenuOpen(`Example`);
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Deactivate`);
|
||||
cy.intercept('POST', '/v3/kontainerDrivers/*').as('deactivateDriver');
|
||||
emberModal.deactivate();
|
||||
cy.wait('@deactivateDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Example').should('contain.text', 'Inactive');
|
||||
});
|
||||
|
||||
it('can activate a cluster driver', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.list().rowActionMenuOpen(`Example`);
|
||||
cy.intercept('POST', '/v3/kontainerDrivers/*').as('activateDriver');
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Activate`);
|
||||
cy.wait('@activateDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Example').should('contain.text', 'Active');
|
||||
});
|
||||
|
||||
it('can delete a cluster driver', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.list().rowActionMenuOpen(`Example`);
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Delete`);
|
||||
cy.intercept('DELETE', '/v3/kontainerDrivers/*').as('deleteDriver');
|
||||
emberModal.delete();
|
||||
cy.wait('@deleteDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Example').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
// Note: This test fails due to https://github.com/rancher/dashboard/issues/10275
|
||||
// skipping this tests until issue has been resolved
|
||||
describe.skip('Node Drivers', () => {
|
||||
it('can delete an existing node driver', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
cy.intercept('GET', '/v3/nodedrivers?limit=-1&sort=name').as('nodeDrivers');
|
||||
driversPage.tabs('Node Drivers').should('be.visible').click();
|
||||
cy.wait('@nodeDrivers');
|
||||
|
||||
driversPage.list().rowActionMenuOpen(`Cloud.ca`);
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Delete`);
|
||||
cy.intercept('DELETE', '/v3/nodeDrivers/*').as('deleteDriver');
|
||||
emberModal.delete();
|
||||
cy.wait('@deleteDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Cloud.ca').should('not.exist');
|
||||
});
|
||||
|
||||
it('can create a node driver', () => {
|
||||
const downloadUrl = 'https://github.com/cloud-ca/docker-machine-driver-cloudca/files/2446837/docker-machine-driver-cloudca_v2.0.0_linux-amd64.zip';
|
||||
const customUrl = 'https://objects-east.cloud.ca/v1/5ef827605f884961b94881e928e7a250/ui-driver-cloudca/v2.1.2/component.js';
|
||||
const checksum = '2a55efd6d62d5f7fd27ce877d49596f4';
|
||||
const domain = 'objects-east.cloud.ca';
|
||||
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.tabs('Node Drivers').should('be.visible').click();
|
||||
driversPage.addNodeDriver().click();
|
||||
driversPage.createEditNodeDriver().formInput(2).set(downloadUrl);
|
||||
driversPage.createEditNodeDriver().formInput(3).set(customUrl);
|
||||
driversPage.createEditNodeDriver().formInput(4).set(checksum);
|
||||
driversPage.createEditNodeDriver().addDomainButton();
|
||||
driversPage.createEditNodeDriver().formInput(5).set(domain);
|
||||
cy.intercept('POST', '/v3/nodedriver').as('createNodeDriver');
|
||||
driversPage.createEditClusterDriver().create();
|
||||
cy.wait('@createNodeDriver').its('response.statusCode').should('eq', 201);
|
||||
driversPage.list().state('Cloud.ca').should('contain.text', 'Active');
|
||||
});
|
||||
|
||||
it('can edit a node driver', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.tabs('Node Drivers').should('be.visible').click();
|
||||
driversPage.list().rowActionMenuOpen(`Cloud.ca`);
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Edit`);
|
||||
cy.intercept('PUT', '/v3/nodeDrivers/*').as('updateDriver');
|
||||
driversPage.createEditClusterDriver().save();
|
||||
cy.wait('@updateDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Cloud.ca').should('contain.text', 'Active');
|
||||
});
|
||||
|
||||
it('can deactivate a node driver', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.tabs('Node Drivers').should('be.visible').click();
|
||||
driversPage.list().rowActionMenuOpen(`Cloud.ca`);
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Deactivate`);
|
||||
cy.intercept('POST', '/v3/nodeDrivers/**').as('deactivateDriver');
|
||||
emberModal.deactivate();
|
||||
cy.wait('@deactivateDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Cloud.ca').should('contain.text', 'Inactive');
|
||||
});
|
||||
|
||||
it('can activate a node driver', () => {
|
||||
RkeDriversPagePo.navTo();
|
||||
driversPage.tabs('Node Drivers').should('be.visible').click();
|
||||
driversPage.list().rowActionMenuOpen(`Cloud.ca`);
|
||||
cy.intercept('POST', '/v3/nodeDrivers/**').as('activateDriver');
|
||||
driversPage.actionMenu().selectMenuItemByLabel(`Activate`);
|
||||
cy.wait('@activateDriver').its('response.statusCode').should('eq', 200);
|
||||
driversPage.list().state('Cloud.ca').should('contain.text', 'Active');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
|
||||
import MachineDeploymentsPagePo from '@/cypress/e2e/po/pages/cluster-manager/machine-deployments.po';
|
||||
import * as path from 'path';
|
||||
import * as jsyaml from 'js-yaml';
|
||||
|
||||
describe('MachineDeployments', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
const machineDeploymentsPage = new MachineDeploymentsPagePo('_');
|
||||
const nsName = 'default';
|
||||
let resourceVersion = '';
|
||||
let creationTimestamp = '';
|
||||
let time = '';
|
||||
let uid = '';
|
||||
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('machinedeployments').as('machineDeploymentsName');
|
||||
});
|
||||
|
||||
it('can create a MachineDeployments', function() {
|
||||
MachineDeploymentsPagePo.navTo();
|
||||
machineDeploymentsPage.waitForPage();
|
||||
|
||||
machineDeploymentsPage.create();
|
||||
|
||||
machineDeploymentsPage.createEditMachineDeployment().waitForPage('as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machine-deployments.yml').then((machineDeploymentDoc) => {
|
||||
// convert yaml into json to update name value
|
||||
const json: any = jsyaml.load(machineDeploymentDoc);
|
||||
|
||||
json.metadata.name = this.machineDeploymentsName;
|
||||
machineDeploymentsPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('POST', '/v1/cluster.x-k8s.io.machinedeployments').as('createMachineDeployment');
|
||||
machineDeploymentsPage.createEditMachineDeployment().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@createMachineDeployment').then((req) => {
|
||||
resourceVersion = req.response?.body.metadata.resourceVersion;
|
||||
creationTimestamp = req.response?.body.metadata.creationTimestamp;
|
||||
time = req.response?.body.metadata.managedFields[0].time;
|
||||
uid = req.response?.body.metadata.uid;
|
||||
});
|
||||
machineDeploymentsPage.waitForPage();
|
||||
machineDeploymentsPage.list().details(this.machineDeploymentsName, 1).should('be.visible');
|
||||
});
|
||||
|
||||
it('can edit a MachineDeployments', function() {
|
||||
MachineDeploymentsPagePo.navTo();
|
||||
|
||||
machineDeploymentsPage.list().actionMenu(this.machineDeploymentsName).getMenuItem('Edit YAML').click();
|
||||
machineDeploymentsPage.createEditMachineDeployment(nsName, this.machineDeploymentsName).waitForPage('mode=edit&as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machine-deployments-edit.yml').then((machineSetDoc) => {
|
||||
// convert yaml into json to update values
|
||||
const json: any = jsyaml.load(machineSetDoc);
|
||||
|
||||
json.spec.template.spec.bootstrap.dataSecretName = 'secretName2';
|
||||
json.metadata.creationTimestamp = creationTimestamp;
|
||||
json.metadata.managedFields.time = time;
|
||||
json.metadata.uid = uid;
|
||||
json.metadata.name = this.machineDeploymentsName;
|
||||
json.metadata.resourceVersion = resourceVersion;
|
||||
machineDeploymentsPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('PUT', `/v1/cluster.x-k8s.io.machinedeployments/${ nsName }/${ this.machineDeploymentsName }`).as('updateMachineSet');
|
||||
machineDeploymentsPage.createEditMachineDeployment().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@updateMachineSet').its('response.statusCode').should('eq', 200);
|
||||
machineDeploymentsPage.waitForPage();
|
||||
|
||||
// check details page
|
||||
machineDeploymentsPage.list().details(this.machineDeploymentsName, 2).find('a').click();
|
||||
cy.contains('secretName2').scrollIntoView().should('be.visible');
|
||||
});
|
||||
|
||||
it('can clone a MachineDeployments', function() {
|
||||
MachineDeploymentsPagePo.navTo();
|
||||
|
||||
machineDeploymentsPage.list().actionMenu(this.machineDeploymentsName).getMenuItem('Clone').click();
|
||||
machineDeploymentsPage.createEditMachineDeployment(nsName, this.machineDeploymentsName).waitForPage('mode=clone&as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machine-deployments.yml').then((machineSetDoc) => {
|
||||
// convert yaml into json to update name value
|
||||
const json: any = jsyaml.load(machineSetDoc);
|
||||
|
||||
json.metadata.name = `${ this.machineDeploymentsName }-clone`;
|
||||
machineDeploymentsPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('POST', 'v1/cluster.x-k8s.io.machinedeployments').as('cloneMachineSet');
|
||||
machineDeploymentsPage.createEditMachineDeployment().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@cloneMachineSet').its('response.statusCode').should('eq', 201);
|
||||
machineDeploymentsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
machineDeploymentsPage.list().details(`${ this.machineDeploymentsName }-clone`, 2).should('be.visible');
|
||||
});
|
||||
|
||||
it('can download YAML', function() {
|
||||
MachineDeploymentsPagePo.navTo();
|
||||
machineDeploymentsPage.list().actionMenu(this.machineDeploymentsName).getMenuItem('Download YAML').click();
|
||||
|
||||
const downloadedFilename = path.join(downloadsFolder, `${ this.machineDeploymentsName }.yaml`);
|
||||
|
||||
cy.readFile(downloadedFilename).then((buffer) => {
|
||||
const obj: any = jsyaml.load(buffer);
|
||||
|
||||
// Basic checks on the downloaded YAML
|
||||
expect(obj.apiVersion).to.equal('cluster.x-k8s.io/v1beta1');
|
||||
expect(obj.metadata.name).to.equal(this.machineDeploymentsName);
|
||||
expect(obj.kind).to.equal('MachineDeployment');
|
||||
});
|
||||
});
|
||||
|
||||
it('can delete a MachineDeployments', function() {
|
||||
MachineDeploymentsPagePo.navTo();
|
||||
|
||||
// delete original cloned MachineSet
|
||||
machineDeploymentsPage.list().actionMenu(`${ this.machineDeploymentsName }-clone`).getMenuItem('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', `v1/cluster.x-k8s.io.machinedeployments/${ nsName }/${ this.machineDeploymentsName }-clone`).as('deleteMachineSet');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteMachineSet');
|
||||
machineDeploymentsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(`${ this.machineDeploymentsName }-clone`).should('not.exist');
|
||||
});
|
||||
|
||||
it('can delete MachineDeployments via bulk actions', function() {
|
||||
MachineDeploymentsPagePo.navTo();
|
||||
|
||||
// delete original MachineSet
|
||||
machineDeploymentsPage.list().resourceTable().sortableTable().rowSelectCtlWithName(`${ this.machineDeploymentsName }`)
|
||||
.set();
|
||||
machineDeploymentsPage.list().openBulkActionDropdown();
|
||||
|
||||
cy.intercept('DELETE', `v1/cluster.x-k8s.io.machinedeployments/${ nsName }/${ this.machineDeploymentsName }`).as('deleteMachineSet');
|
||||
machineDeploymentsPage.list().bulkActionButton('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteMachineSet');
|
||||
machineDeploymentsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(this.machineDeploymentsName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
|
||||
import MachineSetsPagePo from '@/cypress/e2e/po/pages/cluster-manager/machine-sets.po';
|
||||
import * as path from 'path';
|
||||
import * as jsyaml from 'js-yaml';
|
||||
|
||||
describe('MachineSets', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
const machineSetsPage = new MachineSetsPagePo('_');
|
||||
const nsName = 'default';
|
||||
let resourceVersion = '';
|
||||
let creationTimestamp = '';
|
||||
let time = '';
|
||||
let uid = '';
|
||||
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('machinesets').as('machineSetName');
|
||||
});
|
||||
|
||||
it('can create a MachineSet', function() {
|
||||
MachineSetsPagePo.navTo();
|
||||
machineSetsPage.waitForPage();
|
||||
machineSetsPage.create();
|
||||
|
||||
machineSetsPage.createEditMachineSet().waitForPage('as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machine-sets.yml').then((machineSetDoc) => {
|
||||
// convert yaml into json to update name value
|
||||
const json: any = jsyaml.load(machineSetDoc);
|
||||
|
||||
json.metadata.name = this.machineSetName;
|
||||
machineSetsPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('POST', '/v1/cluster.x-k8s.io.machinesets').as('createMachineSet');
|
||||
machineSetsPage.createEditMachineSet().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@createMachineSet').then((req) => {
|
||||
resourceVersion = req.response?.body.metadata.resourceVersion;
|
||||
creationTimestamp = req.response?.body.metadata.creationTimestamp;
|
||||
time = req.response?.body.metadata.managedFields[0].time;
|
||||
uid = req.response?.body.metadata.uid;
|
||||
});
|
||||
machineSetsPage.waitForPage();
|
||||
machineSetsPage.list().details(this.machineSetName, 1).should('be.visible');
|
||||
});
|
||||
|
||||
it('can edit a MachineSet', function() {
|
||||
MachineSetsPagePo.navTo();
|
||||
machineSetsPage.list().actionMenu(this.machineSetName).getMenuItem('Edit YAML').click();
|
||||
machineSetsPage.createEditMachineSet(nsName, this.machineSetName).waitForPage('mode=edit&as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machine-sets-edit.yml').then((machineSetDoc) => {
|
||||
// convert yaml into json to update values
|
||||
const json: any = jsyaml.load(machineSetDoc);
|
||||
|
||||
json.spec.template.spec.bootstrap.dataSecretName = 'secretName2';
|
||||
json.metadata.creationTimestamp = creationTimestamp;
|
||||
json.metadata.managedFields.time = time;
|
||||
json.metadata.uid = uid;
|
||||
json.metadata.name = this.machineSetName;
|
||||
json.metadata.resourceVersion = resourceVersion;
|
||||
machineSetsPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('PUT', `/v1/cluster.x-k8s.io.machinesets/${ nsName }/${ this.machineSetName }`).as('updateMachineSet');
|
||||
machineSetsPage.createEditMachineSet().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@updateMachineSet').its('response.statusCode').should('eq', 200);
|
||||
machineSetsPage.waitForPage();
|
||||
|
||||
// check details page
|
||||
machineSetsPage.list().details(this.machineSetName, 2).find('a').click();
|
||||
cy.contains('secretName2').should('be.visible');
|
||||
});
|
||||
|
||||
it('can clone a MachineSet', function() {
|
||||
MachineSetsPagePo.navTo();
|
||||
machineSetsPage.list().actionMenu(this.machineSetName).getMenuItem('Clone').click();
|
||||
machineSetsPage.createEditMachineSet(nsName, this.machineSetName).waitForPage('mode=clone&as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machine-sets.yml').then((machineSetDoc) => {
|
||||
// convert yaml into json to update name value
|
||||
const json: any = jsyaml.load(machineSetDoc);
|
||||
|
||||
json.metadata.name = `${ this.machineDeploymentsName }-clone`;
|
||||
machineSetsPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('POST', '/v1/cluster.x-k8s.io.machinesets').as('cloneMachineSet');
|
||||
machineSetsPage.createEditMachineSet().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@cloneMachineSet').its('response.statusCode').should('eq', 201);
|
||||
machineSetsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
machineSetsPage.list().details(`${ this.machineDeploymentsName }-clone`, 2).should('be.visible');
|
||||
});
|
||||
|
||||
it('can download YAML', function() {
|
||||
MachineSetsPagePo.navTo();
|
||||
machineSetsPage.list().actionMenu(this.machineSetName).getMenuItem('Download YAML').click();
|
||||
|
||||
const downloadedFilename = path.join(downloadsFolder, `${ this.machineSetName }.yaml`);
|
||||
|
||||
cy.readFile(downloadedFilename).then((buffer) => {
|
||||
const obj: any = jsyaml.load(buffer);
|
||||
|
||||
// Basic checks on the downloaded YAML
|
||||
expect(obj.apiVersion).to.equal('cluster.x-k8s.io/v1beta1');
|
||||
expect(obj.metadata.name).to.equal(this.machineSetName);
|
||||
expect(obj.kind).to.equal('MachineSet');
|
||||
});
|
||||
});
|
||||
|
||||
it('can delete a MachineSet', function() {
|
||||
MachineSetsPagePo.navTo();
|
||||
|
||||
// delete original cloned MachineSet
|
||||
machineSetsPage.list().actionMenu(`${ this.machineDeploymentsName }-clone`).getMenuItem('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', `v1/cluster.x-k8s.io.machinesets/${ nsName }/${ this.machineDeploymentsName }-clone`).as('deleteMachineSet');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteMachineSet');
|
||||
machineSetsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(`${ this.machineDeploymentsName }-clone`).should('not.exist');
|
||||
});
|
||||
|
||||
it('can delete MachineSet via bulk actions', function() {
|
||||
MachineSetsPagePo.navTo();
|
||||
|
||||
// delete original MachineSet
|
||||
machineSetsPage.list().resourceTable().sortableTable().rowSelectCtlWithName(this.machineSetName)
|
||||
.set();
|
||||
machineSetsPage.list().openBulkActionDropdown();
|
||||
|
||||
cy.intercept('DELETE', `v1/cluster.x-k8s.io.machinesets/${ nsName }/${ this.machineSetName }`).as('deleteMachineSet');
|
||||
machineSetsPage.list().bulkActionButton('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteMachineSet');
|
||||
machineSetsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(this.machineSetName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
|
||||
import MachinesPagePo from '@/cypress/e2e/po/pages/cluster-manager/machines.po';
|
||||
import * as path from 'path';
|
||||
import * as jsyaml from 'js-yaml';
|
||||
|
||||
describe('Machines', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
const machinesPage = new MachinesPagePo('_');
|
||||
const nsName = 'default';
|
||||
let resourceVersion = '';
|
||||
let creationTimestamp = '';
|
||||
let time = '';
|
||||
let uid = '';
|
||||
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('machines').as('machineName');
|
||||
});
|
||||
|
||||
it('can create a Machine', function() {
|
||||
MachinesPagePo.navTo();
|
||||
machinesPage.waitForPage();
|
||||
machinesPage.create();
|
||||
|
||||
machinesPage.createEditMachines().waitForPage('as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machines.yml').then((machineDoc) => {
|
||||
// convert yaml into json to update name value
|
||||
const json: any = jsyaml.load(machineDoc);
|
||||
|
||||
json.metadata.name = this.machineName;
|
||||
json.metadata.namespace = nsName;
|
||||
json.spec.bootstrap.clusterName = 'local';
|
||||
json.spec.bootstrap.dataSecretName = 'secretName';
|
||||
|
||||
machinesPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('POST', '/v1/cluster.x-k8s.io.machines').as('createMachine');
|
||||
machinesPage.createEditMachines().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@createMachine').then((req) => {
|
||||
resourceVersion = req.response?.body.metadata.resourceVersion;
|
||||
creationTimestamp = req.response?.body.metadata.creationTimestamp;
|
||||
time = req.response?.body.metadata.managedFields[0].time;
|
||||
uid = req.response?.body.metadata.uid;
|
||||
});
|
||||
machinesPage.waitForPage();
|
||||
machinesPage.list().details(this.machineName, 1).should('be.visible');
|
||||
});
|
||||
|
||||
it('can edit a Machine', function() {
|
||||
MachinesPagePo.navTo();
|
||||
machinesPage.list().actionMenu(this.machineName).getMenuItem('Edit YAML').click();
|
||||
machinesPage.createEditMachines(nsName, this.machineName).waitForPage('mode=edit&as=yaml');
|
||||
|
||||
cy.readFile('cypress/e2e/blueprints/cluster_management/machines-edit.yml').then((machineDoc) => {
|
||||
// convert yaml into json to update values
|
||||
const json: any = jsyaml.load(machineDoc);
|
||||
|
||||
json.spec.bootstrap.dataSecretName = 'secretName2';
|
||||
json.metadata.creationTimestamp = creationTimestamp;
|
||||
json.metadata.managedFields.time = time;
|
||||
json.metadata.uid = uid;
|
||||
json.metadata.name = this.machineName;
|
||||
json.metadata.resourceVersion = resourceVersion;
|
||||
machinesPage.yamlEditor().set(jsyaml.dump(json));
|
||||
});
|
||||
|
||||
cy.intercept('PUT', `/v1/cluster.x-k8s.io.machines/${ nsName }/${ this.machineName }`).as('updateMachine');
|
||||
machinesPage.createEditMachines().saveCreateForm().resourceYaml().saveOrCreate()
|
||||
.click();
|
||||
cy.wait('@updateMachine').its('response.statusCode').should('eq', 200);
|
||||
machinesPage.waitForPage();
|
||||
|
||||
// check details page
|
||||
machinesPage.list().details(this.machineName, 2).find('a').click();
|
||||
cy.contains('secretName2').should('be.visible');
|
||||
});
|
||||
|
||||
it('can download YAML', function() {
|
||||
MachinesPagePo.navTo();
|
||||
machinesPage.list().actionMenu(this.machineName).getMenuItem('Download YAML').click();
|
||||
|
||||
const downloadedFilename = path.join(downloadsFolder, `${ this.machineName }.yaml`);
|
||||
|
||||
cy.readFile(downloadedFilename).then((buffer) => {
|
||||
const obj: any = jsyaml.load(buffer);
|
||||
|
||||
// Basic checks on the downloaded YAML
|
||||
expect(obj.apiVersion).to.equal('cluster.x-k8s.io/v1beta1');
|
||||
expect(obj.metadata.name).to.equal(this.machineName);
|
||||
expect(obj.kind).to.equal('Machine');
|
||||
});
|
||||
});
|
||||
|
||||
it('can delete a Machine', function() {
|
||||
MachinesPagePo.navTo();
|
||||
machinesPage.list().actionMenu(this.machineName).getMenuItem('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', `v1/cluster.x-k8s.io.machines/${ nsName }/${ this.machineName }`).as('deleteCloudCred');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteCloudCred');
|
||||
machinesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(this.machineName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
|
||||
import NodeTemplatesPagePo from '@/cypress/e2e/po/pages/cluster-manager/node-templates.po';
|
||||
import ClusterManagerCreateRke1Amazonec2PagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke1-amazonec2.po';
|
||||
import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po';
|
||||
|
||||
// will only run this in jenkins pipeline where cloud credentials are stored
|
||||
describe('Node Templates', { testIsolation: 'off', tags: ['@manager', '@jenkins', '@adminUser'] }, () => {
|
||||
const nodeTemplatesPage = new NodeTemplatesPagePo('_');
|
||||
const clusterList = new ClusterManagerListPagePo('local');
|
||||
let cloudCredentialId = '';
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('nodeTemplates').as('nodeTemplateName');
|
||||
cy.createE2EResourceName('cloudCredential').as('cloudCredentialName');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1380, 720);
|
||||
});
|
||||
|
||||
let removeCloudCred = false;
|
||||
|
||||
it('can create a node template for Amazon EC2 and should display on RKE1 cluster creation page', function() {
|
||||
cy.createAwsCloudCredentials('fleet-default', this.cloudCredentialName, 'us-west-2', Cypress.env('awsAccessKey'), Cypress.env('awsSecretKey')).then((resp: Cypress.Response<any>) => {
|
||||
cloudCredentialId = resp.body.id;
|
||||
removeCloudCred = true;
|
||||
});
|
||||
|
||||
NodeTemplatesPagePo.navTo();
|
||||
nodeTemplatesPage.waitForPage();
|
||||
nodeTemplatesPage.addTemplate().click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().serviceProviderOptions('Amazon EC2').should('have.class', 'active');
|
||||
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Authenticate & configure nodes').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().accordion().content().find('.radio .acc-label')
|
||||
.eq(0)
|
||||
.click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Select a Security Group').should('exist');
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Select a Security Group').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().accordion().content().contains('.radio label', 'Choose one or more existing groups')
|
||||
.click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().serviceProviderOptions('Amazon EC2').should('have.class', 'active');
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Set Instance options').click();
|
||||
|
||||
nodeTemplatesPage.addNodeTemplateModal().templateName().set(this.nodeTemplateName);
|
||||
cy.intercept('POST', '/v3/nodetemplate').as('createTemplate');
|
||||
|
||||
nodeTemplatesPage.addNodeTemplateModal().create();
|
||||
cy.wait('@createTemplate');
|
||||
nodeTemplatesPage.waitForPage();
|
||||
nodeTemplatesPage.list().rowWithName(this.nodeTemplateName).should('be.visible');
|
||||
|
||||
// check RKE template displays as an option on the RKE cluster create page
|
||||
clusterList.goTo();
|
||||
clusterList.checkIsCurrentPage();
|
||||
clusterList.createCluster();
|
||||
|
||||
const createClusterRKE1Page = new ClusterManagerCreateRke1Amazonec2PagePo();
|
||||
|
||||
createClusterRKE1Page.waitForPage();
|
||||
createClusterRKE1Page.rkeToggle().set('RKE1');
|
||||
createClusterRKE1Page.selectCreate(0);
|
||||
createClusterRKE1Page.nodeTemplateDropdown().selectMenuItemByOption(this.nodeTemplateName);
|
||||
createClusterRKE1Page.selectedOption().checkOptionSelected(this.nodeTemplateName);
|
||||
});
|
||||
|
||||
it('can edit a node template', function() {
|
||||
NodeTemplatesPagePo.navTo();
|
||||
nodeTemplatesPage.list().rowWithName(this.nodeTemplateName).should('be.visible');
|
||||
nodeTemplatesPage.list().rowActionMenuOpen(this.nodeTemplateName);
|
||||
nodeTemplatesPage.list().actionMenu().selectMenuItemByLabel('Edit');
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Authenticate & configure nodes').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Select a Security Group').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Set Instance options').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().templateName().set(`${ this.nodeTemplateName }-edit`);
|
||||
cy.intercept('PUT', '/v3/nodeTemplates/**').as('editTemplate');
|
||||
|
||||
nodeTemplatesPage.addNodeTemplateModal().save();
|
||||
cy.wait('@editTemplate');
|
||||
nodeTemplatesPage.waitForPage();
|
||||
nodeTemplatesPage.list().rowWithName(`${ this.nodeTemplateName }-edit`).should('be.visible');
|
||||
});
|
||||
|
||||
it('can clone a node template', function() {
|
||||
NodeTemplatesPagePo.navTo();
|
||||
nodeTemplatesPage.list().rowWithName(`${ this.nodeTemplateName }-edit`).should('be.visible');
|
||||
nodeTemplatesPage.list().rowActionMenuOpen(`${ this.nodeTemplateName }-edit`);
|
||||
nodeTemplatesPage.list().actionMenu().selectMenuItemByLabel('Clone');
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Authenticate & configure nodes').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Select a Security Group').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().nextButton('Next: Set Instance options').click();
|
||||
nodeTemplatesPage.addNodeTemplateModal().templateName().set(`${ this.nodeTemplateName }-clone`);
|
||||
cy.intercept('POST', '/v3/nodetemplate').as('cloneTemplate');
|
||||
|
||||
nodeTemplatesPage.addNodeTemplateModal().save();
|
||||
cy.wait('@cloneTemplate');
|
||||
nodeTemplatesPage.waitForPage();
|
||||
nodeTemplatesPage.list().rowWithName(`${ this.nodeTemplateName }-clone`).should('be.visible');
|
||||
});
|
||||
|
||||
it('can delete a node template', function() {
|
||||
NodeTemplatesPagePo.navTo();
|
||||
|
||||
// delete clone node template
|
||||
nodeTemplatesPage.list().rowWithName(`${ this.nodeTemplateName }-clone`).should('be.visible');
|
||||
nodeTemplatesPage.list().rowActionMenuOpen(`${ this.nodeTemplateName }-clone`);
|
||||
nodeTemplatesPage.list().actionMenu().selectMenuItemByLabel('Delete');
|
||||
const promptRemove = new EmberModalPo();
|
||||
|
||||
cy.intercept('DELETE', '/v3/nodeTemplates/**').as('deleteNodeTemplate');
|
||||
|
||||
promptRemove.delete();
|
||||
cy.wait('@deleteNodeTemplate');
|
||||
nodeTemplatesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(`${ this.nodeTemplateName }-clone`).should('not.exist');
|
||||
});
|
||||
|
||||
it('can delete a node template via bulk actions', function() {
|
||||
NodeTemplatesPagePo.navTo();
|
||||
|
||||
// delete original node template
|
||||
nodeTemplatesPage.list().rowWithName(`${ this.nodeTemplateName }-edit`).click();
|
||||
nodeTemplatesPage.list().bulkActions('Delete').click();
|
||||
const promptRemove = new EmberModalPo();
|
||||
|
||||
cy.intercept('DELETE', '/v3/nodeTemplates/**').as('deleteNodeTemplate');
|
||||
|
||||
promptRemove.delete();
|
||||
cy.wait('@deleteNodeTemplate');
|
||||
nodeTemplatesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(`${ this.nodeTemplateName }-edit`).should('not.exist');
|
||||
});
|
||||
|
||||
after('clean up', () => {
|
||||
if (removeCloudCred) {
|
||||
// delete cloud cred
|
||||
cy.deleteRancherResource('v3', 'cloudCredentials', cloudCredentialId);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
import PodSecurityAdmissionsPagePo from '@/cypress/e2e/po/pages/cluster-manager/pod-security-admissions.po';
|
||||
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
|
||||
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
|
||||
import * as path from 'path';
|
||||
import * as jsyaml from 'js-yaml';
|
||||
import { createPayloadData, updatePayloadData } from '@/cypress/e2e/blueprints/cluster_management/pod-security-admissions-payload';
|
||||
|
||||
describe('Pod Security Admissions', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
const podSecurityAdmissionsPage = new PodSecurityAdmissionsPagePo('_');
|
||||
const resourceDetails = new ResourceDetailPo('.main-layout');
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('podsecurityadmissions').as('podSecurityAdmissionsName');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1380, 720);
|
||||
});
|
||||
|
||||
it('can create a policy security admission', function() {
|
||||
PodSecurityAdmissionsPagePo.navTo();
|
||||
podSecurityAdmissionsPage.waitForPage();
|
||||
podSecurityAdmissionsPage.create();
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().waitForPage();
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().nameNsDescription().name().set(this.podSecurityAdmissionsName);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().nameNsDescription().description().set(`${ this.podSecurityAdmissionsName }-description`);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlLevel(0, 1);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlLevel(1, 2);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlLevel(2, 3);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlVersion(0, 'latest');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlVersion(1, 'latest');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlVersion(2, 'latest');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsCheckbox(0);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsInput(0, 'admin,user');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsCheckbox(1);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsInput(1, 'myclass1,myclass2');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsCheckbox(2);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsInput(2, 'ingress-nginx,kube-system');
|
||||
resourceDetails.cruResource().saveAndWaitForRequests('POST', '/v1/management.cattle.io.podsecurityadmissionconfigurationtemplates').then(({ request, response }) => {
|
||||
expect(response?.statusCode).to.eq(201);
|
||||
expect(request?.body.configuration.defaults).to.deep.include(createPayloadData.configuration.defaults);
|
||||
expect(response?.body.configuration.defaults).to.deep.include(createPayloadData.configuration.defaults);
|
||||
expect(request?.body.configuration.exemptions).to.deep.include(createPayloadData.configuration.exemptions);
|
||||
expect(response?.body.configuration.exemptions).to.deep.include(createPayloadData.configuration.exemptions);
|
||||
});
|
||||
podSecurityAdmissionsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
podSecurityAdmissionsPage.list().details(this.podSecurityAdmissionsName, 1).should('be.visible');
|
||||
});
|
||||
|
||||
it('can edit a policy security admission', function() {
|
||||
PodSecurityAdmissionsPagePo.navTo();
|
||||
podSecurityAdmissionsPage.list().actionMenu(this.podSecurityAdmissionsName).getMenuItem('Edit Config').click();
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm(this.podSecurityAdmissionsName).waitForPage('mode=edit');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().nameNsDescription().description().set(`${ this.podSecurityAdmissionsName }-description-edit`);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlLevel(0, 1);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlLevel(1, 2);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlLevel(2, 3);
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlVersion(0, 'v1.25');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlVersion(1, 'v1.25');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().psaControlVersion(2, 'v1.25');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsInput(0, 'admin1,user1');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsInput(1, 'myclass3,myclass4');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().setExemptionsInput(2, 'cattle-system,cattle-epinio-system');
|
||||
resourceDetails.cruResource().saveAndWaitForRequests('PUT', '/v1/management.cattle.io.podsecurityadmissionconfigurationtemplates/**').then(({ request, response }) => {
|
||||
expect(response?.statusCode).to.eq(200);
|
||||
expect(request?.body.configuration.defaults).to.deep.include(updatePayloadData.configuration.defaults);
|
||||
expect(response?.body.configuration.defaults).to.deep.include(updatePayloadData.configuration.defaults);
|
||||
expect(request?.body.configuration.exemptions).to.deep.include(updatePayloadData.configuration.exemptions);
|
||||
expect(response?.body.configuration.exemptions).to.deep.include(updatePayloadData.configuration.exemptions);
|
||||
});
|
||||
podSecurityAdmissionsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
podSecurityAdmissionsPage.list().details(`${ this.podSecurityAdmissionsName }-description-edit`, 1).should('be.visible');
|
||||
});
|
||||
|
||||
it('can clone a policy security admission', function() {
|
||||
PodSecurityAdmissionsPagePo.navTo();
|
||||
podSecurityAdmissionsPage.list().actionMenu(this.podSecurityAdmissionsName).getMenuItem('Clone').click();
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm(this.podSecurityAdmissionsName).waitForPage('mode=clone');
|
||||
podSecurityAdmissionsPage.createPodSecurityAdmissionForm().nameNsDescription().name().set(`${ this.podSecurityAdmissionsName }-clone`);
|
||||
resourceDetails.cruResource().saveAndWaitForRequests('POST', '/v1/management.cattle.io.podsecurityadmissionconfigurationtemplates');
|
||||
podSecurityAdmissionsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
podSecurityAdmissionsPage.list().details(`${ this.podSecurityAdmissionsName }-clone`, 1).should('be.visible');
|
||||
});
|
||||
|
||||
it('can download YAML for a policy security admission', function() {
|
||||
PodSecurityAdmissionsPagePo.navTo();
|
||||
podSecurityAdmissionsPage.list().actionMenu(this.podSecurityAdmissionsName).getMenuItem('Download YAML').click();
|
||||
|
||||
const downloadedFilename = path.join(downloadsFolder, `${ this.podSecurityAdmissionsName }.yaml`);
|
||||
|
||||
cy.readFile(downloadedFilename).then((buffer) => {
|
||||
const obj: any = jsyaml.load(buffer);
|
||||
|
||||
// Basic checks on the downloaded YAML
|
||||
expect(obj.apiVersion).to.equal('management.cattle.io/v3');
|
||||
expect(obj.metadata.name).to.equal(this.podSecurityAdmissionsName);
|
||||
expect(obj.kind).to.equal('PodSecurityAdmissionConfigurationTemplate');
|
||||
});
|
||||
});
|
||||
|
||||
it('can delete a policy security admission', function() {
|
||||
PodSecurityAdmissionsPagePo.navTo();
|
||||
podSecurityAdmissionsPage.list().actionMenu(`${ this.podSecurityAdmissionsName }-clone`).getMenuItem('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', `/v1/management.cattle.io.podsecurityadmissionconfigurationtemplates/${ this.podSecurityAdmissionsName }-clone`).as('deletePolicyAdmission');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deletePolicyAdmission');
|
||||
podSecurityAdmissionsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(`${ this.podSecurityAdmissionsName }-clone`).should('not.exist');
|
||||
});
|
||||
|
||||
it('can delete a policy security admission via bulk actions', function() {
|
||||
PodSecurityAdmissionsPagePo.navTo();
|
||||
podSecurityAdmissionsPage.list().details(this.podSecurityAdmissionsName, 0).click();
|
||||
podSecurityAdmissionsPage.list().resourceTable().sortableTable().deleteButton()
|
||||
.click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', `/v1/management.cattle.io.podsecurityadmissionconfigurationtemplates/${ this.podSecurityAdmissionsName }`).as('deletePolicyAdmission');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deletePolicyAdmission');
|
||||
podSecurityAdmissionsPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(this.podSecurityAdmissionsName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import PodSecurityPoliciesTemplatesPagePo from '@/cypress/e2e/po/pages/cluster-manager/pod-security-policy-templates.po';
|
||||
import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po';
|
||||
|
||||
describe.skip('Pod Security Policy Templates', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
// Note: this test fails due to https://github.com/rancher/dashboard/issues/10187
|
||||
// skipping these tests until issue is resolved
|
||||
const podSecurityTemplatesPage = new PodSecurityPoliciesTemplatesPagePo('_');
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('podsecuritytemplate').as('podSecurityTemplateName');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1380, 720);
|
||||
});
|
||||
|
||||
it('can create a policy template', function() {
|
||||
PodSecurityPoliciesTemplatesPagePo.navTo();
|
||||
podSecurityTemplatesPage.waitForPage();
|
||||
podSecurityTemplatesPage.addPolicyTemplate().click();
|
||||
podSecurityTemplatesPage.addPodSecurityTemplateForm().templateName().set(this.podSecurityTemplateName);
|
||||
cy.intercept('POST', '/v3/podsecuritypolicytemplate').as('createPolicyTemplate');
|
||||
podSecurityTemplatesPage.addPodSecurityTemplateForm().create();
|
||||
cy.wait('@createPolicyTemplate');
|
||||
|
||||
// check list details
|
||||
podSecurityTemplatesPage.list().rowWithName(this.podSecurityTemplateName).should('be.visible');
|
||||
});
|
||||
|
||||
it('can edit a policy template', function() {
|
||||
PodSecurityPoliciesTemplatesPagePo.navTo();
|
||||
podSecurityTemplatesPage.list().rowActionMenuOpen(this.podSecurityTemplateName);
|
||||
podSecurityTemplatesPage.actionMenu().selectMenuItemByLabel('Edit');
|
||||
|
||||
// update template by adding a description
|
||||
podSecurityTemplatesPage.addPodSecurityTemplateForm().addDescription();
|
||||
podSecurityTemplatesPage.addPodSecurityTemplateForm().templateDescription().set(`${ this.podSecurityTemplateName }-description`);
|
||||
cy.intercept('PUT', '/v3/podSecurityPolicyTemplates/**').as('updatePolicyTemplate');
|
||||
podSecurityTemplatesPage.addPodSecurityTemplateForm().save();
|
||||
cy.wait('@updatePolicyTemplate');
|
||||
|
||||
podSecurityTemplatesPage.list().rowWithName(this.podSecurityTemplateName).find('a').click();
|
||||
|
||||
podSecurityTemplatesPage.templateDescription(`${ this.podSecurityTemplateName }-description`).should('be.visible');
|
||||
});
|
||||
|
||||
it('can delete a policy template', function() {
|
||||
PodSecurityPoliciesTemplatesPagePo.navTo();
|
||||
podSecurityTemplatesPage.list().rowActionMenuOpen(this.podSecurityTemplateName);
|
||||
podSecurityTemplatesPage.actionMenu().selectMenuItemByLabel('Delete');
|
||||
|
||||
const promptRemove = new EmberModalPo();
|
||||
|
||||
cy.intercept('DELETE', '/v3/podSecurityPolicyTemplates/**').as('deletePolicyTemplate');
|
||||
promptRemove.delete();
|
||||
cy.wait('@deletePolicyTemplate');
|
||||
podSecurityTemplatesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(this.podSecurityTemplateName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
|
||||
import ChartRepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
|
||||
import * as path from 'path';
|
||||
import * as jsyaml from 'js-yaml';
|
||||
|
||||
describe('Cluster Management Helm Repositories', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
const repositoriesPage = new ChartRepositoriesPagePo('_', 'manager');
|
||||
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('repo').as('repoName');
|
||||
});
|
||||
|
||||
it('can create a repository', function() {
|
||||
ChartRepositoriesPagePo.navTo();
|
||||
repositoriesPage.waitForPage();
|
||||
repositoriesPage.waitForGoTo('/v1/catalog.cattle.io.clusterrepos?exclude=metadata.managedFields');
|
||||
repositoriesPage.create();
|
||||
repositoriesPage.createEditRepositories().waitForPage();
|
||||
repositoriesPage.createEditRepositories().nameNsDescription().name().set(this.repoName);
|
||||
repositoriesPage.createEditRepositories().nameNsDescription().description().set(`${ this.repoName }-description`);
|
||||
repositoriesPage.createEditRepositories().repoRadioBtn().set(1);
|
||||
repositoriesPage.createEditRepositories().gitRepoUrl().set('https://git.rancher.io/charts');
|
||||
repositoriesPage.createEditRepositories().gitBranch().set('release-v2.8');
|
||||
repositoriesPage.createEditRepositories().saveAndWaitForRequests('POST', '/v1/catalog.cattle.io.clusterrepos');
|
||||
repositoriesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
repositoriesPage.list().details(this.repoName, 2).should('be.visible');
|
||||
repositoriesPage.list().details(this.repoName, 1).contains('In Progress').should('be.visible');
|
||||
repositoriesPage.list().details(this.repoName, 1).contains('Active').should('be.visible');
|
||||
});
|
||||
|
||||
it('can refresh a repository', function() {
|
||||
ChartRepositoriesPagePo.navTo();
|
||||
cy.intercept('PUT', `/v1/catalog.cattle.io.clusterrepos/${ this.repoName }`).as('refreshRepo');
|
||||
repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Refresh').click();
|
||||
cy.wait('@refreshRepo').its('response.statusCode').should('eq', 200);
|
||||
|
||||
// check list details
|
||||
repositoriesPage.list().details(this.repoName, 1).contains('In Progress').should('be.visible');
|
||||
repositoriesPage.list().details(this.repoName, 1).contains('Active').should('be.visible');
|
||||
});
|
||||
|
||||
it('can edit a repository', function() {
|
||||
ChartRepositoriesPagePo.navTo();
|
||||
repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Edit Config').click();
|
||||
repositoriesPage.createEditRepositories(this.repoName).waitForPage('mode=edit');
|
||||
repositoriesPage.createEditRepositories().nameNsDescription().description().set(`${ this.repoName }-desc-edit`);
|
||||
repositoriesPage.createEditRepositories().saveAndWaitForRequests('PUT', `/v1/catalog.cattle.io.clusterrepos/${ this.repoName }`);
|
||||
repositoriesPage.waitForPage();
|
||||
|
||||
// check details page
|
||||
repositoriesPage.list().details(this.repoName, 2).click();
|
||||
cy.contains(`${ this.repoName }-desc-edit`).should('be.visible');
|
||||
});
|
||||
|
||||
it('can clone a repository', function() {
|
||||
ChartRepositoriesPagePo.navTo();
|
||||
repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Clone').click();
|
||||
repositoriesPage.createEditRepositories(this.repoName).waitForPage('mode=clone');
|
||||
repositoriesPage.createEditRepositories().nameNsDescription().name().set(`${ this.repoName }-clone`);
|
||||
repositoriesPage.createEditRepositories().nameNsDescription().description().set(`${ this.repoName }-desc-clone`);
|
||||
repositoriesPage.createEditRepositories().saveAndWaitForRequests('POST', '/v1/catalog.cattle.io.clusterrepos');
|
||||
repositoriesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
repositoriesPage.list().details(`${ this.repoName }-clone`, 2).should('be.visible');
|
||||
});
|
||||
|
||||
it('can download YAML', function() {
|
||||
ChartRepositoriesPagePo.navTo();
|
||||
repositoriesPage.list().actionMenu(this.repoName).getMenuItem('Download YAML').click();
|
||||
|
||||
const downloadedFilename = path.join(downloadsFolder, `${ this.repoName }.yaml`);
|
||||
|
||||
cy.readFile(downloadedFilename).then((buffer) => {
|
||||
const obj: any = jsyaml.load(buffer);
|
||||
|
||||
// Basic checks on the downloaded YAML
|
||||
expect(obj.apiVersion).to.equal('catalog.cattle.io/v1');
|
||||
expect(obj.metadata.name).to.equal(this.repoName);
|
||||
expect(obj.kind).to.equal('ClusterRepo');
|
||||
});
|
||||
});
|
||||
|
||||
it('can delete a repository', function() {
|
||||
ChartRepositoriesPagePo.navTo();
|
||||
|
||||
// delete original cloned Repository
|
||||
repositoriesPage.list().actionMenu(`${ this.repoName }-clone`).getMenuItem('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
cy.intercept('DELETE', `v1/catalog.cattle.io.clusterrepos/${ this.repoName }-clone`).as('deleteRepository');
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteRepository');
|
||||
repositoriesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(`${ this.repoName }-clone`).should('not.exist');
|
||||
});
|
||||
|
||||
it('can delete a repository via bulk actions', function() {
|
||||
ChartRepositoriesPagePo.navTo();
|
||||
|
||||
// delete original Repository
|
||||
repositoriesPage.list().resourceTable().sortableTable().rowSelectCtlWithName(this.repoName)
|
||||
.set();
|
||||
repositoriesPage.list().openBulkActionDropdown();
|
||||
|
||||
cy.intercept('DELETE', `v1/catalog.cattle.io.clusterrepos/${ this.repoName }`).as('deleteRepository');
|
||||
repositoriesPage.list().bulkActionButton('Delete').click();
|
||||
|
||||
const promptRemove = new PromptRemove();
|
||||
|
||||
promptRemove.remove();
|
||||
cy.wait('@deleteRepository');
|
||||
repositoriesPage.waitForPage();
|
||||
|
||||
// check list details
|
||||
cy.contains(this.repoName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
|
||||
import ClusterManagerCreateRke1CustomPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke1-custom.po';
|
||||
import RkeTemplatesPagePo from '@/cypress/e2e/po/pages/cluster-manager/rke-templates.po';
|
||||
import EmberModalPo from '@/cypress/e2e/po/components/ember/ember-modal.po';
|
||||
|
||||
describe('RKE Templates', { testIsolation: 'off', tags: ['@manager', '@adminUser'] }, () => {
|
||||
const rkeTemplatesPage = new RkeTemplatesPagePo('_');
|
||||
const clusterList = new ClusterManagerListPagePo('local');
|
||||
const promptRemove = new EmberModalPo();
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.createE2EResourceName('rkeTemplate').as('rkeTemplateName');
|
||||
cy.createE2EResourceName('rkeRevision').as('rkeRevisionName');
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1380, 720);
|
||||
});
|
||||
|
||||
it('can create RKE template and should display on RKE1 cluster creation page', function() {
|
||||
RkeTemplatesPagePo.navTo();
|
||||
rkeTemplatesPage.waitForPage();
|
||||
rkeTemplatesPage.addTemplate().click();
|
||||
rkeTemplatesPage.form().templateDetails(3).set(this.rkeTemplateName);
|
||||
rkeTemplatesPage.form().templateDetails(2).set(this.rkeRevisionName);
|
||||
cy.intercept('POST', '/v3/clustertemplate').as('createTemplate');
|
||||
rkeTemplatesPage.form().create();
|
||||
cy.wait('@createTemplate');
|
||||
rkeTemplatesPage.waitForPage();
|
||||
rkeTemplatesPage.groupRow().groupRowWithName(this.rkeTemplateName).should('be.visible');
|
||||
rkeTemplatesPage.groupRow().rowWithinGroupByName(this.rkeTemplateName, this.rkeRevisionName).should('be.visible');
|
||||
|
||||
// check RKE template displays as an option on the RKE custom cluster create page
|
||||
clusterList.goTo();
|
||||
clusterList.checkIsCurrentPage();
|
||||
clusterList.createCluster();
|
||||
|
||||
const createClusterRKE1Page = new ClusterManagerCreateRke1CustomPagePo();
|
||||
|
||||
createClusterRKE1Page.waitForPage();
|
||||
|
||||
createClusterRKE1Page.rkeToggle().set('RKE1');
|
||||
createClusterRKE1Page.selectCustom(0);
|
||||
createClusterRKE1Page.clusterTemplateCheckbox().set();
|
||||
createClusterRKE1Page.rkeTemplateAndRevisionDropdown().selectMenuItemByOption(this.rkeTemplateName);
|
||||
createClusterRKE1Page.selectedOption().checkOptionSelected(this.rkeTemplateName);
|
||||
createClusterRKE1Page.selectedOption().checkOptionSelected(this.rkeRevisionName, 1);
|
||||
});
|
||||
|
||||
it('can disable RKE template revision', function() {
|
||||
RkeTemplatesPagePo.navTo();
|
||||
rkeTemplatesPage.mainRow().rowActionMenuOpen(this.rkeRevisionName);
|
||||
cy.intercept('POST', '/v3/clusterTemplateRevisions/*').as('disableTemplateRevision');
|
||||
rkeTemplatesPage.actionMenu().selectMenuItemByLabel('Disable');
|
||||
cy.wait('@disableTemplateRevision');
|
||||
rkeTemplatesPage.mainRow().state(this.rkeRevisionName).contains('Active').should('not.exist');
|
||||
rkeTemplatesPage.mainRow().state(this.rkeRevisionName).should('contain.text', 'Disabled');
|
||||
});
|
||||
|
||||
it('can enable RKE template revision', function() {
|
||||
RkeTemplatesPagePo.navTo();
|
||||
rkeTemplatesPage.mainRow().rowActionMenuOpen(this.rkeRevisionName);
|
||||
cy.intercept('POST', '/v3/clusterTemplateRevisions/*').as('enableTemplateRevision');
|
||||
rkeTemplatesPage.actionMenu().selectMenuItemByLabel('Enable');
|
||||
cy.wait('@enableTemplateRevision');
|
||||
rkeTemplatesPage.mainRow().state(this.rkeRevisionName).contains('Disabled').should('not.exist');
|
||||
rkeTemplatesPage.mainRow().state(this.rkeRevisionName).should('contain.text', 'Active');
|
||||
});
|
||||
|
||||
it('can clone RKE template revision', function() {
|
||||
RkeTemplatesPagePo.navTo();
|
||||
rkeTemplatesPage.groupRow().groupRowWithName(this.rkeTemplateName).should('be.visible');
|
||||
rkeTemplatesPage.mainRow().rowActionMenuOpen(this.rkeRevisionName);
|
||||
rkeTemplatesPage.actionMenu().selectMenuItemByLabel('Clone Revision');
|
||||
rkeTemplatesPage.form().templateDetails(2).set(`${ this.rkeRevisionName }-2`);
|
||||
cy.intercept('PUT', '/v3/clusterTemplates/*').as('cloneTemplateRevision');
|
||||
rkeTemplatesPage.form().save();
|
||||
cy.wait('@cloneTemplateRevision');
|
||||
rkeTemplatesPage.groupRow().rowWithinGroupByName(this.rkeTemplateName, `${ this.rkeRevisionName }-2`);
|
||||
});
|
||||
|
||||
it('can delete RKE template revision', function() {
|
||||
RkeTemplatesPagePo.navTo();
|
||||
rkeTemplatesPage.mainRow().rowActionMenuOpen(`${ this.rkeRevisionName }-2`);
|
||||
rkeTemplatesPage.actionMenu().selectMenuItemByLabel(`Delete`);
|
||||
cy.intercept('DELETE', '/v3/clusterTemplateRevisions/*').as('deleteTemplateRevision');
|
||||
promptRemove.delete();
|
||||
cy.wait('@deleteTemplateRevision').its('response.statusCode').should('eq', 204);
|
||||
rkeTemplatesPage.mainRow().rowWithName(`${ this.rkeRevisionName }-2`).should('not.exist');
|
||||
});
|
||||
|
||||
it('can delete RKE template group', function() {
|
||||
RkeTemplatesPagePo.navTo();
|
||||
rkeTemplatesPage.groupRow().groupRowActionMenuOpen(this.rkeTemplateName);
|
||||
rkeTemplatesPage.actionMenu().selectMenuItemByLabel(`Delete`);
|
||||
cy.intercept('DELETE', '/v3/clusterTemplates/*').as('deleteTemplate');
|
||||
promptRemove.delete();
|
||||
cy.wait('@deleteTemplate').its('response.statusCode').should('eq', 204);
|
||||
rkeTemplatesPage.groupRow().groupRowWithName(this.rkeTemplateName).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import BannersPo from '@/cypress/e2e/po/components/banners.po';
|
||||
import HomePagePo from '@/cypress/e2e/po/pages/home.po';
|
||||
import PreferencesPagePo from '@/cypress/e2e/po/pages/preferences.po';
|
||||
import ReposListPagePo from '@/cypress/e2e/po/pages/repositories.po';
|
||||
import UserMenuPo from '@/cypress/e2e/po/side-bars/user-menu.po';
|
||||
import RepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
|
||||
// import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
|
||||
|
||||
const userMenu = new UserMenuPo();
|
||||
const prefPage = new PreferencesPagePo();
|
||||
const repoListPage = new ReposListPagePo('_', 'manager');
|
||||
const repoListPage = new RepositoriesPagePo('_', 'manager');
|
||||
const repoList = repoListPage.list();
|
||||
// const clusterManagerPage = new ClusterManagerListPagePo('_');
|
||||
|
||||
|
|
@ -360,9 +360,9 @@ describe('User can update their preferences', () => {
|
|||
Validate http request's payload & response contain correct values per selection
|
||||
*/
|
||||
const buttonOptions = {
|
||||
'Normal human': 'sublime',
|
||||
Emacs: 'emacs',
|
||||
Vim: 'vim',
|
||||
'Normal human': 'sublime'
|
||||
};
|
||||
|
||||
prefPage.goTo();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ declare global {
|
|||
login(username?: string, password?: string, cacheSession?: boolean): Chainable<Element>;
|
||||
logout(): Chainable;
|
||||
byLabel(label: string): Chainable<Element>;
|
||||
createE2EResourceName(context: string): Chainable<Element>;
|
||||
|
||||
createUser(params: CreateUserParams): Chainable;
|
||||
setGlobalRoleBinding(userId: string, role: string): Chainable;
|
||||
|
|
@ -38,6 +39,7 @@ declare global {
|
|||
createProject(projName: string, clusterId: string, userId: string): Chainable;
|
||||
createNamespace(nsName: string, projId: string): Chainable;
|
||||
createPod(nsName: string, podName: string, image: string): Chainable;
|
||||
createAwsCloudCredentials(nsName: string, cloudCredName: string, defaultRegion: string, accessKey: string, secretKey: string): Chainable;
|
||||
|
||||
getRancherResource(prefix: 'v3' | 'v1', resourceType: string, resourceId?: string, expectedStatusCode?: number): Chainable;
|
||||
setRancherResource(prefix: 'v3' | 'v1', resourceType: string, resourceId: string, body: string): Chainable;
|
||||
|
|
|
|||
|
|
@ -59,3 +59,12 @@ Cypress.Commands.add('iFrame', () => {
|
|||
.should('not.be.empty')
|
||||
.then((body) => cy.wrap(body));
|
||||
});
|
||||
|
||||
/**
|
||||
* Create resource name
|
||||
*/
|
||||
const runTimestamp = +new Date();
|
||||
|
||||
Cypress.Commands.add('createE2EResourceName', (context) => {
|
||||
return cy.wrap(`e2e-test-${ runTimestamp }-${ context }`);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -299,6 +299,34 @@ Cypress.Commands.add('createPod', (nsName, podName, image) => {
|
|||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* create aws cloud credentials
|
||||
*/
|
||||
Cypress.Commands.add('createAwsCloudCredentials', (nsName, cloudCredName, defaultRegion, accessKey, secretKey) => {
|
||||
return cy.request({
|
||||
method: 'POST',
|
||||
url: `${ Cypress.env('api') }/v3/cloudcredentials`,
|
||||
headers: {
|
||||
'x-api-csrf': token.value,
|
||||
Accept: 'application/json'
|
||||
},
|
||||
body: {
|
||||
type: 'provisioning.cattle.io/cloud-credential',
|
||||
metadata: { generateName: 'cc-', namespace: `${ nsName }` },
|
||||
_name: `${ cloudCredName }`,
|
||||
annotations: { 'provisioning.cattle.io/driver': 'aws' },
|
||||
amazonec2credentialConfig: {
|
||||
defaultRegion: `${ defaultRegion }`, accessKey: `${ accessKey }`, secretKey: `${ secretKey }`
|
||||
},
|
||||
_type: 'provisioning.cattle.io/cloud-credential',
|
||||
name: `${ cloudCredName }`
|
||||
}
|
||||
})
|
||||
.then((resp) => {
|
||||
expect(resp.status).to.eq(201);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Override user preferences to default values, allowing to pass custom preferences for a deterministic scenario
|
||||
*/
|
||||
|
|
@ -395,7 +423,7 @@ Cypress.Commands.add('setRancherResource', (prefix, resourceType, resourceId, bo
|
|||
/**
|
||||
* delete a v3 / v1 resource
|
||||
*/
|
||||
Cypress.Commands.add('deleteRancherResource', (prefix, resourceType, resourceId) => {
|
||||
Cypress.Commands.add('deleteRancherResource', (prefix, resourceType, resourceId, expectedStatusCode = 200) => {
|
||||
return cy.request({
|
||||
method: 'DELETE',
|
||||
url: `${ Cypress.env('api') }/${ prefix }/${ resourceType }/${ resourceId }`,
|
||||
|
|
|
|||
Loading…
Reference in New Issue