Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

automation: fleet cluster groups tests #13088

Merged
merged 1 commit into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cypress/e2e/po/components/create-edit-view.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ export default class CreateEditViewPo extends ComponentPo {
saveButtonPo() :AsyncButtonPo {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary'));
}

editAsYaml() {
return new AsyncButtonPo(this.self().find('[data-testid="form-yaml"]')).click();
}
}
30 changes: 19 additions & 11 deletions cypress/e2e/po/edit/fleet/fleet.cattle.io.clustergroup.po.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
import CodeMirrorPo from '@/cypress/e2e/po/components/code-mirror.po';

import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po';
export default class FleetClusterGroupsCreateEditPo extends PagePo {
private static createPath(clusterId: string, id?: string ) {
const root = `/c/${ clusterId }/explorer/storage.k8s.io.storageclass/create`;
private static createPath(clusterId: string, workspace?: string, id?: string ) {
const root = `/c/${ clusterId }/fleet/fleet.cattle.io.clustergroup`;

return id ? `${ root }/${ id }` : `${ root }/create`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
}

static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}

constructor(clusterId = '_', id?: string) {
super(FleetClusterGroupsCreateEditPo.createPath(clusterId, id));
constructor(clusterId = '_', workspace?: string, id?: string) {
super(FleetClusterGroupsCreateEditPo.createPath(clusterId, workspace, id));
}

title() {
return this.self().get('.title .primaryheader h1');
}

nameNsDescription() {
return new NameNsDescription(this.self());
}

editAsYaml() {
return new AsyncButtonPo('[data-testid="form-yaml"]', this.self());
saveCreateForm(): ResourceDetailPo {
return new ResourceDetailPo(this.self());
}

yamlEditor(): CodeMirrorPo {
return CodeMirrorPo.bySelector(this.self(), '[data-testid="yaml-editor-code-mirror"]');
saveButton() {
return new AsyncButtonPo('[data-testid="form-save"]', this.self());
}
}
16 changes: 9 additions & 7 deletions cypress/e2e/po/pages/fleet/fleet.cattle.io.clustergroup.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
import FleetClusterGroupsList from '@/cypress/e2e/po/lists/fleet/fleet.cattle.io.clustergroup';
import FleetClusterGroupsCreateEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.clustergroup.po';
export class FleetClusterGroupsListPagePo extends PagePo {
static url = `/c/_/fleet/fleet.cattle.io.clustergroup`
private static createPath(clusterId: string) {
return `/c/${ clusterId }/fleet/fleet.cattle.io.clustergroup`;
}

constructor() {
super(FleetClusterGroupsListPagePo.url);
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(FleetClusterGroupsListPagePo.createPath(clusterId));
}

goTo() {
return cy.visit(FleetClusterGroupsListPagePo.url);
constructor(private clusterId = '_') {
super(FleetClusterGroupsListPagePo.createPath(clusterId));
}

static navTo() {
Expand Down Expand Up @@ -44,7 +46,7 @@ export class FleetClusterGroupsListPagePo extends PagePo {
return this.self().find('[data-testid="masthead-create"]').click();
}

createFleetClusterGroupsForm(id? : string): FleetClusterGroupsCreateEditPo {
return new FleetClusterGroupsCreateEditPo(id);
createFleetClusterGroupsForm(workspace?: string, id? : string): FleetClusterGroupsCreateEditPo {
return new FleetClusterGroupsCreateEditPo(this.clusterId, workspace, id);
}
}
166 changes: 125 additions & 41 deletions cypress/e2e/tests/pages/fleet/cluster-groups.spec.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,147 @@
import { FleetClusterGroupsListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.clustergroup.po';
import FleetClusterGroupDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.clustergroup.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';

describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetClusterGroups = new FleetClusterGroupsListPagePo();
const headerPo = new HeaderPo();
const localWorkspace = 'fleet-local';
let clusterGroupName;
let removeClusterGroups = false;
const clusterGroupsToDelete = [];

describe('List', { tags: ['@vai', '@adminUser'] }, () => {
before(() => {
cy.login();
before(() => {
cy.login();
cy.createE2EResourceName('cluster-group').then((name) => {
clusterGroupName = name;
});
});

it('check table headers are available in list and details view', () => {
const groupName = 'default';
const workspace = 'fleet-local';
it('can create cluster group', () => {
FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.clickCreate();
fleetClusterGroups.createFleetClusterGroupsForm().waitForPage();

FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
headerPo.selectWorkspace(workspace);
fleetClusterGroups.clusterGroupsList().rowWithName(groupName).checkVisible();
fleetClusterGroups.createFleetClusterGroupsForm().nameNsDescription().name().set(clusterGroupName);
fleetClusterGroups.createFleetClusterGroupsForm().saveCreateForm().cruResource().saveOrCreate()
.click()
.then(() => {
removeClusterGroups = true;
clusterGroupsToDelete.push(`${ localWorkspace }/${ clusterGroupName }`);
});

// check table headers
const expectedHeaders = ['State', 'Name', 'Clusters Ready', 'Resources', 'Age'];
fleetClusterGroups.waitForPage();
fleetClusterGroups.clusterGroupsList().details(clusterGroupName, 1).should('be.visible');
});

fleetClusterGroups.clusterGroupsList().resourceTable().sortableTable().tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeaders[i]);
});
it('can edit a cluster group', () => {
FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.clusterGroupsList().actionMenu(clusterGroupName).getMenuItem('Edit Config').click();
fleetClusterGroups.createFleetClusterGroupsForm(localWorkspace, clusterGroupName).waitForPage('mode=edit');
fleetClusterGroups.createFleetClusterGroupsForm().nameNsDescription().description().set(`${ clusterGroupName }-fleet-desc`);
fleetClusterGroups.createFleetClusterGroupsForm().saveCreateForm().cruResource().saveAndWaitForRequests('PUT', `v1/fleet.cattle.io.clustergroups/${ localWorkspace }/${ clusterGroupName }`)
.then(({ response }) => {
expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata).to.have.property('name', clusterGroupName);
expect(response?.body.metadata.annotations).to.have.property('field.cattle.io/description', `${ clusterGroupName }-fleet-desc`);
});
fleetClusterGroups.waitForPage();
});

// go to fleet cluster details
fleetClusterGroups.goToDetailsPage(groupName);
it('can clone a cluster group', () => {
FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.clusterGroupsList().actionMenu(clusterGroupName).getMenuItem('Clone').click();
fleetClusterGroups.createFleetClusterGroupsForm(localWorkspace, clusterGroupName).waitForPage('mode=clone');
fleetClusterGroups.createFleetClusterGroupsForm().nameNsDescription().name().set(`clone-${ clusterGroupName }`);
fleetClusterGroups.createFleetClusterGroupsForm().nameNsDescription().description().set(`${ clusterGroupName }-fleet-desc`);
fleetClusterGroups.createFleetClusterGroupsForm().saveCreateForm().cruResource().saveAndWaitForRequests('POST', 'v1/fleet.cattle.io.clustergroups')
.then(({ response }) => {
expect(response?.statusCode).to.eq(201);
removeClusterGroups = true;
clusterGroupsToDelete.push(`${ localWorkspace }/clone-${ clusterGroupName }`);
expect(response?.body.metadata).to.have.property('name', `clone-${ clusterGroupName }`);
expect(response?.body.metadata.annotations).to.have.property('field.cattle.io/description', `${ clusterGroupName }-fleet-desc`);
});
fleetClusterGroups.waitForPage();
fleetClusterGroups.clusterGroupsList().details(`clone-${ clusterGroupName }`, 1).should('be.visible');
});

const fleetClusterGroupDetailsPage = new FleetClusterGroupDetailsPo(workspace, groupName);
it('can delete cluster group', () => {
FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.clusterGroupsList().actionMenu(clusterGroupName).getMenuItem('Delete').click();
fleetClusterGroups.clusterGroupsList().resourceTable().sortableTable().rowNames('.col-link-detail')
.then((rows: any) => {
const promptRemove = new PromptRemove();

fleetClusterGroupDetailsPage.waitForPage(null, 'clusters');
cy.intercept('DELETE', `v1/fleet.cattle.io.clustergroups/${ localWorkspace }/clone-${ clusterGroupName }`).as('deleteClusterGroup');

// check table headers
const expectedHeadersDetailsView = ['State', 'Name', 'Bundles Ready', 'Repos Ready', 'Resources', 'Last Seen', 'Age'];
promptRemove.remove();
cy.wait('@deleteClusterGroup');
fleetClusterGroups.waitForPage();
fleetClusterGroups.clusterGroupsList().resourceTable().sortableTable().checkRowCount(false, rows.length - 1);
fleetClusterGroups.clusterGroupsList().resourceTable().sortableTable().rowNames('.col-link-detail')
.should('not.contain', `clone-${ clusterGroupName }`);
});
});

fleetClusterGroupDetailsPage.clusterList().resourceTable().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeadersDetailsView[i]);
});
});
// testing https://github.com/rancher/dashboard/issues/11687
it('can open "Edit as YAML"', () => {
FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
fleetClusterGroups.clickCreate();
fleetClusterGroups.createFleetClusterGroupsForm().saveCreateForm().createEditView().editAsYaml();
fleetClusterGroups.createFleetClusterGroupsForm().saveCreateForm().resourceYaml().codeMirror()
.checkExists();
});
describe('Edit', { tags: ['@vai', '@adminUser'] }, () => {
before(() => {
cy.login();
});

it('can open "Edit as YAML"', () => {
FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
fleetClusterGroups.clickCreate();
fleetClusterGroups.createFleetClusterGroupsForm().editAsYaml().click();
fleetClusterGroups.createFleetClusterGroupsForm().yamlEditor().checkExists();
});
it('check table headers are available in list and details view', { tags: ['@vai', '@adminUser'] }, () => {
const groupName = 'default';

FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.clusterGroupsList().rowWithName(groupName).checkVisible();

// check table headers
const expectedHeaders = ['State', 'Name', 'Clusters Ready', 'Resources', 'Age'];

fleetClusterGroups.clusterGroupsList().resourceTable().sortableTable().tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeaders[i]);
});

// go to fleet cluster details
fleetClusterGroups.goToDetailsPage(groupName);

const fleetClusterGroupDetailsPage = new FleetClusterGroupDetailsPo(localWorkspace, groupName);

fleetClusterGroupDetailsPage.waitForPage(null, 'clusters');

// check table headers
const expectedHeadersDetailsView = ['State', 'Name', 'Bundles Ready', 'Repos Ready', 'Resources', 'Last Seen', 'Age'];

fleetClusterGroupDetailsPage.clusterList().resourceTable().sortableTable()
.tableHeaderRow()
.within('.table-header-container .content')
.each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeadersDetailsView[i]);
});
});

after(() => {
if (removeClusterGroups) {
// delete gitrepo
clusterGroupsToDelete.forEach((r) => cy.deleteRancherResource('v1', 'fleet.cattle.io.clustergroups', r, false));
}
});
});
5 changes: 4 additions & 1 deletion cypress/e2e/tests/pages/fleet/dashboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import FleetGitRepoDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io
import { GitRepoCreatePo } from '@/cypress/e2e/po/pages/fleet/gitrepo-create.po';
import { GitRepoEditPo } from '@/cypress/e2e/po/edit/fleet/gitrepo-edit.po';
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
import { LONG_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import { LONG_TIMEOUT_OPT, MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import { gitRepoTargetAllClustersRequest } from '@/cypress/e2e/blueprints/fleet/gitrepos';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import { MenuActions } from '@/cypress/support/types/menu-actions';
Expand Down Expand Up @@ -118,11 +118,14 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
it('can clone a git repo', () => {
const gitRepoEditPage = new GitRepoEditPo(localWorkspace, repoName);

cy.intercept('GET', '/v1/secrets?exclude=metadata.managedFields').as('getSecrets');

fleetDashboardPage.goTo();
fleetDashboardPage.waitForPage();
fleetDashboardPage.sortableTable().rowActionMenuOpen(repoName).getMenuItem('Clone').click();

gitRepoEditPage.waitForPage('mode=clone');
cy.wait('@getSecrets', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
gitRepoEditPage.title().contains(`Git Repo: Clone from ${ repoName }`).should('be.visible');
headerPo.selectWorkspace('fleet-default');
gitRepoEditPage.nameNsDescription().name().set(`clone-${ repoName }`);
Expand Down
Loading