Merge remote-tracking branch 'upstream/master' into pagination-depaginate

This commit is contained in:
Richard Cox 2025-05-28 11:09:25 +01:00
commit 20e7af3e59
168 changed files with 3883 additions and 2041 deletions

View File

@ -28,3 +28,4 @@ Fixes #
- [ ] The PR has a reviewer assigned - [ ] The PR has a reviewer assigned
- [ ] The PR has automated tests or clear instructions for manual tests and the linked issue has appropriate QA labels, or tests are not needed - [ ] The PR has automated tests or clear instructions for manual tests and the linked issue has appropriate QA labels, or tests are not needed
- [ ] The PR has reviewed with UX and tested in light and dark mode, or there are no UX changes - [ ] The PR has reviewed with UX and tested in light and dark mode, or there are no UX changes
- [ ] The PR has been reviewed in terms of Accessibility

View File

@ -15,6 +15,9 @@ const GH_PRJ_TO_TEST = 'To Test';
const GH_PRJ_QA_REVIEW = 'QA Review'; const GH_PRJ_QA_REVIEW = 'QA Review';
const GH_PRJ_IN_REVIEW = 'Review'; const GH_PRJ_IN_REVIEW = 'Review';
// This label is used so that PRs from dependabot don't fail the check for 'fixes' notation
const GH_DEPENDENCIES_LABEL = 'area/dependencies';
function parseOrgAndRepo(repoUrl) { function parseOrgAndRepo(repoUrl) {
const parts = repoUrl.split('/'); const parts = repoUrl.split('/');
@ -267,6 +270,14 @@ async function processOpenOrEditAction() {
console.log('+ This PR fixes issues: #' + issues.join(', ')); console.log('+ This PR fixes issues: #' + issues.join(', '));
} else { } else {
console.log("+ This PR does not fix any issues"); console.log("+ This PR does not fix any issues");
// PRs must fix an issue or have the label 'QA/None'
if (!hasLabel(pr, QA_NONE_LABEL) && !hasLabel(pr, GH_DEPENDENCIES_LABEL)) {
console.log('Error: A PR MUST either declare which issues it fixes OR must have the QA/None label');
process.exit(1);
}
console.log('Allowing PR to proceed without being linked to an issue because of the labels on the PR');
} }
const milestones = {}; const milestones = {};

View File

@ -0,0 +1,63 @@
// original eks default attributes are declared in @/pkg/eks/components/CruEKS.vue. This file is a typescript file to be consumed by cypress. Any changes in the default values must also be updated here.
export const DEFAULT_CLUSTER = {
dockerRootDir: '/var/lib/docker',
enableClusterAlerting: false,
enableClusterMonitoring: false,
enableNetworkPolicy: false,
labels: {},
annotations: {},
windowsPreferedCluster: false,
fleetAgentDeploymentCustomization: {},
clusterAgentDeploymentCustomization: {}
};
export const DEFAULT__IMPORT_CLUSTER = {
dockerRootDir: '/var/lib/docker',
enableNetworkPolicy: false,
labels: {},
annotations: {},
windowsPreferedCluster: false,
fleetAgentDeploymentCustomization: {},
clusterAgentDeploymentCustomization: {},
eksConfig: {
amazonCredentialSecret: '',
displayName: '',
imported: true,
region: ''
}
};
export const DEFAULT_REGION = 'us-west-2';
export const DEFAULT_NODE_GROUP_CONFIG = {
desiredSize: '2',
diskSize: '20',
ec2SshKey: '',
gpu: false,
imageId: null,
instanceType: 't3.medium',
labels: {},
maxSize: '2',
minSize: '2',
nodegroupName: 'group1',
nodeRole: 'Default (One will be created automatically)',
requestSpotInstances: false,
resourceTags: {},
spotInstanceTypes: [],
subnets: [],
tags: {},
type: 'nodeGroup',
userData: '',
_isNew: true,
};
export const DEFAULT_EKS_CONFIG = {
publicAccess: true,
privateAccess: false,
publicAccessSources: [],
secretsEncryption: false,
securityGroups: [],
tags: {},
subnets: [],
loggingTypes: [],
};

View File

@ -1,5 +1,5 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po'; import ComponentPo from '@/cypress/e2e/po/components/component.po';
import BaseResourceList from '~/cypress/e2e/po/lists/base-resource-list.po'; import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
export default class CertificatesPo extends ComponentPo { export default class CertificatesPo extends ComponentPo {
constructor() { constructor() {

View File

@ -7,14 +7,22 @@ export default class CreateEditViewPo extends ComponentPo {
return new NameNsDescription(this.self()); return new NameNsDescription(this.self());
} }
createButton() {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary'));
}
create() { create() {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary')).click(); return this.createButton().click();
} }
save() { save() {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary')).click(); return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary')).click();
} }
cancel() {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-secondary')).click();
}
saveAndWait() { saveAndWait() {
return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary')).action('Save', 'Saved'); return new AsyncButtonPo(this.self().find('.cru-resource-footer .role-primary')).action('Save', 'Saved');
} }

View File

@ -2,6 +2,10 @@ import ComponentPo from '@/cypress/e2e/po/components/component.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po'; import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
export default class CruResourcePo extends ComponentPo { export default class CruResourcePo extends ComponentPo {
findSubTypeByName(name: string) {
return this.self().find(`[data-testid="subtype-banner-item-${ name }"]`);
}
selectSubType(groupIndex: number, itemIndex: number) { selectSubType(groupIndex: number, itemIndex: number) {
return this.self().find('.subtypes-container > div') return this.self().find('.subtypes-container > div')
.eq(groupIndex).find('.item') .eq(groupIndex).find('.item')
@ -17,6 +21,10 @@ export default class CruResourcePo extends ComponentPo {
return new AsyncButtonPo('[data-testid="form-save"]', this.self()); return new AsyncButtonPo('[data-testid="form-save"]', this.self());
} }
cancel(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="form-cancel"]', this.self());
}
saveAndWaitForRequests(method, endpoint: string, statusCode?: number): Cypress.Chainable { saveAndWaitForRequests(method, endpoint: string, statusCode?: number): Cypress.Chainable {
cy.intercept(method, endpoint).as(endpoint); cy.intercept(method, endpoint).as(endpoint);
this.saveOrCreate().click(); this.saveOrCreate().click();

View File

@ -0,0 +1,12 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po';
import { CypressChainable } from '@/cypress/e2e/po/po.types';
export default class DialogPo extends ComponentPo {
constructor(selector = '#modal-container-element') {
super(selector);
}
getActionButton(): CypressChainable {
return this.self().get('.dialog-buttons');
}
}

View File

@ -22,6 +22,10 @@ export class ImportYamlPo extends ComponentPo {
this.self().find('[data-testid="import-yaml-close"]').click(); this.self().find('[data-testid="import-yaml-close"]').click();
} }
importYamlCancelClick() {
this.self().find('[data-testid="import-yaml-cancel"]').click();
}
importYamlSortableTable() { importYamlSortableTable() {
return new SortableTablePo(this.self()); return new SortableTablePo(this.self());
} }

View File

@ -1,5 +1,4 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po'; import ComponentPo from '@/cypress/e2e/po/components/component.po';
export default class LabeledSelectPo extends ComponentPo { export default class LabeledSelectPo extends ComponentPo {
toggle() { toggle() {
return this.self().click(); return this.self().click();
@ -38,6 +37,12 @@ export default class LabeledSelectPo extends ComponentPo {
}); });
} }
checkContainsOptionSelected(label: string): Cypress.Chainable {
return this.self().find('.vs__selected-options > span.vs__selected').should((elm) => {
expect(elm.text().trim()).to.include(label);
});
}
/** /**
* Get dropdown options * Get dropdown options
* @returns * @returns

View File

@ -13,4 +13,25 @@ export default class ResourceTablePo extends ComponentPo {
snapshotNowButton() { snapshotNowButton() {
return cy.get('[data-testid="action-button-async-button"').last(); return cy.get('[data-testid="action-button-async-button"').last();
} }
/**
* Returns a specific table column value for a row with the given name
* @param name
* @param index
* @returns
*/
resourceTableDetails(name: string, index: number) {
return this.sortableTable().rowWithName(name)
.column(index);
}
/**
* Navigates to the detail page for a given resource name
* @param name
* @returns
*/
goToDetailsPage(name: string) {
return this.sortableTable().detailsPageLinkWithName(name)
.click();
}
} }

View File

@ -20,6 +20,10 @@ export default class ResourceYamlPo extends ComponentPo {
return CodeMirrorPo.bySelector(this.self(), '[data-testid="yaml-editor-code-mirror"]'); return CodeMirrorPo.bySelector(this.self(), '[data-testid="yaml-editor-code-mirror"]');
} }
cancel(): Cypress.Chainable {
return this.self().find('button.role-secondary');
}
saveOrCreate(): AsyncButtonPo { saveOrCreate(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self()); return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self());
} }

View File

@ -1,33 +0,0 @@
import ComponentPo, { GetOptions } from '@/cypress/e2e/po/components/component.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
export class SharedComponentsPo extends ComponentPo {
resourceTable(options?: GetOptions) {
return new ResourceTablePo(this.self(options));
}
baseResourceList(options?: GetOptions) {
return new BaseResourceList(this.self(options));
}
resourceDetail(options?: GetOptions) {
return new ResourceDetailPo(this.self(options));
}
list() {
return new BaseResourceList('[data-testid="sortable-table-list-container"]');
}
resourceTableDetails(name: string, index: number) {
return this.baseResourceList().resourceTable().sortableTable().rowWithName(name)
.column(index);
}
goToDetailsPage(elemName: string) {
const resourceTable = new ResourceTablePo(this.self());
return resourceTable.sortableTable().detailsPageLinkWithName(elemName).click();
}
}

View File

@ -24,6 +24,15 @@ export default class SortableTablePo extends ComponentPo {
return this.rowElementWithName(name).find('td.col-link-detail a'); return this.rowElementWithName(name).find('td.col-link-detail a');
} }
/**
* Get the bulk action button
* @param label
* @returns
*/
bulkActionButton(label: string) {
return this.self().find(`.fixed-header-actions .bulk button`).contains(label);
}
/** /**
* Get the bulk action dropdown button (this is where collapsed bulk actions go when screen width is too small) * Get the bulk action dropdown button (this is where collapsed bulk actions go when screen width is too small)
*/ */

View File

@ -1,23 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* Details component for fleet.cattle.io.bundle resources
*/
export default class FleetBundleDetailsPo extends PagePo {
private static createPath(fleetWorkspace: string, bundleName: string) {
return `/c/_/fleet/fleet.cattle.io.bundle/${ fleetWorkspace }/${ bundleName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, bundleName: string) {
super(FleetBundleDetailsPo.createPath(fleetWorkspace, bundleName));
}
list() {
return new BaseResourceList('[data-testid="sortable-table-list-container"]');
}
}

View File

@ -1,33 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import FleetGitRepoList from '@/cypress/e2e/po/lists/fleet/fleet.cattle.io.gitrepo.po';
import GitReposTab from '@/cypress/e2e/po/detail/fleet/tabs/git-repos-tab.po';
/**
* Details component for fleet.cattle.io.gitrepo resources
*/
export default class FleetClusterDetailsPo extends PagePo {
private static createPath(fleetWorkspace: string, clusterName: string) {
return `/c/_/fleet/fleet.cattle.io.cluster/${ fleetWorkspace }/${ clusterName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, clusterName: string) {
super(FleetClusterDetailsPo.createPath(fleetWorkspace, clusterName));
}
clusterTabs(): TabbedPo {
return new TabbedPo();
}
gitReposList(): FleetGitRepoList {
return new FleetGitRepoList(this.self());
}
gitReposTab() {
return new GitReposTab();
}
}

View File

@ -1,28 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import FleetClusterList from '@/cypress/e2e/po/lists/fleet/fleet.cattle.io.cluster.po';
/**
* Details component for fleet.cattle.io.clustergroup resources
*/
export default class FleetClusterGroupDetailsPo extends PagePo {
private static createPath(fleetWorkspace: string, clusterGroup: string) {
return `/c/_/fleet/fleet.cattle.io.clustergroup/${ fleetWorkspace }/${ clusterGroup }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, clusterName: string) {
super(FleetClusterGroupDetailsPo.createPath(fleetWorkspace, clusterName));
}
groupTabs(): TabbedPo {
return new TabbedPo();
}
clusterList() {
return new FleetClusterList('#clusters [data-testid="sortable-table-list-container"]');
}
}

View File

@ -1,32 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* Details component for fleet.cattle.io.fleetworkspace resources
*/
export default class FleetWorkspaceDetailsPo extends PagePo {
private static createPath(fleetWorkspace: string) {
return `/c/_/fleet/management.cattle.io.fleetworkspace/${ fleetWorkspace }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string) {
super(FleetWorkspaceDetailsPo.createPath(fleetWorkspace));
}
workspaceTabs(): TabbedPo {
return new TabbedPo();
}
recentEventsList() {
return new BaseResourceList('#events [data-testid="sortable-table-list-container"]');
}
relatedResourcesList(index: number) {
return new BaseResourceList(`#related div:nth-of-type(${ index })[data-testid="sortable-table-list-container"]`);
}
}

View File

@ -1,44 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import BundlesTab from '@/cypress/e2e/po/detail/fleet/tabs/bundles-tab.po';
/**
* Details component for fleet.cattle.io.gitrepo resources
*/
export default class FleetGitRepoDetailsPo extends PagePo {
private static createPath(fleetWorkspace: string, gitRepoName: string) {
return `/c/_/fleet/fleet.cattle.io.gitrepo/${ fleetWorkspace }/${ gitRepoName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, gitRepoName: string) {
super(FleetGitRepoDetailsPo.createPath(fleetWorkspace, gitRepoName));
}
gitRepoTabs(): TabbedPo {
return new TabbedPo();
}
bundlesCount(): Cypress.Chainable {
return this.self().find('[data-testid="gitrepo-bundle-summary"] .count').invoke('text');
}
bundlesTab() {
return new BundlesTab();
}
shwoConfig() {
this.self().find('[data-testid="button-group-child-1"]').click();
}
showGraph() {
this.self().find('[data-testid="button-group-child-2"]').click();
}
graph() {
return this.self().find('[data-testid="gitrepo_graph"]');
}
}

View File

@ -1,12 +0,0 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po';
import BaseResourceList from '~/cypress/e2e/po/lists/base-resource-list.po';
export default class BundlesTab extends ComponentPo {
constructor(selector = '.dashboard-root') {
super(selector);
}
list() {
return new BaseResourceList('#bundles [data-testid="sortable-table-list-container"]');
}
}

View File

@ -1,16 +0,0 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po';
import BaseResourceList from '~/cypress/e2e/po/lists/base-resource-list.po';
export default class GitReposTab extends ComponentPo {
constructor(selector = '.dashboard-root') {
super(selector);
}
list() {
return new BaseResourceList('#repos [data-testid="sortable-table-list-container"]');
}
addRepostoryButton() {
return this.self().get('.btn').contains('Add Repository');
}
}

View File

@ -0,0 +1,12 @@
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import BaseCloudCredentialsPo from '@/cypress/e2e/po/edit/base-cloud-credentials.po';
export default class DigitalOceanCloudCredentialsCreateEditPo extends BaseCloudCredentialsPo {
credentialName(): LabeledInputPo {
return LabeledInputPo.byLabel(this.self(), 'Credential Name');
}
accessToken(): LabeledInputPo {
return LabeledInputPo.byLabel(this.self(), 'Access Token');
}
}

View File

@ -0,0 +1,4 @@
import AmazonCloudCredentialsCreateEditPo from '@/cypress/e2e/po/edit/cloud-credentials-amazon.po';
export default class EKSCloudCredentialsCreateEditPo extends AmazonCloudCredentialsCreateEditPo {
}

View File

@ -1,16 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
export default class FleetBundlesCreateEditPo extends PagePo {
private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.bundle`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetBundlesCreateEditPo.createPath(workspace, id));
}
}

View File

@ -1,17 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
export default class FleetBundleNsMappingCreateEditPo extends PagePo {
private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.bundlenamespacemapping`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetBundleNsMappingCreateEditPo.createPath(workspace, id));
}
}

View File

@ -1,20 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
export default class FleetClusterEditPo extends PagePo {
private static createPath(fleetWorkspace: string, clusterName: string) {
return `/c/_/fleet/fleet.cattle.io.cluster/${ fleetWorkspace }/${ clusterName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace = 'fleet-default', clusterName: string) {
super(FleetClusterEditPo.createPath(fleetWorkspace, clusterName));
}
sharedComponents() {
return new SharedComponentsPo(this.self());
}
}

View File

@ -1,22 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
export default class FleetClusterGroupsCreateEditPo extends PagePo {
private static createPath(clusterId: string, workspace?: string, id?: string ) {
const root = `/c/${ clusterId }/fleet/fleet.cattle.io.clustergroup`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(clusterId = '_', workspace?: string, id?: string) {
super(FleetClusterGroupsCreateEditPo.createPath(clusterId, workspace, id));
}
sharedComponents() {
return new SharedComponentsPo(this.self());
}
}

View File

@ -1,17 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
export default class FleetTokensCreateEditPo extends PagePo {
private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.clusterregistrationtoken`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetTokensCreateEditPo.createPath(workspace, id));
}
}

View File

@ -1,32 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import ArrayListPo from '@/cypress/e2e/po/components/array-list.po';
import KeyValuePo from '@/cypress/e2e/po/components/key-value.po';
export default class FleetWorkspaceCreateEditPo extends PagePo {
private static createPath(fleetWorkspace: string) {
const root = '/c/_/fleet/management.cattle.io.fleetworkspace';
return fleetWorkspace ? `${ root }/${ fleetWorkspace }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string) {
super(FleetWorkspaceCreateEditPo.createPath(fleetWorkspace));
}
sharedComponents() {
return new SharedComponentsPo(this.self());
}
allowTargetNsTabList() {
return new ArrayListPo('section#allowedtargetnamespaces');
}
lablesAnnotationsKeyValue() {
return new KeyValuePo('section#labels');
}
}

View File

@ -1,17 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
export default class FleetRestrictionCreateEditPo extends PagePo {
private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.gitreporestriction`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetRestrictionCreateEditPo.createPath(workspace, id));
}
}

View File

@ -1,56 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import ArrayListPo from '@/cypress/e2e/po/components/array-list.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
import SelectOrCreateAuthPo from '@/cypress/e2e/po/components/select-or-create-auth.po';
export class GitRepoEditPo extends PagePo {
private static createPath(fleetWorkspace: string, gitRepoName: string) {
return `/c/_/fleet/fleet.cattle.io.gitrepo/${ fleetWorkspace }/${ gitRepoName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, gitRepoName: string) {
super(GitRepoEditPo.createPath(fleetWorkspace, gitRepoName));
}
sharedComponents() {
return new SharedComponentsPo(this.self());
}
setBranchName(branch = 'dashboard-e2e-basic') {
return LabeledInputPo.byLabel(this.self(), 'Branch').set(branch);
}
setGitRepoUrl(url: string) {
return LabeledInputPo.byLabel(this.self(), 'Repository URL').set(url);
}
setHelmRepoURLRegex(regexStr = 'https://charts.rancher.io/*') {
return LabeledInputPo.bySelector(this.self(), '[data-testid="gitrepo-helm-repo-url-regex"]').set(regexStr);
}
setGitRepoPath(path: string, index = 0) {
return this.gitRepoPaths().setValueAtIndex(path, index);
}
targetCluster(): LabeledSelectPo {
return new LabeledSelectPo('[data-testid="fleet-gitrepo-target-cluster"]');
}
gitRepoPaths() {
return new ArrayListPo('[data-testid="gitRepo-paths"]');
}
authSelectOrCreate(selector: string) {
return new SelectOrCreateAuthPo(selector);
}
helmAuthSelectOrCreate() {
return this.authSelectOrCreate('[data-testid="gitrepo-helm-auth"]');
}
}

View File

@ -1,11 +1,10 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po'; import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po'; import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po';
import { CypressChainable } from '@/cypress/e2e/po/po.types'; import { CypressChainable } from '@/cypress/e2e/po/po.types';
import GlobalRoleBindings from '@/cypress/e2e/po/components/global-role-binding.po'; import GlobalRoleBindings from '@/cypress/e2e/po/components/global-role-binding.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
export default class MgmtUserEditPo extends PagePo { export default class MgmtUserEditPo extends BaseDetailPagePo {
private static createPath(clusterId: string, userId?: string ) { private static createPath(clusterId: string, userId?: string ) {
const root = `/c/${ clusterId }/auth/management.cattle.io.user`; const root = `/c/${ clusterId }/auth/management.cattle.io.user`;
@ -44,10 +43,6 @@ export default class MgmtUserEditPo extends PagePo {
return CheckboxInputPo.byLabel(this.self(), label); return CheckboxInputPo.byLabel(this.self(), label);
} }
saveCreateForm(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="form-save"]', this.self());
}
saveCreateWithErrorRetry(attempt = 1): Cypress.Chainable | null { saveCreateWithErrorRetry(attempt = 1): Cypress.Chainable | null {
if (attempt > 3) { if (attempt > 3) {
return null; return null;
@ -56,7 +51,8 @@ export default class MgmtUserEditPo extends PagePo {
cy.intercept('POST', 'v3/users').as('userCreation'); cy.intercept('POST', 'v3/users').as('userCreation');
cy.intercept('POST', 'v3/globalrolebindings').as('globalRoleBindingsCreation'); cy.intercept('POST', 'v3/globalrolebindings').as('globalRoleBindingsCreation');
this.saveCreateForm().click(); this.resourceDetail().cruResource().saveOrCreate()
.click();
// Based on issue https://github.com/rancher/dashboard/issues/10260 // Based on issue https://github.com/rancher/dashboard/issues/10260
// main xhr request for user creation // main xhr request for user creation
@ -83,7 +79,8 @@ export default class MgmtUserEditPo extends PagePo {
saveAndWaitForRequests(method: string, url: any, multipleCalls?: boolean): CypressChainable { saveAndWaitForRequests(method: string, url: any, multipleCalls?: boolean): CypressChainable {
cy.intercept(method, url).as('request'); cy.intercept(method, url).as('request');
this.saveCreateForm().click(); this.resourceDetail().cruResource().saveOrCreate()
.click();
return (multipleCalls ? cy.wait(['@request', '@request'], { timeout: 10000 }) : cy.wait('@request', { timeout: 10000 })); return (multipleCalls ? cy.wait(['@request', '@request'], { timeout: 10000 }) : cy.wait('@request', { timeout: 10000 }));
} }

View File

@ -0,0 +1,24 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
export default class NamespaceCreateEditPagePo extends PagePo {
private static createPath(clusterId: string, nsName?: string ) {
const root = `/c/${ clusterId }/explorer/namespace`;
return nsName ? `${ root }/${ nsName }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(clusterId = '_', nsName?: string) {
super(NamespaceCreateEditPagePo.createPath(clusterId, nsName));
}
static navTo() {
const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Projects/Namespaces');
}
}

View File

@ -0,0 +1,104 @@
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 ClusterManagerCreateRke2AmazonPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke2-amazon.po';
import EKSCloudCredentialsCreateEditPo from '@/cypress/e2e/po/edit/cloud-credentials-eks.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
import eksVersions from '@/pkg/eks/assets/data/eks-versions.js';
import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po';
import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po';
/**
* Create page for an EKS cluster
*/
export default class ClusterManagerCreateEKSPagePo extends ClusterManagerCreateRke2AmazonPagePo {
static url(clusterId: string) {
return `${ ClusterManagerCreatePagePo.url(clusterId) }/create?type=amazoneks&rkeType=rke2`;
}
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return PagePo.goTo(ClusterManagerCreateRke2AmazonPagePo.url(clusterId));
}
goToAmazonClusterCreation(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return PagePo.goTo(`${ ClusterManagerCreatePagePo.url(clusterId) }?type=amazoneks&rkeType=rke2`);
}
cloudCredentialsForm(): EKSCloudCredentialsCreateEditPo {
return new EKSCloudCredentialsCreateEditPo();
}
getClusterName() {
return new LabeledInputPo('[data-testid="eks-name-input"]');
}
getClusterDescription() {
return new LabeledInputPo('[placeholder*="better describes this resource"]');
}
getRegion() {
return new LabeledSelectPo('[data-testid="eks_region"]');
}
getVersion() {
return new LabeledSelectPo('[data-testid="eks-version-dropdown"]');
}
getNodeGroup() {
return new LabeledInputPo('[data-testid="eks-nodegroup-name"]');
}
getNodeRole() {
return new LabeledSelectPo('[data-testid="eks-noderole"]');
}
getLauchTemplate() {
return new LabeledSelectPo('[data-testid="eks-launch-template-dropdown"]');
}
getDesiredASGSize() {
return LabeledInputPo.byLabel(cy.get('[data-testid="cru-form"]'), 'Desired ASG Size');
}
getMinASGSize() {
return LabeledInputPo.byLabel(cy.get('[data-testid="cru-form"]'), 'Minimum ASG Size');
}
getMaxASGSize() {
return LabeledInputPo.byLabel(cy.get('[data-testid="cru-form"]'), 'Maximum ASG Size');
}
getInstanceType() {
return new LabeledSelectPo('[data-testid="eks-instance-type-dropdown"]');
}
getDiskSize() {
return new LabeledInputPo('[data-testid="eks-disksize-input"]');
}
getServiceRole() {
return new RadioGroupInputPo('[data-testid="radio-button-0"]');
}
getPublicAccess() {
return CheckboxInputPo.byLabel(this.self(), 'Public Access');
}
getPrivateAccess() {
return CheckboxInputPo.byLabel(this.self(), 'Private Access');
}
getLatestEKSversion() {
let latestVersion = 0;
eksVersions.forEach((version: string) => {
const versionNumber = Number(version);
if (versionNumber > latestVersion) {
latestVersion = versionNumber;
}
});
return String(latestVersion);
}
}

View File

@ -6,7 +6,8 @@ import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
export default class ResourceDetailPo extends ComponentPo { export default class ResourceDetailPo extends ComponentPo {
/** /**
* components for handling CRUD operations for resources, including cancel/save buttons * Returns the page object for interacting with the CRU (Create, Read, Update) resource component,
* including support for actions like selecting types and clicking save/cancel buttons.
* @returns * @returns
*/ */
cruResource() { cruResource() {
@ -14,7 +15,8 @@ export default class ResourceDetailPo extends ComponentPo {
} }
/** /**
* components for managing the resource creation and edit forms * Returns the page object for managing resource creation and edit views,
* including interactions like saving, editing as YAML, and navigating form steps.
* @returns * @returns
*/ */
createEditView() { createEditView() {
@ -22,13 +24,19 @@ export default class ResourceDetailPo extends ComponentPo {
} }
/** /**
* components for YAML editor * Returns the page object for interacting with the YAML editor,
* including methods to access the editor, footer, and save/create actions.
* @returns * @returns
*/ */
resourceYaml() { resourceYaml() {
return new ResourceYamlPo(this.self()); return new ResourceYamlPo(this.self());
} }
/**
* Returns the page object for interacting with tabbed UI components,
* allowing tab selection and verification of active tabs.
* @returns
*/
tabs() { tabs() {
return new TabbedPo('[data-testid="tabbed"]'); return new TabbedPo('[data-testid="tabbed"]');
} }

View File

@ -4,7 +4,7 @@ import CodeMirrorPo from '@/cypress/e2e/po/components/code-mirror.po';
export default class StorageClassesCreateEditPo extends PagePo { export default class StorageClassesCreateEditPo extends PagePo {
private static createPath(clusterId: string, id?: string ) { private static createPath(clusterId: string, id?: string ) {
const root = `/c/${ clusterId }/explorer/storage.k8s.io.storageclass/create`; const root = `/c/${ clusterId }/explorer/storage.k8s.io.storageclass`;
return id ? `${ root }/${ id }` : `${ root }/create`; return id ? `${ root }/${ id }` : `${ root }/create`;
} }
@ -13,7 +13,7 @@ export default class StorageClassesCreateEditPo extends PagePo {
throw new Error('invalid'); throw new Error('invalid');
} }
constructor(clusterId = '_', id?: string) { constructor(clusterId = 'local', id?: string) {
super(StorageClassesCreateEditPo.createPath(clusterId, id)); super(StorageClassesCreateEditPo.createPath(clusterId, id));
} }

View File

@ -1,13 +1,13 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import PagePo from '@/cypress/e2e/po/pages/page.po';
import { InstallChartPage } from '@/cypress/e2e/po/pages/explorer/charts/install-charts.po'; import { InstallChartPage } from '@/cypress/e2e/po/pages/explorer/charts/install-charts.po';
import ChartInstalledAppsPagePo from '@/cypress/e2e/po/pages/chart-installed-apps.po'; import ChartInstalledAppsListPagePo from '@/cypress/e2e/po/pages/chart-installed-apps.po';
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po'; import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
import NameNsDescriptionPo from '@/cypress/e2e/po/components/name-ns-description.po'; import NameNsDescriptionPo from '@/cypress/e2e/po/components/name-ns-description.po';
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po'; import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
import CodeMirrorPo from '~/cypress/e2e/po/components/code-mirror.po'; import CodeMirrorPo from '~/cypress/e2e/po/components/code-mirror.po';
const installChartPage = new InstallChartPage(); const installChartPage = new InstallChartPage();
const appsPage = new ChartInstalledAppsPagePo('local', 'apps'); const appsPage = new ChartInstalledAppsListPagePo('local', 'apps');
const root = '.dashboard-root'; const root = '.dashboard-root';
export default class ExtensionsCompatibilityUtils { export default class ExtensionsCompatibilityUtils {

View File

@ -4,21 +4,22 @@ import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po'; import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po'; import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po'; import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po';
import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po';
/** /**
* Edit page for imported cluster * Edit page for imported cluster
*/ */
export default class ClusterManagerEditImportedPagePo extends PagePo { export default class ClusterManagerEditImportedPagePo extends PagePo {
private static createPath(clusterId: string, clusterName: string) { private static createPath(clusterId: string, ns: string, clusterName: string) {
return `/c/${ clusterId }/manager/provisioning.cattle.io.cluster/fleet-default/${ clusterName }`; return `/c/${ clusterId }/manager/provisioning.cattle.io.cluster/${ ns }/${ clusterName }`;
} }
static goTo(clusterId: string, clusterName: string ): Cypress.Chainable<Cypress.AUTWindow> { static goTo(clusterId: string, ns: string, clusterName: string ): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(ClusterManagerEditImportedPagePo.createPath(clusterId, clusterName)); return super.goTo(ClusterManagerEditImportedPagePo.createPath(clusterId, ns, clusterName));
} }
constructor(clusterId = '_', clusterName: string) { constructor(clusterId = '_', ns = 'fleet-default', clusterName: string) {
super(ClusterManagerEditImportedPagePo.createPath(clusterId, clusterName)); super(ClusterManagerEditImportedPagePo.createPath(clusterId, ns, clusterName));
} }
nameNsDescription() { nameNsDescription() {
@ -37,6 +38,26 @@ export default class ClusterManagerEditImportedPagePo extends PagePo {
return this.accordion(index, label).click(); return this.accordion(index, label).click();
} }
versionManagementBanner() {
return this.self().find('[data-testid="version-management-banner"]');
}
versionManagementRadioButton(): RadioGroupInputPo {
return new RadioGroupInputPo('[data-testid="imported-version-management-radio"]');
}
enableVersionManagement() {
return this.versionManagementRadioButton().set(1);
}
disableVersionManagement() {
return this.versionManagementRadioButton().set(2);
}
defaultVersionManagement() {
return this.versionManagementRadioButton().set(0);
}
privateRegistryCheckbox() { privateRegistryCheckbox() {
return new CheckboxInputPo('[data-testid="private-registry-enable-checkbox"]'); return new CheckboxInputPo('[data-testid="private-registry-enable-checkbox"]');
} }
@ -56,4 +77,8 @@ export default class ClusterManagerEditImportedPagePo extends PagePo {
save() { save() {
return this.resourceDetail().createEditView().save(); return this.resourceDetail().createEditView().save();
} }
cancel() {
return this.resourceDetail().createEditView().cancel();
}
} }

View File

@ -11,4 +11,8 @@ export default class ClusterManagerImportGenericPagePo extends ClusterManagerImp
networkingAccordion() { networkingAccordion() {
return this.self().find('[data-testid="networking-accordion"]'); return this.self().find('[data-testid="networking-accordion"]');
} }
versionManagementBanner() {
return this.self().find('[data-testid="version-management-banner"]');
}
} }

View File

@ -1,8 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for events
*/
export default class EventsListPo extends BaseResourceList {
}

View File

@ -1,10 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.bundle resources
*/
export default class FleetBundlesList extends BaseResourceList {
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
}

View File

@ -1,10 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.bundlenamespacemapping resources
*/
export default class FleetBundleNamespaceMappingList extends BaseResourceList {
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
}

View File

@ -1,14 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.cluster resources
*/
export default class FleetClusterList extends BaseResourceList {
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
subRows() {
return this.resourceTable().sortableTable().subRows();
}
}

View File

@ -1,10 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.clustergroup resources
*/
export default class FleetClusterGroupsList extends BaseResourceList {
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
}

View File

@ -1,10 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.clusterregistrationtoken resources
*/
export default class FleetClusterRegistrationTokensList extends BaseResourceList {
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
}

View File

@ -1,14 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.gitrepo resources
*/
export default class FleetGitRepoList extends BaseResourceList {
create() {
return this.masthead().actions().eq(0).click();
}
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
}

View File

@ -1,10 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.gitreporestriction resources
*/
export default class FleetGitRepoRestrictionList extends BaseResourceList {
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
}

View File

@ -1,10 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for fleet.cattle.io.workspaces resources
*/
export default class FleetWorkspaceList extends BaseResourceList {
details(name: string, index: number) {
return this.resourceTable().sortableTable().rowWithName(name).column(index);
}
}

View File

@ -1,7 +0,0 @@
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* List component for pods resources
*/
export default class SecretsListPo extends BaseResourceList {
}

View File

@ -28,6 +28,10 @@ export default class CreateKeyPagePo extends PagePo {
return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self()); return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self());
} }
cancelButton(): Cypress.Chainable {
return this.self().get('button.role-secondary');
}
doneButton(): AsyncButtonPo { doneButton(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="token_done_create_button"]', this.self()); return new AsyncButtonPo('[data-testid="token_done_create_button"]', this.self());
} }
@ -43,4 +47,8 @@ export default class CreateKeyPagePo extends PagePo {
create(): Cypress.Chainable { create(): Cypress.Chainable {
return this.createButton().click(); return this.createButton().click();
} }
cancel() {
return this.cancelButton().click();
}
} }

View File

@ -0,0 +1,15 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po';
/**
* Shared detail-page behavior
*/
export abstract class BaseDetailPagePo extends PagePo {
/**
* Returns resource detail page object
* @returns
*/
resourceDetail() {
return new ResourceDetailPo(this.self());
}
}

View File

@ -0,0 +1,42 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
/**
* Shared list-page behavior
*/
export abstract class BaseListPagePo extends PagePo {
/**
* Returns base resource list page object
* @returns
*/
baseResourceList() {
return new BaseResourceList(this.self());
}
/**
* Standard sortable list page object
* @returns
*/
list() {
return new BaseResourceList('[data-testid="sortable-table-list-container"]');
}
/**
* Returns a specific table column value for a row with the given name
* @param name
* @param index
* @returns
*/
resourceTableDetails(name: string, index: number) {
return this.baseResourceList().resourceTable().resourceTableDetails(name, index);
}
/**
* Navigates to the detail page for a given resource name
* @param name
* @returns
*/
goToDetailsPage(name: string) {
return this.baseResourceList().resourceTable().goToDetailsPage(name);
}
}

View File

@ -1,32 +1,31 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import Kubectl from '@/cypress/e2e/po/components/kubectl.po'; import Kubectl from '@/cypress/e2e/po/components/kubectl.po';
import { GetOptions } from '@/cypress/e2e/po/components/component.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po'; import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
const terminal = new Kubectl(); const terminal = new Kubectl();
/** /**
* List page for catalog.cattle.io.app resources * List page for catalog.cattle.io.app resources
*/ */
export default class ChartInstalledAppsPagePo extends PagePo { export default class ChartInstalledAppsListPagePo extends BaseListPagePo {
private static createPath(clusterId: string, product: 'apps' | 'manager') { private static createPath(clusterId: string, product: 'apps' | 'manager') {
return `/c/${ clusterId }/${ product }/catalog.cattle.io.app`; return `/c/${ clusterId }/${ product }/catalog.cattle.io.app`;
} }
static goTo(clusterId: string, product: 'apps' | 'manager'): Cypress.Chainable<Cypress.AUTWindow> { static goTo(clusterId: string, product: 'apps' | 'manager'): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(ChartInstalledAppsPagePo.createPath(clusterId, product)); return super.goTo(ChartInstalledAppsListPagePo.createPath(clusterId, product));
} }
constructor(clusterId = 'local', product: 'apps' | 'manager') { constructor(clusterId = 'local', product: 'apps' | 'manager') {
super(ChartInstalledAppsPagePo.createPath(clusterId, product)); super(ChartInstalledAppsListPagePo.createPath(clusterId, product));
} }
filter(key: string) { filter(key: string) {
this.self().get('.input-sm.search-box').type(key); this.self().get('.input-sm.search-box').type(key);
} }
sharedComponents(options?: GetOptions) { appsList() {
return new SharedComponentsPo('[data-testid="installed-app-catalog-list"]', this.self(options)); return new ResourceTablePo('[data-testid="installed-app-catalog-list"]');
} }
waitForInstallCloseTerminal(interceptName: string, installableParts: Array<String>) { waitForInstallCloseTerminal(interceptName: string, installableParts: Array<String>) {
@ -37,7 +36,7 @@ export default class ChartInstalledAppsPagePo extends PagePo {
terminal.closeTerminal(); terminal.closeTerminal();
installableParts.forEach((item:string) => { installableParts.forEach((item:string) => {
this.sharedComponents().resourceTableDetails(item, 0).should('contain', 'Deployed'); this.appsList().resourceTableDetails(item, 0).should('contain', 'Deployed');
}); });
// timeout to give time for everything to be setup, otherwise the extension // timeout to give time for everything to be setup, otherwise the extension

View File

@ -1,11 +1,11 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import PagePo from '@/cypress/e2e/po/pages/page.po';
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
import CustomBadgeDialogPo from '@/cypress/e2e/po/components/custom-badge-dialog.po'; import CustomBadgeDialogPo from '@/cypress/e2e/po/components/custom-badge-dialog.po';
import EventsListPo from '@/cypress/e2e/po/lists/events-list.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po'; import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import CertificatesPo from '@/cypress/e2e/po/components/certificates.po'; import CertificatesPo from '@/cypress/e2e/po/components/certificates.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po'; import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import { NamespaceFilterPo } from '@/cypress/e2e/po/components/namespace-filter.po'; import { NamespaceFilterPo } from '@/cypress/e2e/po/components/namespace-filter.po';
import ResourceTablePo from '~/cypress/e2e/po/components/resource-table.po';
export default class ClusterDashboardPagePo extends PagePo { export default class ClusterDashboardPagePo extends PagePo {
private static createPath(clusterId: string) { private static createPath(clusterId: string) {
@ -38,10 +38,6 @@ export default class ClusterDashboardPagePo extends PagePo {
return new CustomBadgeDialogPo(); return new CustomBadgeDialogPo();
} }
eventsList(): EventsListPo {
return new EventsListPo('[data-testid="sortable-table-list-container"]');
}
certificates(): CertificatesPo { certificates(): CertificatesPo {
return new CertificatesPo(); return new CertificatesPo();
} }
@ -64,6 +60,14 @@ export default class ClusterDashboardPagePo extends PagePo {
return cy.get('.cert-table-link').contains('Full secrets list'); return cy.get('.cert-table-link').contains('Full secrets list');
} }
eventsList() {
return new ResourceTablePo('#cluster-events [data-testid="sortable-table-list-container"]');
}
certificatesList() {
return new ResourceTablePo('#cluster-certs [data-testid="sortable-table-list-container"]');
}
clusterActionsHeader() { clusterActionsHeader() {
return new HeaderPo(); return new HeaderPo();
} }

View File

@ -1,4 +1,5 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import PagePo from '@/cypress/e2e/po/pages/page.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
export default class ClusterToolsPagePo extends PagePo { export default class ClusterToolsPagePo extends PagePo {
private static createPath(clusterId: string) { private static createPath(clusterId: string) {
@ -13,6 +14,12 @@ export default class ClusterToolsPagePo extends PagePo {
super(ClusterToolsPagePo.createPath(clusterId)); super(ClusterToolsPagePo.createPath(clusterId));
} }
static navTo() {
const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Tools');
}
featureChartCards(): Cypress.Chainable { featureChartCards(): Cypress.Chainable {
return cy.get('.grid > .item'); return cy.get('.grid > .item');
} }

View File

@ -1,18 +1,18 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import EventsListPo from '@/cypress/e2e/po/lists/events-list.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
export class EventsPagePo extends PagePo { export class EventsPageListPo extends BaseListPagePo {
private static createPath(clusterId: string) { private static createPath(clusterId: string) {
return `/c/${ clusterId }/explorer/event`; return `/c/${ clusterId }/explorer/event`;
} }
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> { static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(EventsPagePo.createPath(clusterId)); return super.goTo(EventsPageListPo.createPath(clusterId));
} }
constructor(clusterId: string) { constructor(clusterId: string) {
super(EventsPagePo.createPath(clusterId)); super(EventsPageListPo.createPath(clusterId));
} }
static navTo() { static navTo() {
@ -20,15 +20,20 @@ export class EventsPagePo extends PagePo {
sideNav.navToSideMenuEntryByLabel('Events'); sideNav.navToSideMenuEntryByLabel('Events');
} }
}
eventslist(): EventsListPo { export class EventsCreateEditPo extends BaseDetailPagePo {
return new EventsListPo('[data-testid="sortable-table-list-container"]'); private static createPath(clusterId: string, namespace?: string, eventName?: string) {
const root = `/c/${ clusterId }/explorer/event`;
return namespace && eventName ? `${ root }/${ namespace }/${ eventName }` : `${ root }/create`;
} }
/** static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
* Convenience method throw new Error('invalid');
*/ }
sortableTable() {
return this.eventslist().resourceTable().sortableTable(); constructor(clusterId = 'local', namespace?: string, eventName?: string) {
super(EventsCreateEditPo.createPath(clusterId, namespace, eventName));
} }
} }

View File

@ -1,52 +1,46 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po'; import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import ResourceListMastheadPo from '@/cypress/e2e/po/components/ResourceList/resource-list-masthead.po'; import GenericPrompt from '@/cypress/e2e/po/prompts/genericPrompt.po';
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po'; import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
export default class ProjectNamespacePagePo extends PagePo { export class ProjectsNamespacesListPagePo extends BaseListPagePo {
private static createPath(clusterId: string) { private static createPath(clusterId: string) {
return `/c/${ clusterId }/explorer/projectsnamespaces`; return `/c/${ clusterId }/explorer/projectsnamespaces`;
} }
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> { static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(ProjectNamespacePagePo.createPath(clusterId)); return super.goTo(ProjectsNamespacesListPagePo.createPath(clusterId));
} }
constructor(clusterId: string) { constructor(clusterId = 'local') {
super(ProjectNamespacePagePo.createPath(clusterId)); super(ProjectsNamespacesListPagePo.createPath(clusterId));
} }
flatListButton() { static navTo() {
return this.self().getId('button-group-child-0'); const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Projects/Namespaces');
} }
flatListClick(): Cypress.Chainable { createNamespaceButton() {
return this.flatListButton().click(); return this.self().get('[data-testid="create_project_namespaces"]');
}
}
export class ProjectCreateEditPagePo extends BaseDetailPagePo {
private static createPath(clusterId: string, projName?: string ) {
const root = `/c/${ clusterId }/explorer/management.cattle.io.project`;
return projName ? `${ root }/${ projName }` : `${ root }/create`;
} }
createProjectNamespaceButton() { static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
return this.self().getId('create_project_namespaces'); throw new Error('invalid');
} }
createProjectNamespaceClick(): Cypress.Chainable { constructor(clusterId = 'local', projName?: string) {
return this.createProjectNamespaceButton().click(); super(ProjectCreateEditPagePo.createPath(clusterId, projName));
}
createProjectButtonClick(): Cypress.Chainable {
return new ResourceListMastheadPo(this.self()).create();
}
nameNsDescription() {
return new NameNsDescription(this.self());
}
nsProject() {
return this.nameNsDescription().project();
}
name() {
return this.nameNsDescription().name();
} }
tabResourceQuotas() { tabResourceQuotas() {
@ -65,10 +59,6 @@ export default class ProjectNamespacePagePo extends PagePo {
return new LabeledInputPo(cy.get('[data-testid="projectrow-namespace-quota-input"]')); return new LabeledInputPo(cy.get('[data-testid="projectrow-namespace-quota-input"]'));
} }
buttonSubmit() {
return new AsyncButtonPo(this.self().getId('form-save'));
}
tabContainerDefaultResourceLimit() { tabContainerDefaultResourceLimit() {
return this.self().getId('btn-container-default-resource-limit'); return this.self().getId('btn-container-default-resource-limit');
} }
@ -92,4 +82,28 @@ export default class ProjectNamespacePagePo extends PagePo {
bannerError(n: number) { bannerError(n: number) {
return this.self().getId(`error-banner${ n }`); return this.self().getId(`error-banner${ n }`);
} }
addProjectMemberButton() {
return this.self().get('[data-testid="add-item"]');
}
addProjectMemberModal(): GenericPrompt {
return new GenericPrompt(this.self());
}
}
export class NamespaceCreateEditPagePo extends BaseDetailPagePo {
private static createPath(clusterId: string, nsName?: string ) {
const root = `/c/${ clusterId }/explorer/namespace`;
return nsName ? `${ root }/${ nsName }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(clusterId = 'local', nsName?: string) {
super(NamespaceCreateEditPagePo.createPath(clusterId, nsName));
}
} }

View File

@ -1,20 +1,42 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import SecretsListPo from '@/cypress/e2e/po/lists/secrets-list.po'; import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
export class SecretsPagePo extends PagePo { export class SecretsListPagePo extends BaseListPagePo {
private static createPath(clusterId: string) { private static createPath(clusterId: string) {
return `/c/${ clusterId }/explorer/secret`; return `/c/${ clusterId }/explorer/secret`;
} }
static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> { static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(SecretsPagePo.createPath(clusterId)); return super.goTo(SecretsListPagePo.createPath(clusterId));
} }
constructor(clusterId: string) { constructor(clusterId: string) {
super(SecretsPagePo.createPath(clusterId)); super(SecretsListPagePo.createPath(clusterId));
} }
secretsList(): SecretsListPo { static navTo(clusterId = 'local') {
return new SecretsListPo('[data-testid="sortable-table-list-container"]'); const burgerMenu = new BurgerMenuPo();
const sideNav = new ProductNavPo();
burgerMenu.goToCluster(clusterId);
sideNav.navToSideMenuGroupByLabel('Storage');
sideNav.navToSideMenuEntryByLabel('Secrets');
}
}
export class SecretsCreateEditPo extends BaseDetailPagePo {
private static createPath(clusterId: string, namespace?: string, id?: string ) {
const root = `/c/${ clusterId }/explorer/secret`;
return id ? `${ root }/${ namespace }/${ id }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(clusterId: string, namespace?: string, id?: string) {
super(SecretsCreateEditPo.createPath(clusterId, namespace, id));
} }
} }

View File

@ -1,13 +1,10 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import BaseResourceList from '@/cypress/e2e/po/lists/base-resource-list.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';
import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po'; import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po'; import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import ResourceListMastheadPo from '@/cypress/e2e/po/components/ResourceList/resource-list-masthead.po';
import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po'; import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
export class WorkloadsDaemonsetsListPagePo extends PagePo { export class WorkloadsDaemonsetsListPagePo extends BaseListPagePo {
private static createPath(clusterId: string) { private static createPath(clusterId: string) {
return `/c/${ clusterId }/explorer/apps.daemonset`; return `/c/${ clusterId }/explorer/apps.daemonset`;
} }
@ -19,29 +16,35 @@ export class WorkloadsDaemonsetsListPagePo extends PagePo {
constructor(clusterId = 'local') { constructor(clusterId = 'local') {
super(WorkloadsDaemonsetsListPagePo.createPath(clusterId)); super(WorkloadsDaemonsetsListPagePo.createPath(clusterId));
} }
}
masthead() { export class WorkLoadsDaemonsetsCreatePagePo extends BaseDetailPagePo {
return new ResourceListMastheadPo(this.self()); static url: string;
private static createPath(clusterId: string, queryParams?: Record<string, string>) {
const urlStr = `/c/${ clusterId }/explorer/apps.daemonset/create`;
if (!queryParams) {
return urlStr;
} }
createDaemonset() { const params = new URLSearchParams(queryParams);
return this.masthead().create();
return `${ urlStr }?${ params.toString() }`;
} }
goToeditItemWithName(name:string) { static goTo(): Cypress.Chainable<Cypress.AUTWindow> {
const baseResourceList = new BaseResourceList(this.self()); return super.goTo(this.url);
return baseResourceList.actionMenu(name).getMenuItem('Edit Config').click();
} }
listElementWithName(name:string) { constructor(clusterId = 'local', queryParams?: Record<string, string>) {
const baseResourceList = new BaseResourceList(this.self()); super(WorkLoadsDaemonsetsCreatePagePo.createPath(clusterId, queryParams));
return baseResourceList.resourceTable().sortableTable().rowElementWithName(name); WorkLoadsDaemonsetsCreatePagePo.url = WorkLoadsDaemonsetsCreatePagePo.createPath(clusterId, queryParams);
} }
} }
export class WorkLoadsDaemonsetsEditPagePo extends PagePo { export class WorkLoadsDaemonsetsEditPagePo extends BaseDetailPagePo {
static url: string; static url: string;
private static createPath(daemonsetId: string, clusterId: string, namespaceId: string, queryParams?: Record<string, string>) { private static createPath(daemonsetId: string, clusterId: string, namespaceId: string, queryParams?: Record<string, string>) {
@ -66,10 +69,6 @@ export class WorkLoadsDaemonsetsEditPagePo extends PagePo {
WorkLoadsDaemonsetsEditPagePo.url = WorkLoadsDaemonsetsEditPagePo.createPath(daemonsetId, clusterId, namespaceId, queryParams); WorkLoadsDaemonsetsEditPagePo.url = WorkLoadsDaemonsetsEditPagePo.createPath(daemonsetId, clusterId, namespaceId, queryParams);
} }
nameNsDescription() {
return new NameNsDescription(this.self());
}
containerImageInput(): LabeledInputPo { containerImageInput(): LabeledInputPo {
return LabeledInputPo.byLabel(this.self(), 'Container Image'); return LabeledInputPo.byLabel(this.self(), 'Container Image');
} }
@ -81,8 +80,4 @@ export class WorkLoadsDaemonsetsEditPagePo extends PagePo {
ScalingUpgradePolicyRadioBtn(): RadioGroupInputPo { ScalingUpgradePolicyRadioBtn(): RadioGroupInputPo {
return new RadioGroupInputPo('[data-testid="input-policy-strategy"]'); return new RadioGroupInputPo('[data-testid="input-policy-strategy"]');
} }
saveCreateForm(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="form-save"]', this.self());
}
} }

View File

@ -9,6 +9,7 @@ import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import WorkloadPodStoragePo from '@/cypress/e2e/po/components/workloads/pod-storage.po'; import WorkloadPodStoragePo from '@/cypress/e2e/po/components/workloads/pod-storage.po';
import ContainerMountPathPo from '@/cypress/e2e/po/components/workloads/container-mount-paths.po'; import ContainerMountPathPo from '@/cypress/e2e/po/components/workloads/container-mount-paths.po';
import { WorkloadType } from '@shell/types/fleet'; import { WorkloadType } from '@shell/types/fleet';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
export class workloadDetailsPageBasePo extends PagePo { export class workloadDetailsPageBasePo extends PagePo {
static url: string; static url: string;
@ -93,6 +94,12 @@ export class WorkloadsListPageBasePo extends PagePo {
super(WorkloadsListPageBasePo.createPath(clusterId, workloadType, queryParams)); super(WorkloadsListPageBasePo.createPath(clusterId, workloadType, queryParams));
} }
static navTo() {
const sideNav = new ProductNavPo();
sideNav.navToSideMenuGroupByLabel('Workloads');
}
navigateToCreatePage() { navigateToCreatePage() {
const baseResourceList = new BaseResourceList(this.self()); const baseResourceList = new BaseResourceList(this.self());

View File

@ -7,8 +7,9 @@ import RepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
import BannersPo from '@/cypress/e2e/po/components/banners.po'; import BannersPo from '@/cypress/e2e/po/components/banners.po';
import ChartRepositoriesCreateEditPo from '@/cypress/e2e/po/edit/chart-repositories.po'; import ChartRepositoriesCreateEditPo from '@/cypress/e2e/po/edit/chart-repositories.po';
import AppClusterRepoEditPo from '@/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po'; import AppClusterRepoEditPo from '@/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po';
import { LONG_TIMEOUT_OPT, MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; import { LONG_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import { CLUSTER_REPOS_BASE_URL } from '@/cypress/support/utils/api-endpoints'; import { CLUSTER_REPOS_BASE_URL } from '@/cypress/support/utils/api-endpoints';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
export default class ExtensionsPagePo extends PagePo { export default class ExtensionsPagePo extends PagePo {
static url = '/c/local/uiplugins' static url = '/c/local/uiplugins'
@ -35,6 +36,10 @@ export default class ExtensionsPagePo extends PagePo {
return this.title().should('contain', 'Extensions'); return this.title().should('contain', 'Extensions');
} }
catalogsList() {
return new ResourceTablePo('[data-testid="sortable-table-list-container"]');
}
loading() { loading() {
return this.self().get('.data-loading'); return this.self().get('.data-loading');
} }
@ -55,7 +60,7 @@ export default class ExtensionsPagePo extends PagePo {
// we should be on the extensions page // we should be on the extensions page
this.waitForPage(null, 'available'); this.waitForPage(null, 'available');
this.loading(MEDIUM_TIMEOUT_OPT).should('not.exist'); this.loading().should('not.exist');
// go to app repos // go to app repos
this.extensionMenuToggle(); this.extensionMenuToggle();
@ -226,7 +231,7 @@ export default class ExtensionsPagePo extends PagePo {
} }
extensionTabAllClick(): Cypress.Chainable { extensionTabAllClick(): Cypress.Chainable {
return this.extensionTabs.clickNthTab(4); return this.extensionTabs.clickTabWithName('all');
} }
extensionTabBuiltinClick(): Cypress.Chainable { extensionTabBuiltinClick(): Cypress.Chainable {
@ -268,6 +273,10 @@ export default class ExtensionsPagePo extends PagePo {
return new ActionMenuPo(this.self()).getMenuItem('Add Rancher Repositories').click(); return new ActionMenuPo(this.self()).getMenuItem('Add Rancher Repositories').click();
} }
manageExtensionCatalogsClick(): Cypress.Chainable {
return new ActionMenuPo(this.self()).getMenuItem('Manage Extension Catalogs').click();
}
// ------------------ ADD RANCHER REPOSITORIES modal ------------------ // ------------------ ADD RANCHER REPOSITORIES modal ------------------
addReposModal() { addReposModal() {
return this.self().getId('add-extensions-repos-modal'); return this.self().getId('add-extensions-repos-modal');
@ -277,6 +286,11 @@ export default class ExtensionsPagePo extends PagePo {
return this.addReposModal().get('.dialog-buttons button:last-child').click(); return this.addReposModal().get('.dialog-buttons button:last-child').click();
} }
// ------------------ Import Extension Catalog modal ------------------
importExtensionCatalogModal(): Cypress.Chainable {
return this.self().get('.plugin-install-dialog');
}
// ------------------ add a new repo (Extension Examples) ------------------ // ------------------ add a new repo (Extension Examples) ------------------
enterClusterRepoName(name: string) { enterClusterRepoName(name: string) {
return new NameNsDescriptionPo(this.self()).name().set(name); return new NameNsDescriptionPo(this.self()).name().set(name);

View File

@ -1,10 +1,9 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po'; import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.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 } from '@/cypress/support/utils/timeouts';
export class FleetDashboardPagePo extends PagePo { export class FleetDashboardListPagePo extends BaseListPagePo {
static url: string; static url: string;
private static createPath( private static createPath(
@ -23,7 +22,7 @@ export class FleetDashboardPagePo extends PagePo {
} }
static goTo(clusterId = 'local'): Cypress.Chainable<Cypress.AUTWindow> { static goTo(clusterId = 'local'): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(FleetDashboardPagePo.createPath(clusterId)); return super.goTo(FleetDashboardListPagePo.createPath(clusterId));
} }
static navTo() { static navTo() {
@ -33,11 +32,7 @@ export class FleetDashboardPagePo extends PagePo {
} }
constructor(clusterId: string) { constructor(clusterId: string) {
super(FleetDashboardPagePo.createPath(clusterId)); super(FleetDashboardListPagePo.createPath(clusterId));
}
sharedComponents() {
return new SharedComponentsPo(this.self());
} }
collapsibleTable(name: string) { collapsibleTable(name: string) {

View File

@ -1,28 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
export class GitRepoCreatePo extends PagePo {
static url: string;
private static createPath(
clusterId: string,
queryParams?: Record<string, string>
) {
const urlStr = `/c/${ clusterId }/fleet/management.cattle.io.fleetworkspace/create`;
if (!queryParams) {
return urlStr;
}
const params = new URLSearchParams(queryParams);
return `${ urlStr }?${ params.toString() }`;
}
static goTo(clusterId = 'local'): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(GitRepoCreatePo.createPath(clusterId));
}
constructor(clusterId: string) {
super(GitRepoCreatePo.createPath(clusterId));
}
}

View File

@ -1,10 +1,10 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import FleetBundlesCreateEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.bundle.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
export class FleetBundlesListPagePo extends PagePo { export class FleetBundlesListPagePo extends BaseListPagePo {
static url = `/c/_/fleet/fleet.cattle.io.bundle` static url = `/c/_/fleet/fleet.cattle.io.bundle`
constructor() { constructor() {
@ -16,9 +16,9 @@ export class FleetBundlesListPagePo extends PagePo {
} }
static navTo() { static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
@ -26,12 +26,38 @@ export class FleetBundlesListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced'); sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Bundles'); sideNav.navToSideMenuEntryByLabel('Bundles');
} }
}
sharedComponents() { export class FleetBundlesCreateEditPo extends BaseDetailPagePo {
return new SharedComponentsPo(this.self()); private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.bundle`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
} }
createBundlesForm(fleetWorkspace?: string, id?: string): FleetBundlesCreateEditPo { static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
return new FleetBundlesCreateEditPo(fleetWorkspace, id); throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetBundlesCreateEditPo.createPath(workspace, id));
}
}
export class FleetBundleDetailsPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace: string, bundleName: string) {
return `/c/_/fleet/fleet.cattle.io.bundle/${ fleetWorkspace }/${ bundleName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, bundleName: string) {
super(FleetBundleDetailsPo.createPath(fleetWorkspace, bundleName));
}
resourcesList() {
return new ResourceTablePo(this.self());
} }
} }

View File

@ -1,10 +1,9 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import FleetBundleNsMappingCreateEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.bundlenamespacemapping.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
export class FleetBundleNamespaceMappingListPagePo extends PagePo { export class FleetBundleNamespaceMappingListPagePo extends BaseListPagePo {
static url = `/c/_/fleet/fleet.cattle.io.bundlenamespacemapping` static url = `/c/_/fleet/fleet.cattle.io.bundlenamespacemapping`
constructor() { constructor() {
@ -16,9 +15,9 @@ export class FleetBundleNamespaceMappingListPagePo extends PagePo {
} }
static navTo() { static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
@ -26,12 +25,20 @@ export class FleetBundleNamespaceMappingListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced'); sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Bundle Namespace Mappings'); sideNav.navToSideMenuEntryByLabel('Bundle Namespace Mappings');
} }
}
sharedComponents() { export class FleetBundleNsMappingCreateEditPo extends BaseDetailPagePo {
return new SharedComponentsPo(this.self()); private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.bundlenamespacemapping`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
} }
createMappingForm(fleetWorkspace?: string, id?: string): FleetBundleNsMappingCreateEditPo { static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
return new FleetBundleNsMappingCreateEditPo(fleetWorkspace, id); throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetBundleNsMappingCreateEditPo.createPath(workspace, id));
} }
} }

View File

@ -1,11 +1,12 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import FleetClusterEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.cluster.po';
import AssignToDialogPo from '@/cypress/e2e/po/components/assign-to-dialog.po'; import AssignToDialogPo from '@/cypress/e2e/po/components/assign-to-dialog.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
export class FleetClusterListPagePo extends PagePo { export class FleetClusterListPagePo extends BaseListPagePo {
static url = `/c/_/fleet/fleet.cattle.io.cluster` static url = `/c/_/fleet/fleet.cattle.io.cluster`
constructor() { constructor() {
@ -17,9 +18,9 @@ export class FleetClusterListPagePo extends PagePo {
} }
static navTo() { static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
@ -27,10 +28,6 @@ export class FleetClusterListPagePo extends PagePo {
sideNav.navToSideMenuEntryByLabel('Clusters'); sideNav.navToSideMenuEntryByLabel('Clusters');
} }
sharedComponents() {
return new SharedComponentsPo(this.self());
}
selectWorkspace(workspaceName = 'fleet-local') { selectWorkspace(workspaceName = 'fleet-local') {
return this.header().selectWorkspace(workspaceName); return this.header().selectWorkspace(workspaceName);
} }
@ -43,3 +40,43 @@ export class FleetClusterListPagePo extends PagePo {
return new AssignToDialogPo(); return new AssignToDialogPo();
} }
} }
export class FleetClusterDetailsPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace: string, clusterName: string) {
return `/c/_/fleet/fleet.cattle.io.cluster/${ fleetWorkspace }/${ clusterName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, clusterName: string) {
super(FleetClusterDetailsPo.createPath(fleetWorkspace, clusterName));
}
clusterTabs(): TabbedPo {
return new TabbedPo();
}
gitReposList() {
return new ResourceTablePo('#repos [data-testid="sortable-table-list-container"]');
}
addRepostoryButton() {
return this.self().get('.btn').contains('Add Repository');
}
}
export class FleetClusterEditPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace: string, clusterName: string) {
return `/c/_/fleet/fleet.cattle.io.cluster/${ fleetWorkspace }/${ clusterName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace = 'fleet-default', clusterName: string) {
super(FleetClusterEditPo.createPath(fleetWorkspace, clusterName));
}
}

View File

@ -1,10 +1,11 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import FleetClusterGroupsCreateEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.clustergroup.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
export class FleetClusterGroupsListPagePo extends PagePo { export class FleetClusterGroupsListPagePo extends BaseListPagePo {
private static createPath(clusterId: string) { private static createPath(clusterId: string) {
return `/c/${ clusterId }/fleet/fleet.cattle.io.clustergroup`; return `/c/${ clusterId }/fleet/fleet.cattle.io.clustergroup`;
} }
@ -18,21 +19,51 @@ export class FleetClusterGroupsListPagePo extends PagePo {
} }
static navTo() { static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Cluster Groups'); sideNav.navToSideMenuEntryByLabel('Cluster Groups');
} }
}
sharedComponents() { export class FleetClusterGroupsCreateEditPo extends BaseDetailPagePo {
return new SharedComponentsPo(this.self()); private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.clustergroup`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
} }
createFleetClusterGroupsForm(workspace?: string, id? : string): FleetClusterGroupsCreateEditPo { static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
return new FleetClusterGroupsCreateEditPo(this.clusterId, workspace, id); throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetClusterGroupsCreateEditPo.createPath(workspace, id));
}
}
export class FleetClusterGroupDetailsPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace: string, clusterGroup: string) {
return `/c/_/fleet/fleet.cattle.io.clustergroup/${ fleetWorkspace }/${ clusterGroup }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, clusterName: string) {
super(FleetClusterGroupDetailsPo.createPath(fleetWorkspace, clusterName));
}
groupTabs(): TabbedPo {
return new TabbedPo();
}
clusterList() {
return new ResourceTablePo('#clusters [data-testid="sortable-table-list-container"]');
} }
} }

View File

@ -1,10 +1,9 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import FleetTokensCreateEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.clusterregistrationtoken.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
export class FleetClusterRegistrationTokenListPagePo extends PagePo { export class FleetClusterRegistrationTokenListPagePo extends BaseListPagePo {
static url = `/c/_/fleet/fleet.cattle.io.clusterregistrationtoken` static url = `/c/_/fleet/fleet.cattle.io.clusterregistrationtoken`
constructor() { constructor() {
@ -16,9 +15,9 @@ export class FleetClusterRegistrationTokenListPagePo extends PagePo {
} }
static navTo() { static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
@ -26,12 +25,20 @@ export class FleetClusterRegistrationTokenListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced'); sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Cluster Registration Tokens'); sideNav.navToSideMenuEntryByLabel('Cluster Registration Tokens');
} }
}
sharedComponents() { export class FleetTokensCreateEditPo extends BaseDetailPagePo {
return new SharedComponentsPo(this.self()); private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.clusterregistrationtoken`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
} }
createTokenForm(fleetWorkspace?: string, id?: string): FleetTokensCreateEditPo { static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
return new FleetTokensCreateEditPo(fleetWorkspace, id); throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetTokensCreateEditPo.createPath(workspace, id));
} }
} }

View File

@ -1,10 +1,13 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import FleetWorkspaceCreateEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.fleetworkspace.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
import ArrayListPo from '@/cypress/e2e/po/components/array-list.po';
import KeyValuePo from '@/cypress/e2e/po/components/key-value.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
export class FleetWorkspaceListPagePo extends PagePo { export class FleetWorkspaceListPagePo extends BaseListPagePo {
static url = `/c/_/fleet/management.cattle.io.fleetworkspace` static url = `/c/_/fleet/management.cattle.io.fleetworkspace`
constructor() { constructor() {
@ -16,9 +19,9 @@ export class FleetWorkspaceListPagePo extends PagePo {
} }
static navTo() { static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
@ -26,12 +29,54 @@ export class FleetWorkspaceListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced'); sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('Workspaces'); sideNav.navToSideMenuEntryByLabel('Workspaces');
} }
}
sharedComponents() { export class FleetWorkspaceCreateEditPo extends BaseDetailPagePo {
return new SharedComponentsPo(this.self()); private static createPath(fleetWorkspace?: string) {
const root = '/c/_/fleet/management.cattle.io.fleetworkspace';
return fleetWorkspace ? `${ root }/${ fleetWorkspace }` : `${ root }/create`;
} }
createWorkspaceForm(fleetWorkspace?: string): FleetWorkspaceCreateEditPo { static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
return new FleetWorkspaceCreateEditPo(fleetWorkspace); throw new Error('invalid');
}
constructor(fleetWorkspace?: string) {
super(FleetWorkspaceCreateEditPo.createPath(fleetWorkspace));
}
allowTargetNsTabList() {
return new ArrayListPo('section#allowedtargetnamespaces');
}
lablesAnnotationsKeyValue() {
return new KeyValuePo('section#labels');
}
}
export class FleetWorkspaceDetailsPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace: string) {
return `/c/_/fleet/management.cattle.io.fleetworkspace/${ fleetWorkspace }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string) {
super(FleetWorkspaceDetailsPo.createPath(fleetWorkspace));
}
workspaceTabs(): TabbedPo {
return new TabbedPo();
}
recentEventsList() {
return new ResourceTablePo('#events [data-testid="sortable-table-list-container"]');
}
relatedResourcesList(index: number) {
return new ResourceTablePo(`#related div:nth-of-type(${ index })[data-testid="sortable-table-list-container"]`);
} }
} }

View File

@ -1,9 +1,15 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
import ArrayListPo from '@/cypress/e2e/po/components/array-list.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
import SelectOrCreateAuthPo from '@/cypress/e2e/po/components/select-or-create-auth.po';
import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import ResourceTablePo from '@/cypress/e2e/po/components/resource-table.po';
export class FleetGitRepoListPagePo extends PagePo { export class FleetGitRepoListPagePo extends BaseListPagePo {
static url = `/c/_/fleet/fleet.cattle.io.gitrepo` static url = `/c/_/fleet/fleet.cattle.io.gitrepo`
constructor() { constructor() {
@ -15,19 +21,130 @@ export class FleetGitRepoListPagePo extends PagePo {
} }
navTo() { navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
sideNav.navToSideMenuEntryByLabel('Git Repos'); sideNav.navToSideMenuEntryByLabel('Git Repos');
this.sharedComponents().list().checkVisible(); this.list().checkVisible();
} }
}
sharedComponents() {
return new SharedComponentsPo(this.self()); export class FleetGitRepoCreateEditPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace?: string, gitRepoName?: string) {
const root = `/c/_/fleet/fleet.cattle.io.gitrepo`;
return fleetWorkspace ? `${ root }/${ fleetWorkspace }/${ gitRepoName }` : `${ root }/create`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace?: string, gitRepoName?: string) {
super(FleetGitRepoCreateEditPo.createPath(fleetWorkspace, gitRepoName));
}
setBranchName(branch = 'dashboard-e2e-basic') {
return LabeledInputPo.byLabel(this.self(), 'Branch').set(branch);
}
setGitRepoUrl(url: string) {
return LabeledInputPo.byLabel(this.self(), 'Repository URL').set(url);
}
setHelmRepoURLRegex(regexStr = 'https://charts.rancher.io/*') {
return LabeledInputPo.bySelector(this.self(), '[data-testid="gitrepo-helm-repo-url-regex"]').set(regexStr);
}
setGitRepoPath(path: string, index = 0) {
return this.gitRepoPaths().setValueAtIndex(path, index);
}
targetCluster(): LabeledSelectPo {
return new LabeledSelectPo('[data-testid="fleet-gitrepo-target-cluster"]');
}
gitRepoPaths() {
return new ArrayListPo('[data-testid="gitRepo-paths"]');
}
authSelectOrCreate(selector: string) {
return new SelectOrCreateAuthPo(selector);
}
helmAuthSelectOrCreate() {
return this.authSelectOrCreate('[data-testid="gitrepo-helm-auth"]');
}
gitAuthSelectOrCreate() {
return this.authSelectOrCreate('[data-testid="gitrepo-git-auth"]');
}
setPollingInterval(value: number) {
return LabeledInputPo.byLabel(this.self(), 'Polling Interval').set(value);
}
displayAlwaysKeepInformationMessage() {
this.self().get('[data-testid="checkbox-info-icon"]').eq(0).as('always');
cy.get('@always').realHover();
cy.get('@always').should('have.attr', 'data-popper-shown');
}
displayPollingInvervalTimeInformationMessage() {
this.self().get('[data-testid="checkbox-info-icon"]').eq(1).as('polling');
cy.get('@polling').realHover();
cy.get('@polling').should('have.attr', 'data-popper-shown');
}
displaySelfHealingInformationMessage() {
this.self().get('[data-testid="labeledTooltip-info-icon"]').eq(0).as('selfhealingicon');
cy.get('@selfhealingicon').realHover();
cy.get('@selfhealingicon').should('have.attr', 'data-popper-shown');
}
}
export class FleetGitRepoDetailsPo extends BaseDetailPagePo {
private static createPath(fleetWorkspace: string, gitRepoName: string) {
return `/c/_/fleet/fleet.cattle.io.gitrepo/${ fleetWorkspace }/${ gitRepoName }`;
}
static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
throw new Error('invalid');
}
constructor(fleetWorkspace: string, gitRepoName: string) {
super(FleetGitRepoDetailsPo.createPath(fleetWorkspace, gitRepoName));
}
gitRepoTabs(): TabbedPo {
return new TabbedPo();
}
bundlesCount(): Cypress.Chainable {
return this.self().find('[data-testid="gitrepo-bundle-summary"] .count').invoke('text');
}
bundlesList() {
return new ResourceTablePo('#bundles [data-testid="sortable-table-list-container"]');
}
shwoConfig() {
this.self().find('[data-testid="button-group-child-1"]').click();
}
showGraph() {
this.self().find('[data-testid="button-group-child-2"]').click();
}
graph() {
return this.self().find('[data-testid="gitrepo_graph"]');
} }
} }

View File

@ -1,10 +1,9 @@
import PagePo from '@/cypress/e2e/po/pages/page.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po'; import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import FleetRestrictionCreateEditPo from '@/cypress/e2e/po/edit/fleet/fleet.cattle.io.gitreporestriction.po'; import { BaseListPagePo } from '@/cypress/e2e/po/pages/base/base-list-page.po';
import { BaseDetailPagePo } from '@/cypress/e2e/po/pages/base/base-detail-page.po';
export class FleetGitRepoRestrictionListPagePo extends PagePo { export class FleetGitRepoRestrictionListPagePo extends BaseListPagePo {
static url = `/c/_/fleet/fleet.cattle.io.gitreporestriction` static url = `/c/_/fleet/fleet.cattle.io.gitreporestriction`
constructor() { constructor() {
@ -16,9 +15,9 @@ export class FleetGitRepoRestrictionListPagePo extends PagePo {
} }
static navTo() { static navTo() {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
const sideNav = new ProductNavPo(); const sideNav = new ProductNavPo();
@ -26,12 +25,20 @@ export class FleetGitRepoRestrictionListPagePo extends PagePo {
sideNav.navToSideMenuGroupByLabel('Advanced'); sideNav.navToSideMenuGroupByLabel('Advanced');
sideNav.navToSideMenuEntryByLabel('GitRepoRestrictions'); sideNav.navToSideMenuEntryByLabel('GitRepoRestrictions');
} }
}
sharedComponents() { export class FleetRestrictionCreateEditPo extends BaseDetailPagePo {
return new SharedComponentsPo(this.self()); private static createPath(workspace?: string, id?: string ) {
const root = `/c/_/fleet/fleet.cattle.io.gitreporestriction`;
return id ? `${ root }/${ workspace }/${ id }` : `${ root }/create`;
} }
createRestrictionForm(fleetWorkspace?: string, id?: string): FleetRestrictionCreateEditPo { static goTo(path: string): Cypress.Chainable<Cypress.AUTWindow> {
return new FleetRestrictionCreateEditPo(fleetWorkspace, id); throw new Error('invalid');
}
constructor(workspace?: string, id?: string) {
super(FleetRestrictionCreateEditPo.createPath(workspace, id));
} }
} }

View File

@ -1,106 +0,0 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import { SharedComponentsPo } from '@/cypress/e2e/po/components/shared-components/shared-components.po';
import ArrayListPo from '@/cypress/e2e/po/components/array-list.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
import SelectOrCreateAuthPo from '@/cypress/e2e/po/components/select-or-create-auth.po';
import { FleetGitRepoListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po';
export class GitRepoCreatePo extends PagePo {
static url: string;
private static createPath(
clusterId: string,
queryParams?: Record<string, string>
) {
const urlStr = `/c/${ clusterId }/fleet/fleet.cattle.io.gitrepo/create`;
if (!queryParams) {
return urlStr;
}
const params = new URLSearchParams(queryParams);
return `${ urlStr }?${ params.toString() }`;
}
static goTo(clusterId = 'local'): Cypress.Chainable<Cypress.AUTWindow> {
return super.goTo(GitRepoCreatePo.createPath(clusterId));
}
constructor(clusterId: string) {
super(GitRepoCreatePo.createPath(clusterId));
}
static navTo() {
const listPage = new FleetGitRepoListPagePo();
listPage.navTo();
listPage.sharedComponents().resourceDetail().createEditView().create();
}
sharedComponents() {
return new SharedComponentsPo(this.self());
}
setBranchName(branch = 'dashboard-e2e-basic') {
return LabeledInputPo.byLabel(this.self(), 'Branch').set(branch);
}
setGitRepoUrl(url: string) {
return LabeledInputPo.byLabel(this.self(), 'Repository URL').set(url);
}
setHelmRepoURLRegex(regexStr = 'https://charts.rancher.io/*') {
return LabeledInputPo.bySelector(this.self(), '[data-testid="gitrepo-helm-repo-url-regex"]').set(regexStr);
}
setGitRepoPath(path: string, index = 0) {
return this.gitRepoPaths().setValueAtIndex(path, index);
}
targetCluster(): LabeledSelectPo {
return new LabeledSelectPo('[data-testid="fleet-gitrepo-target-cluster"]');
}
gitRepoPaths() {
return new ArrayListPo('[data-testid="gitRepo-paths"]');
}
authSelectOrCreate(selector: string) {
return new SelectOrCreateAuthPo(selector);
}
helmAuthSelectOrCreate() {
return this.authSelectOrCreate('[data-testid="gitrepo-git-auth"]');
}
gitAuthSelectOrCreate() {
return this.authSelectOrCreate('[data-testid="gitrepo-helm-auth"]');
}
setPollingInterval(value: number) {
return LabeledInputPo.byLabel(this.self(), 'Polling Interval').set(value);
}
displayAlwaysKeepInformationMessage() {
this.self().get('[data-testid="checkbox-info-icon"]').eq(0).as('always');
cy.get('@always').realHover();
cy.get('@always').should('have.attr', 'data-popper-shown');
}
displayPollingInvervalTimeInformationMessage() {
this.self().get('[data-testid="checkbox-info-icon"]').eq(1).as('polling');
cy.get('@polling').realHover();
cy.get('@polling').should('have.attr', 'data-popper-shown');
}
displaySelfHealingInformationMessage() {
this.self().get('[data-testid="labeledTooltip-info-icon"]').eq(0).as('selfhealingicon');
cy.get('@selfhealingicon').realHover();
cy.get('@selfhealingicon').should('have.attr', 'data-popper-shown');
}
}

View File

@ -0,0 +1,20 @@
import DialogPo from '@/cypress/e2e/po/components/dialog.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
import ComponentPo from '@/cypress/e2e/po/components/component.po';
export default class GenericDialog extends ComponentPo {
private dialog: DialogPo;
constructor(selector = '#modal-container-element') {
super(selector);
this.dialog = new DialogPo(selector);
}
labeledSelect(selector = '.labeled-select'): LabeledSelectPo {
return new LabeledSelectPo(selector);
}
clickActionButton(text: string) {
return this.dialog.getActionButton().contains(text).click();
}
}

View File

@ -1,5 +1,6 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po'; import ComponentPo from '@/cypress/e2e/po/components/component.po';
import CardPo from '@/cypress/e2e/po/components/card.po'; import CardPo from '@/cypress/e2e/po/components/card.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
export default class GenericPrompt extends ComponentPo { export default class GenericPrompt extends ComponentPo {
card = new CardPo(); card = new CardPo();
@ -12,11 +13,11 @@ export default class GenericPrompt extends ComponentPo {
return this.card.getBody(); return this.card.getBody();
} }
cancel() { labeledSelect(selector = '.labeled-select'): LabeledSelectPo {
return this.self().find('.btn role-secondary'); return new LabeledSelectPo(selector);
} }
submit(text: string) { clickActionButton(text: string) {
return this.card.getActionButton().contains(text).click(); return this.card.getActionButton().contains(text).click();
} }
} }

View File

@ -24,7 +24,7 @@ export default class PromptRemove extends ComponentPo {
} }
cancel() { cancel() {
return this.self().get('.btn.role-secondary').click(); return this.self().get('.btn.role-secondary').contains('Cancel').click();
} }
// Get the warning message // Get the warning message

View File

@ -0,0 +1,10 @@
import GenericPrompt from '@/cypress/e2e/po/prompts/genericPrompt.po';
import GenericDialog from '@/cypress/e2e/po/prompts/genericDialog.po';
export function promptModal(): GenericPrompt {
return new GenericPrompt('.modal-container');
}
export function dialogModal(): GenericDialog {
return new GenericDialog();
}

View File

@ -1,5 +0,0 @@
import GenericPrompt from '@/cypress/e2e/po/prompts/genericPrompt.po';
export function promptModal(): GenericPrompt {
return new GenericPrompt('.prompt-restore');
}

View File

@ -2,10 +2,17 @@ import ComponentPo from '@/cypress/e2e/po/components/component.po';
export default class SlideInPo extends ComponentPo { export default class SlideInPo extends ComponentPo {
constructor() { constructor() {
super('[data-testid="slide-in-panel"]'); super('[data-testid="slide-in-panel-resource-explain"]');
}
waitforContent() {
return this.self().find('.explain-panel').should('be.visible').within(() => {
cy.get('.icon-spinner').should('not.exist');
cy.get('.markdown').should('be.visible');
});
} }
closeButton() { closeButton() {
return this.self().get('[data-testid="slide-in-panel-close"'); return this.self().get('[data-testid="slide-in-panel-close-resource-explain"');
} }
} }

View File

@ -19,6 +19,29 @@ import PodSecurityAdmissionsPagePo from '@/cypress/e2e/po/pages/cluster-manager/
import BannersPo from '@/cypress/e2e/po/components/banners.po'; import BannersPo from '@/cypress/e2e/po/components/banners.po';
import { HomeLinksPagePo } from '@/cypress/e2e/po/pages/global-settings/home-links.po'; import { HomeLinksPagePo } from '@/cypress/e2e/po/pages/global-settings/home-links.po';
import ChartRepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po'; import ChartRepositoriesPagePo from '@/cypress/e2e/po/pages/chart-repositories.po';
import { EventsCreateEditPo, EventsPageListPo } from '@/cypress/e2e/po/pages/explorer/events.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import { ProjectsNamespacesListPagePo, NamespaceCreateEditPagePo, ProjectCreateEditPagePo } from '@/cypress/e2e/po/pages/explorer/projects-namespaces.po';
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
import { dialogModal, promptModal } from '@/cypress/e2e/po/prompts/shared/modalInstances.po';
import ClusterToolsPagePo from '@/cypress/e2e/po/pages/explorer/cluster-tools.po';
import { WorkloadsListPageBasePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads.po';
import { WorkLoadsDaemonsetsCreatePagePo, WorkloadsDaemonsetsListPagePo } from '@/cypress/e2e/po/pages/explorer/workloads-daemonsets.po';
import { ChartPage } from '@/cypress/e2e/po/pages/explorer/charts/chart.po';
import { MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import { SecretsCreateEditPo, SecretsListPagePo } from '@/cypress/e2e/po/pages/explorer/secrets.po';
import SlideInPo from '@/cypress/e2e/po/side-bars/slide-in.po';
import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
import DigitalOceanCloudCredentialsCreateEditPo from '@/cypress/e2e/po/edit/cloud-credentials-digitalocean.po';
import KontainerDriversPagePo from '@/cypress/e2e/po/pages/cluster-manager/kontainer-drivers.po';
import UsersPo from '@/cypress/e2e/po/pages/users-and-auth/users.po';
import UserRetentionPo from '@/cypress/e2e/po/pages/users-and-auth/user.retention.po';
import ResourceSearchDialog from '@/cypress/e2e/po/prompts/ResourceSearchDialog.po';
import { StorageClassesPagePo } from '@/cypress/e2e/po/pages/explorer/storage-classes.po';
import { BrandingPagePo } from '@/cypress/e2e/po/pages/global-settings/branding.po';
import { BannersPagePo } from '@/cypress/e2e/po/pages/global-settings/banners.po';
import { USERS_BASE_URL } from '@/cypress/support/utils/api-endpoints';
import { FleetGitRepoCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po';
describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () => { describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () => {
describe('Login page', () => { describe('Login page', () => {
@ -78,11 +101,25 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkPageAccessibility(); cy.checkPageAccessibility();
}); });
describe('Accounts', () => { it('Fleet GitRepo - Add Repository page', () => {
const gitRepoCreatePage = new FleetGitRepoCreateEditPo();
gitRepoCreatePage.goTo();
gitRepoCreatePage.waitForPage();
gitRepoCreatePage.resourceDetail().createEditView().nameNsDescription()
.name()
.checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
describe('Account and API Keys', () => {
const accountPage = new AccountPagePo(); const accountPage = new AccountPagePo();
const createKeyPage = new CreateKeyPagePo(); const createKeyPage = new CreateKeyPagePo();
it('Account', () => { it('Account and API Keys Page', () => {
accountPage.goTo(); accountPage.goTo();
accountPage.waitForPage(); accountPage.waitForPage();
accountPage.title(); accountPage.title();
@ -91,7 +128,7 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkPageAccessibility(); cy.checkPageAccessibility();
}); });
it('Change password dialog', () => { it('Change Password dialog', () => {
accountPage.changePassword(); accountPage.changePassword();
accountPage.currentPassword().checkVisible(); accountPage.currentPassword().checkVisible();
cy.injectAxe(); cy.injectAxe();
@ -100,33 +137,48 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkElementAccessibility(el); cy.checkElementAccessibility(el);
}); });
accountPage.cancel(); promptModal().clickActionButton('Cancel');
}); });
it('Create API key', () => { it('API Key - Create', () => {
accountPage.create(); accountPage.create();
createKeyPage.waitForPage(); createKeyPage.waitForPage();
createKeyPage.mastheadTitle().then((el) => { createKeyPage.mastheadTitle().then((title) => {
expect(el.trim()).to.include('API Key'); expect(title.replace(/\s+/g, ' ')).to.contain('API Key: Create');
}); });
cy.injectAxe(); cy.injectAxe();
cy.checkPageAccessibility(); cy.checkPageAccessibility();
createKeyPage.cancel();
accountPage.waitForPage();
});
it('API Key - Delete', () => {
accountPage.title();
accountPage.list().resourceTable().sortableTable().selectAllCheckbox()
.set();
accountPage.list().resourceTable().sortableTable().deleteButton()
.click();
cy.injectAxe();
cy.checkPageAccessibility();
}); });
}); });
describe('Cluster Dashboard', () => { describe('Explorer', () => {
describe('Cluster', () => {
const clusterDashboard = new ClusterDashboardPagePo('local'); const clusterDashboard = new ClusterDashboardPagePo('local');
it('Cluster dashboard page', () => { it('Cluster Dashboard page', () => {
ClusterDashboardPagePo.navTo(); clusterDashboard.goTo();
clusterDashboard.waitForPage(); clusterDashboard.waitForPage();
cy.injectAxe(); cy.injectAxe();
cy.checkPageAccessibility(); cy.checkPageAccessibility();
}); });
it('Cluster appearance dialog', () => { it('Cluster Appearance Modal', () => {
clusterDashboard.customizeAppearanceButton().click(); clusterDashboard.customizeAppearanceButton().click();
const customClusterCard = new CardPo(); const customClusterCard = new CardPo();
@ -138,15 +190,327 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkElementAccessibility(el); cy.checkElementAccessibility(el);
}); });
customClusterCard.getActionButton().contains('Cancel').click(); promptModal().clickActionButton('Cancel');
});
describe('Projects-Namespaces', () => {
const projectsNamespacesPage = new ProjectsNamespacesListPagePo();
const createProjectPage = new ProjectCreateEditPagePo();
const createNamespacePage = new NamespaceCreateEditPagePo();
it('Projects-Namespaces - Move dialog', () => {
ProjectsNamespacesListPagePo.navTo();
projectsNamespacesPage.waitForPage();
projectsNamespacesPage.list().resourceTable().sortableTable().rowActionMenuOpen('cattle-fleet-system')
.getMenuItem('Move')
.click();
cy.injectAxe();
promptModal().self().then((el) => {
cy.checkElementAccessibility(el);
});
promptModal().clickActionButton('Cancel');
});
it('Projects-Namespaces - Delete Project dialog', () => {
projectsNamespacesPage.waitForPage();
projectsNamespacesPage.list().resourceTable().sortableTable().groupByButtons(1)
.click();
projectsNamespacesPage.list().resourceTable().sortableTable().rowActionMenuOpen('Project: Default')
.getMenuItem('Delete')
.click();
const promptRemove = new PromptRemove();
cy.injectAxe();
promptRemove.self().then((el) => {
cy.checkElementAccessibility(el);
});
promptRemove.cancel();
});
it('Projects-Namespaces - Create Project', () => {
projectsNamespacesPage.waitForPage();
projectsNamespacesPage.baseResourceList().masthead().create();
projectsNamespacesPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Project: Create');
});
createProjectPage.waitForPage(null, 'members');
createProjectPage.resourceDetail().createEditView()
.nameNsDescription()
.name()
.checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Projects-Namespaces - Add Project Member', () => {
createProjectPage.goTo();
createProjectPage.waitForPage();
createProjectPage.addProjectMemberButton().should('be.visible');
createProjectPage.addProjectMemberButton().click();
promptModal().getBody().should('be.visible');
cy.injectAxe();
promptModal().self().then((el) => {
cy.checkElementAccessibility(el);
});
promptModal().clickActionButton('Cancel');
createProjectPage.resourceDetail().cruResource()
.cancel()
.click();
});
it('Projects-Namespaces - Create Namespace', () => {
projectsNamespacesPage.waitForPage();
projectsNamespacesPage.list().resourceTable().sortableTable().groupByButtons(0)
.click();
projectsNamespacesPage.createNamespaceButton().should('be.visible').click();
projectsNamespacesPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Namespace: Create');
});
createNamespacePage.waitForPage('flatView=true', 'container-resource-limit');
createNamespacePage.resourceDetail().createEditView()
.nameNsDescription()
.name()
.checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
createNamespacePage.resourceDetail().cruResource()
.cancel()
.click();
});
it('Projects-Namespaces Page', () => {
projectsNamespacesPage.waitForPage();
projectsNamespacesPage.list().masthead().title().should('contain', 'Projects/Namespaces');
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Tools', () => {
it('Cluster Tools Page', () => {
const clusterTools = new ClusterToolsPagePo('local');
ClusterToolsPagePo.navTo();
clusterTools.waitForPage();
clusterTools.featureChartCards().should('be.visible');
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Events', () => {
const events = new EventsPageListPo('local');
it('Cluster events page', () => {
EventsPageListPo.navTo();
events.waitForPage();
events.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Create event from YAML', () => {
const createEventPage = new EventsCreateEditPo();
EventsPageListPo.navTo();
events.waitForPage();
events.baseResourceList().masthead().createYaml();
createEventPage.waitForPage('as=yaml');
events.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Event: Create');
});
createEventPage.resourceDetail().resourceYaml()
.codeMirror()
.checkExists();
cy.injectAxe();
cy.checkPageAccessibility();
createEventPage.resourceDetail().resourceYaml()
.cancel();
});
});
});
describe('Workloads', () => {
it('Workloads page', () => {
const workloadsListPage = new WorkloadsListPageBasePo('local', 'workload');
WorkloadsListPageBasePo.navTo();
workloadsListPage.waitForPage();
workloadsListPage.sortableTable().checkLoadingIndicatorNotVisible();
// expand the health scale up/down control
workloadsListPage.details('rancher', 8).should('be.visible');
workloadsListPage.details('rancher', 8).click();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Deployments page', () => {
const deploymentsListPage = new WorkloadsDeploymentsListPagePo();
deploymentsListPage.goTo();
deploymentsListPage.waitForPage();
deploymentsListPage.sortableTable().checkLoadingIndicatorNotVisible();
// expand the health scale up/down control
deploymentsListPage.sortableTable().getTableCell(1, 10).click();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('DeamonSets - Create', () => {
const daemonsetsListPage = new WorkloadsDaemonsetsListPagePo();
const daemonsetsCreatePage = new WorkLoadsDaemonsetsCreatePagePo('local');
daemonsetsListPage.goTo();
daemonsetsListPage.waitForPage();
daemonsetsListPage.baseResourceList().masthead().create();
daemonsetsCreatePage.waitForPage();
daemonsetsCreatePage.resourceDetail().createEditView().nameNsDescription()
.name()
.checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
daemonsetsCreatePage.resourceDetail().cruResource()
.cancel()
.click();
});
});
describe('Storage', () => {
it('Secret - Create page', () => {
const secretsListPage = new SecretsListPagePo('local');
const secretsCreatePage = new SecretsCreateEditPo('local');
SecretsListPagePo.navTo();
secretsListPage.waitForPage();
secretsListPage.baseResourceList().masthead().create();
secretsCreatePage.waitForPage();
secretsCreatePage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Secret: Create');
});
secretsCreatePage.resourceDetail().cruResource().findSubTypeByName('custom')
.should('be.visible');
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Secret - Describe Resource', () => {
const header = new HeaderPo();
const slideIn = new SlideInPo();
header.kubectlExplain().click();
slideIn.checkVisible();
slideIn.waitforContent();
cy.injectAxe();
cy.checkPageAccessibility();
slideIn.closeButton().click();
slideIn.checkNotVisible();
});
it('Storage Class - Create', () => {
const storageClasses = new StorageClassesPagePo();
storageClasses.goTo();
storageClasses.waitForPage();
storageClasses.clickCreate();
storageClasses.createStorageClassesForm().waitForPage(null, 'parameters');
storageClasses.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('StorageClass: Create');
});
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Header', () => {
const header = new HeaderPo();
it('Import YAML', () => {
const clusterDashboard = new ClusterDashboardPagePo('local');
ClusterDashboardPagePo.navTo();
clusterDashboard.waitForPage();
header.importYamlHeaderAction().click();
header.importYaml().checkVisible();
cy.injectAxe();
header.importYaml().self().then((el: any) => {
cy.checkElementAccessibility(el);
});
header.importYaml().importYamlCancelClick();
header.importYaml().checkNotExists();
});
it('Kubectl Shell', () => {
header.kubectlShell().openTerminal();
header.kubectlShell().waitForTerminalToBeVisible();
cy.injectAxe();
header.kubectlShell().self().then((el: any) => {
cy.checkElementAccessibility(el);
});
header.kubectlShell().closeTerminal();
});
it('Resource Search', () => {
const dialog = new ResourceSearchDialog();
header.resourceSearchButton().click();
dialog.searchBox().should('be.visible');
cy.injectAxe();
dialog.self().then((el: any) => {
cy.checkElementAccessibility(el);
});
dialog.close();
dialog.checkNotExists();
});
}); });
}); });
describe('Cluster Management', () => { describe('Cluster Management', () => {
it('Clusters - Create page', () => {
const createClusterPage = new ClusterManagerCreatePagePo(); const createClusterPage = new ClusterManagerCreatePagePo();
const loadingPo = new LoadingPo('.loading-indicator'); const loadingPo = new LoadingPo('.loading-indicator');
it('Clusters - Create page', () => {
createClusterPage.goTo(); createClusterPage.goTo();
createClusterPage.waitForPage(); createClusterPage.waitForPage();
loadingPo.checkNotExists(); loadingPo.checkNotExists();
@ -164,6 +528,73 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
}); });
}); });
it('Cluster - Create Digital Ocean Cloud Credential', () => {
const clusterList = new ClusterManagerListPagePo();
ClusterManagerListPagePo.navTo();
clusterList.waitForPage();
clusterList.createCluster();
createClusterPage.rkeToggle().set('RKE2/K3s');
createClusterPage.selectCreate(2);
loadingPo.checkNotExists();
createClusterPage.rke2PageTitle().should('include', 'Create DigitalOcean');
createClusterPage.waitForPage('type=digitalocean&rkeType=rke2');
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Cluster - Create Digital Ocean', () => {
const cloudCredForm = new DigitalOceanCloudCredentialsCreateEditPo();
// fake cloud credential authentication
cy.intercept('GET', '/meta/proxy/api.digitalocean.com/v2/regions?per_page=1000', (req) => {
req.reply({ statusCode: 200 });
}).as('doCloudCred');
// create fake cloud credential
cloudCredForm.credentialName().set('doCloudCredName');
cloudCredForm.accessToken().set('fakeToken');
cloudCredForm.saveCreateForm().cruResource().saveOrCreate().click();
cy.wait('@doCloudCred');
createClusterPage.waitForPage('type=digitalocean&rkeType=rke2', 'basic');
createClusterPage.rke2PageTitle().should('include', 'Create DigitalOcean');
cy.injectAxe();
cy.checkPageAccessibility();
// delete digital ocean cloud credential
cy.getRancherResource('v3', 'cloudcredentials', null, null).then((resp: Cypress.Response<any>) => {
const body = resp.body;
if (body.pagination['total'] > 0) {
body.data.forEach((item: any) => {
if (item.digitaloceancredentialConfig) {
const id = item.id;
cy.deleteRancherResource('v3', 'cloudcredentials', id);
}
});
}
});
});
it('Cluster drivers page', () => {
const driversPage = new KontainerDriversPagePo();
KontainerDriversPagePo.navTo();
driversPage.waitForPage();
driversPage.list().masthead().title().should('contain', 'Cluster Drivers');
driversPage.list().resourceTable().sortableTable().checkVisible();
driversPage.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
it('Pod Security Admissions - Create page', () => { it('Pod Security Admissions - Create page', () => {
const podSecurityAdmissionsPage = new PodSecurityAdmissionsPagePo(); const podSecurityAdmissionsPage = new PodSecurityAdmissionsPagePo();
@ -201,19 +632,55 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
}); });
}); });
it('Deployments page', () => { describe('Users', () => {
const deploymentsListPage = new WorkloadsDeploymentsListPagePo(); const usersPo = new UsersPo('_');
deploymentsListPage.goTo(); it('Users page', () => {
deploymentsListPage.waitForPage(); cy.intercept('GET', `${ USERS_BASE_URL }?exclude=metadata.managedFields`).as('getUsers');
deploymentsListPage.sortableTable().checkLoadingIndicatorNotVisible();
// expand the health scale up/down control usersPo.goTo();
deploymentsListPage.sortableTable().getTableCell(1, 10).click(); usersPo.waitForPage();
usersPo.list().masthead().title().should('contain', 'Users');
cy.wait('@getUsers');
usersPo.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
usersPo.list().refreshGroupMembership().checkVisible();
cy.injectAxe(); cy.injectAxe();
cy.checkPageAccessibility(); cy.checkPageAccessibility();
}); });
it('Users - Create page', () => {
const userCreate = usersPo.createEdit();
usersPo.list().masthead().create();
userCreate.waitForPage();
userCreate.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('User: Create');
});
userCreate.username().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
userCreate.resourceDetail().cruResource().cancel()
.click();
usersPo.waitForPage();
});
it('User Retention Settings', () => {
const userRetentionPo = new UserRetentionPo();
usersPo.userRetentionLink().click();
userRetentionPo.waitForPage();
userRetentionPo.disableAfterPeriodCheckbox().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Charts', () => {
it('Charts page', () => { it('Charts page', () => {
const chartsPage = new ChartsPage(); const chartsPage = new ChartsPage();
@ -225,25 +692,71 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkPageAccessibility(); cy.checkPageAccessibility();
}); });
it('Extensions page', () => { it('Chart Detail Page - Kubecost', () => {
const chartPage = new ChartPage();
ChartPage.navTo(null, 'Kubecost');
chartPage.waitForChartPage('rancher-partner-charts', 'cost-analyzer');
chartPage.waitForChartHeader('Kubecost', MEDIUM_TIMEOUT_OPT);
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Extensions', () => {
const extensionsPo = new ExtensionsPagePo(); const extensionsPo = new ExtensionsPagePo();
it('Extensions page', () => {
// Set the preference // Set the preference
cy.setUserPreference({ 'plugin-developer': true }); cy.setUserPreference({ 'plugin-developer': true });
extensionsPo.goTo(); extensionsPo.goTo();
extensionsPo.waitForPage(null, 'available'); extensionsPo.waitForPage(null, 'available');
extensionsPo.loading().should('not.exist'); extensionsPo.loading().should('not.exist');
extensionsPo.extensionTabBuiltin().checkExists(); extensionsPo.extensionTabAllClick();
extensionsPo.extensionTabBuiltinClick(); extensionsPo.waitForPage(null, 'all');
extensionsPo.waitForPage(null, 'builtin');
extensionsPo.extensionCard('aks').should('be.visible'); extensionsPo.extensionCard('aks').should('be.visible');
cy.injectAxe(); cy.injectAxe();
cy.checkPageAccessibility(); cy.checkPageAccessibility();
}); });
it('Global Settings page', () => { it('Add Rancher Repositories Modal', () => {
extensionsPo.extensionMenuToggle();
extensionsPo.addRepositoriesClick();
dialogModal().checkVisible();
cy.injectAxe();
dialogModal().self().then((el) => {
cy.checkElementAccessibility(el);
});
dialogModal().clickActionButton('Cancel');
});
it('Import Extension Catalog Modal', () => {
extensionsPo.extensionMenuToggle();
extensionsPo.manageExtensionCatalogsClick();
extensionsPo.catalogsList().sortableTable()
.bulkActionButton('Import Extension Catalog')
.click();
dialogModal().checkVisible();
cy.injectAxe();
dialogModal().self().then((el) => {
cy.checkElementAccessibility(el);
});
dialogModal().clickActionButton('Cancel');
});
});
describe('Global Settings', () => {
it('Settings page', () => {
const settingsPage = new SettingsPagePo('local'); const settingsPage = new SettingsPagePo('local');
SettingsPagePo.navTo(); SettingsPagePo.navTo();
@ -273,20 +786,34 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
cy.checkPageAccessibility(); cy.checkPageAccessibility();
}); });
it('Branding page', () => {
const brandingPage = new BrandingPagePo();
BrandingPagePo.navTo();
brandingPage.privateLabel().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
}); });
describe('Menus', { testIsolation: 'off' }, () => { it('Banners page', () => {
const homePage = new HomePagePo(); const bannersPage = new BannersPagePo();
BannersPagePo.navTo();
bannersPage.headerBannerCheckbox().checkVisible();
cy.injectAxe();
cy.checkPageAccessibility();
});
});
describe('Menus', () => {
const burgerMenu = new BurgerMenuPo(); const burgerMenu = new BurgerMenuPo();
const userMenu = new UserMenuPo();
before(() => {
cy.login();
});
it('User Menu', () => { it('User Menu', () => {
HomePagePo.navTo(); const userMenu = new UserMenuPo();
homePage.waitForPage();
userMenu.ensureOpen(); userMenu.ensureOpen();
cy.injectAxe(); cy.injectAxe();
@ -296,8 +823,8 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
}); });
it('Burger Menu', () => { it('Burger Menu', () => {
HomePagePo.navTo(); // HomePagePo.navTo();
homePage.waitForPage(); // homePage.waitForPage();
burgerMenu.checkVisible(); burgerMenu.checkVisible();
BurgerMenuPo.toggle(); BurgerMenuPo.toggle();
cy.injectAxe(); cy.injectAxe();
@ -331,6 +858,7 @@ describe('Shell a11y testing', { tags: ['@adminUser', '@accessibility'] }, () =>
}); });
}); });
}); });
});
after(() => { after(() => {
cy.updateNamespaceFilter('local', 'none', '{"local":["all://user"]}'); cy.updateNamespaceFilter('local', 'none', '{"local":["all://user"]}');

View File

@ -7,7 +7,7 @@ import { LoggingClusterflowEditPagePo, LoggingClusterflowListPagePo } from '@/cy
import Kubectl from '@/cypress/e2e/po/components/kubectl.po'; import Kubectl from '@/cypress/e2e/po/components/kubectl.po';
import ClusterToolsPagePo from '@/cypress/e2e/po/pages/explorer/cluster-tools.po'; import ClusterToolsPagePo from '@/cypress/e2e/po/pages/explorer/cluster-tools.po';
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
import ChartInstalledAppsPagePo from '@/cypress/e2e/po/pages/chart-installed-apps.po'; import ChartInstalledAppsListPagePo from '@/cypress/e2e/po/pages/chart-installed-apps.po';
import { MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; import { MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import { CLUSTER_APPS_BASE_URL } from '@/cypress/support/utils/api-endpoints'; import { CLUSTER_APPS_BASE_URL } from '@/cypress/support/utils/api-endpoints';
@ -77,14 +77,15 @@ describe('Logging Chart', { testIsolation: 'off', tags: ['@charts', '@adminUser'
cy.intercept('GET', `${ CLUSTER_APPS_BASE_URL }?exclude=metadata.managedFields`).as('getCharts'); cy.intercept('GET', `${ CLUSTER_APPS_BASE_URL }?exclude=metadata.managedFields`).as('getCharts');
const clusterTools = new ClusterToolsPagePo('local'); const clusterTools = new ClusterToolsPagePo('local');
const installedAppsPage = new ChartInstalledAppsPagePo('local', 'apps'); const installedAppsPage = new ChartInstalledAppsListPagePo('local', 'apps');
installedAppsPage.goTo(); installedAppsPage.goTo();
installedAppsPage.waitForPage(); installedAppsPage.waitForPage();
installedAppsPage.sharedComponents(MEDIUM_TIMEOUT_OPT).resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); cy.wait('@getCharts', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
installedAppsPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist(); installedAppsPage.appsList().sortableTable().checkLoadingIndicatorNotVisible();
installedAppsPage.sharedComponents().resourceTableDetails(chartApp, 1).should('exist'); installedAppsPage.appsList().sortableTable().noRowsShouldNotExist();
installedAppsPage.sharedComponents().resourceTableDetails(chartCrd, 1).should('exist'); installedAppsPage.appsList().resourceTableDetails(chartApp, 1).should('exist');
installedAppsPage.appsList().resourceTableDetails(chartCrd, 1).should('exist');
clusterTools.goTo(); clusterTools.goTo();
clusterTools.waitForPage(); clusterTools.waitForPage();
@ -110,13 +111,13 @@ describe('Logging Chart', { testIsolation: 'off', tags: ['@charts', '@adminUser'
installedAppsPage.goTo(); installedAppsPage.goTo();
installedAppsPage.waitForPage(); installedAppsPage.waitForPage();
installedAppsPage.sharedComponents(MEDIUM_TIMEOUT_OPT).resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); cy.wait('@getCharts', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
installedAppsPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist(); installedAppsPage.appsList().sortableTable().checkLoadingIndicatorNotVisible();
installedAppsPage.appsList().sortableTable().noRowsShouldNotExist();
installedAppsPage.sharedComponents().resourceTable().sortableTable().rowNames('.col-link-detail', MEDIUM_TIMEOUT_OPT) installedAppsPage.appsList().sortableTable().rowNames('.col-link-detail', MEDIUM_TIMEOUT_OPT)
.should('not.contain', chartApp); .should('not.contain', chartApp);
// CRD removal may take time to reflect in the UI, so we conditionally wait until it's gone // CRD removal may take time to reflect in the UI, so we conditionally wait until it's gone
installedAppsPage.sharedComponents().resourceTable().sortableTable().waitForListItemRemoval('.col-link-detail', chartCrd, MEDIUM_TIMEOUT_OPT); installedAppsPage.appsList().sortableTable().waitForListItemRemoval('.col-link-detail', chartCrd, MEDIUM_TIMEOUT_OPT);
}); });
after('clean up', () => { after('clean up', () => {

View File

@ -1,6 +1,6 @@
import ClusterDashboardPagePo from '@/cypress/e2e/po/pages/explorer/cluster-dashboard.po'; import ClusterDashboardPagePo from '@/cypress/e2e/po/pages/explorer/cluster-dashboard.po';
import { SecretsPagePo } from '@/cypress/e2e/po/pages/explorer/secrets.po'; import { SecretsListPagePo } from '@/cypress/e2e/po/pages/explorer/secrets.po';
import { CYPRESS_SAFE_RESOURCE_REVISION } from '@/cypress/e2e/blueprints/blueprint.utils'; import { CYPRESS_SAFE_RESOURCE_REVISION } from '@/cypress/e2e/blueprints/blueprint.utils';
const certName = 'expired'; const certName = 'expired';
@ -102,7 +102,7 @@ describe('Certificates', { testIsolation: 'off', tags: ['@explorer', '@adminUser
clusterDashboard.fullSecretsList().scrollIntoView(); clusterDashboard.fullSecretsList().scrollIntoView();
clusterDashboard.fullSecretsList().click(); clusterDashboard.fullSecretsList().click();
const secrets = new SecretsPagePo('local'); const secrets = new SecretsListPagePo('local');
secrets.waitForPage(); secrets.waitForPage();
}); });

View File

@ -6,7 +6,7 @@ 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';
import { WorkloadsDeploymentsListPagePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads-deployments.po'; import { WorkloadsDeploymentsListPagePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads-deployments.po';
import { NodesPagePo } from '@/cypress/e2e/po/pages/explorer/nodes.po'; import { NodesPagePo } from '@/cypress/e2e/po/pages/explorer/nodes.po';
import { EventsPagePo } from '@/cypress/e2e/po/pages/explorer/events.po'; import { EventsPageListPo } from '@/cypress/e2e/po/pages/explorer/events.po';
import * as path from 'path'; import * as path from 'path';
import { eventsNoDataset } from '@/cypress/e2e/blueprints/explorer/cluster/events'; import { eventsNoDataset } from '@/cypress/e2e/blueprints/explorer/cluster/events';
@ -86,7 +86,6 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
header.kubectlShell().openAndExecuteCommand('get no'); header.kubectlShell().openAndExecuteCommand('get no');
header.kubectlShell().closeTerminal(); header.kubectlShell().closeTerminal();
header.kubectlShell().checkNotVisible();
}); });
it('can download kubeconfig from header', () => { it('can download kubeconfig from header', () => {
@ -245,15 +244,16 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
clusterDashboard.waitForPage(undefined, 'cluster-events'); clusterDashboard.waitForPage(undefined, 'cluster-events');
// Check events // Check events
clusterDashboard.eventsList().resourceTable().sortableTable().rowElements() clusterDashboard.eventsList().sortableTable().rowElements()
.should('have.length.gte', 2); .should('have.length.gte', 2);
clusterDashboard.fullEventsLink().click(); clusterDashboard.fullEventsLink().click();
const events = new EventsPagePo('local'); const events = new EventsPageListPo('local');
events.waitForPage(); events.waitForPage();
events.sortableTable().rowElements().should('have.length.gte', 2); events.list().resourceTable().sortableTable().rowElements()
.should('have.length.gte', 2);
}); });
it('can view events table empty if no events', { tags: ['@vai', '@adminUser'] }, () => { it('can view events table empty if no events', { tags: ['@vai', '@adminUser'] }, () => {
@ -263,7 +263,7 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
cy.wait('@eventsNoData'); cy.wait('@eventsNoData');
clusterDashboard.waitForPage(undefined, 'cluster-events'); clusterDashboard.waitForPage(undefined, 'cluster-events');
clusterDashboard.eventsList().resourceTable().sortableTable().checkRowCount(true, 1); clusterDashboard.eventsList().sortableTable().checkRowCount(true, 1);
let expectedHeaders = ['Reason', 'Object', 'Message', 'Name', 'Date']; let expectedHeaders = ['Reason', 'Object', 'Message', 'Name', 'Date'];
@ -272,10 +272,10 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
expectedHeaders = ['Reason', 'Object', 'Message', 'Name', 'First Seen', 'Last Seen', 'Count']; expectedHeaders = ['Reason', 'Object', 'Message', 'Name', 'First Seen', 'Last Seen', 'Count'];
} }
clusterDashboard.eventsList().resourceTable().sortableTable().tableHeaderRow() clusterDashboard.eventsList().sortableTable().tableHeaderRow()
.self() .self()
.scrollIntoView(); .scrollIntoView();
clusterDashboard.eventsList().resourceTable().sortableTable().tableHeaderRow() clusterDashboard.eventsList().sortableTable().tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeaders[i]); expect(el.text().trim()).to.eq(expectedHeaders[i]);
@ -283,16 +283,16 @@ describe('Cluster Dashboard', { testIsolation: 'off', tags: ['@explorer', '@admi
clusterDashboard.fullEventsLink().click(); clusterDashboard.fullEventsLink().click();
cy.wait('@eventsNoData'); cy.wait('@eventsNoData');
const events = new EventsPagePo('local'); const events = new EventsPageListPo('local');
events.waitForPage(); events.waitForPage();
events.eventslist().resourceTable().sortableTable().checkRowCount(true, 1); events.list().resourceTable().sortableTable().checkRowCount(true, 1);
const expectedFullHeaders = ['State', 'Last Seen', 'Type', 'Reason', 'Object', const expectedFullHeaders = ['State', 'Last Seen', 'Type', 'Reason', 'Object',
'Subobject', 'Source', 'Message', 'First Seen', 'Count', 'Name', 'Namespace']; 'Subobject', 'Source', 'Message', 'First Seen', 'Count', 'Name', 'Namespace'];
events.eventslist().resourceTable().sortableTable().tableHeaderRow() events.list().resourceTable().sortableTable().tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
expect(el.text().trim()).to.eq(expectedFullHeaders[i]); expect(el.text().trim()).to.eq(expectedFullHeaders[i]);

View File

@ -1,12 +1,12 @@
import ClusterDashboardPagePo from '@/cypress/e2e/po/pages/explorer/cluster-dashboard.po'; import ClusterDashboardPagePo from '@/cypress/e2e/po/pages/explorer/cluster-dashboard.po';
import { EventsPagePo } from '@/cypress/e2e/po/pages/explorer/events.po'; import { EventsPageListPo } from '@/cypress/e2e/po/pages/explorer/events.po';
import { generateEventsDataSmall } from '@/cypress/e2e/blueprints/explorer/cluster/events'; import { generateEventsDataSmall } from '@/cypress/e2e/blueprints/explorer/cluster/events';
import LoadingPo from '@/cypress/e2e/po/components/loading.po'; import LoadingPo from '@/cypress/e2e/po/components/loading.po';
import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po'; import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po';
const cluster = 'local'; const cluster = 'local';
const clusterDashboard = new ClusterDashboardPagePo(cluster); const clusterDashboard = new ClusterDashboardPagePo(cluster);
const events = new EventsPagePo(cluster); const events = new EventsPageListPo(cluster);
const pageSize = 10; const pageSize = 10;
// Should be enough to create at least 3 pages of events // Should be enough to create at least 3 pages of events
const podCount = 15; const podCount = 15;
@ -87,7 +87,7 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] },
ClusterDashboardPagePo.goToAndConfirmNsValues(cluster, { all: { is: true } }); ClusterDashboardPagePo.goToAndConfirmNsValues(cluster, { all: { is: true } });
clusterDashboard.waitForPage(undefined, 'cluster-events'); clusterDashboard.waitForPage(undefined, 'cluster-events');
EventsPagePo.navTo(); EventsPageListPo.navTo();
events.waitForPage(); events.waitForPage();
let vaiCacheEnabled = false; let vaiCacheEnabled = false;
@ -110,65 +110,104 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] },
expect(initialCount).to.be.greaterThan(3 * pageSize); expect(initialCount).to.be.greaterThan(3 * pageSize);
// pagination is visible // pagination is visible
events.sortableTable().pagination().checkVisible(); events.list().resourceTable().sortableTable().pagination()
.checkVisible();
const loadingPo = new LoadingPo('.title .resource-loading-indicator'); const loadingPo = new LoadingPo('.title .resource-loading-indicator');
loadingPo.checkNotExists(); loadingPo.checkNotExists();
// basic checks on navigation buttons // basic checks on navigation buttons
events.sortableTable().pagination().beginningButton().isDisabled(); events.list().resourceTable().sortableTable().pagination()
events.sortableTable().pagination().leftButton().isDisabled(); .beginningButton()
events.sortableTable().pagination().rightButton().isEnabled(); .isDisabled();
events.sortableTable().pagination().endButton().isEnabled(); events.list().resourceTable().sortableTable().pagination()
.leftButton()
.isDisabled();
events.list().resourceTable().sortableTable().pagination()
.rightButton()
.isEnabled();
events.list().resourceTable().sortableTable().pagination()
.endButton()
.isEnabled();
// check text before navigation // check text before navigation
events.sortableTable().pagination().self().scrollIntoView(); events.list().resourceTable().sortableTable().pagination()
events.sortableTable().pagination().paginationText().then((el) => { .self()
.scrollIntoView();
events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ initialCount } Events`); expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ initialCount } Events`);
}); });
// navigate to next page - right button // navigate to next page - right button
countHelper.setupCount(vaiCacheEnabled, initialCount); countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().rightButton().click(); events.list().resourceTable().sortableTable().pagination()
.rightButton()
.click();
countHelper.handleCount(vaiCacheEnabled); countHelper.handleCount(vaiCacheEnabled);
// check text and buttons after navigation // check text and buttons after navigation
events.sortableTable().pagination().self().scrollIntoView(); events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => { countHelper.getCount().then((count) => {
return events.sortableTable().pagination().paginationText().then((el) => { return events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`${ pageSize + 1 } - ${ 2 * pageSize } of ${ count } Events`); expect(el.trim()).to.eq(`${ pageSize + 1 } - ${ 2 * pageSize } of ${ count } Events`);
}); });
}); });
events.sortableTable().pagination().beginningButton().isEnabled(); events.list().resourceTable().sortableTable().pagination()
events.sortableTable().pagination().leftButton().isEnabled(); .beginningButton()
.isEnabled();
events.list().resourceTable().sortableTable().pagination()
.leftButton()
.isEnabled();
// navigate to first page - left button // navigate to first page - left button
countHelper.setupCount(vaiCacheEnabled, initialCount); countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().leftButton().click(); events.list().resourceTable().sortableTable().pagination()
.leftButton()
.click();
countHelper.handleCount(vaiCacheEnabled); countHelper.handleCount(vaiCacheEnabled);
// check text and buttons after navigation // check text and buttons after navigation
events.sortableTable().pagination().self().scrollIntoView(); events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => { countHelper.getCount().then((count) => {
return events.sortableTable().pagination().paginationText().then((el) => { return events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`); expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`);
}); });
}); });
events.sortableTable().pagination().beginningButton().isDisabled(); events.list().resourceTable().sortableTable().pagination()
events.sortableTable().pagination().leftButton().isDisabled(); .beginningButton()
.isDisabled();
events.list().resourceTable().sortableTable().pagination()
.leftButton()
.isDisabled();
// navigate to last page - end button // navigate to last page - end button
countHelper.setupCount(vaiCacheEnabled, initialCount); countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().endButton().scrollIntoView() events.list().resourceTable().sortableTable().pagination()
.endButton()
.scrollIntoView()
.click(); .click();
countHelper.handleCount(vaiCacheEnabled); countHelper.handleCount(vaiCacheEnabled);
// check text after navigation // check text after navigation
events.sortableTable().pagination().self().scrollIntoView(); events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => { countHelper.getCount().then((count) => {
return events.sortableTable().pagination().paginationText().then((el) => { return events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
let pages = Math.floor(count / pageSize); let pages = Math.floor(count / pageSize);
if (count % pageSize === 0) { if (count % pageSize === 0) {
@ -183,77 +222,103 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] },
// navigate to first page - beginning button // navigate to first page - beginning button
countHelper.setupCount(vaiCacheEnabled, initialCount); countHelper.setupCount(vaiCacheEnabled, initialCount);
events.sortableTable().pagination().beginningButton().click(); events.list().resourceTable().sortableTable().pagination()
.beginningButton()
.click();
countHelper.handleCount(vaiCacheEnabled); countHelper.handleCount(vaiCacheEnabled);
// check text and buttons after navigation // check text and buttons after navigation
events.sortableTable().pagination().self().scrollIntoView(); events.list().resourceTable().sortableTable().pagination()
.self()
.scrollIntoView();
countHelper.getCount().then((count) => { countHelper.getCount().then((count) => {
events.sortableTable().pagination().paginationText().then((el) => { events.list().resourceTable().sortableTable().pagination()
.paginationText()
.then((el) => {
expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`); expect(el.trim()).to.eq(`1 - ${ pageSize } of ${ count } Events`);
}); });
}); });
events.sortableTable().pagination().beginningButton().isDisabled(); events.list().resourceTable().sortableTable().pagination()
events.sortableTable().pagination().leftButton().isDisabled(); .beginningButton()
.isDisabled();
events.list().resourceTable().sortableTable().pagination()
.leftButton()
.isDisabled();
}); });
}); });
it('filter events', () => { it('filter events', () => {
ClusterDashboardPagePo.navTo(); ClusterDashboardPagePo.navTo();
clusterDashboard.waitForPage(undefined, 'cluster-events'); clusterDashboard.waitForPage(undefined, 'cluster-events');
EventsPagePo.navTo(); EventsPageListPo.navTo();
events.waitForPage(); events.waitForPage();
events.sortableTable().checkVisible(); events.list().resourceTable().sortableTable().checkVisible();
events.sortableTable().checkLoadingIndicatorNotVisible(); events.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
events.sortableTable().checkRowCount(false, pageSize); events.list().resourceTable().sortableTable().checkRowCount(false, pageSize);
// filter by namespace // filter by namespace
events.sortableTable().filter(nsName2); events.list().resourceTable().sortableTable().filter(nsName2);
events.waitForPage(`q=${ nsName2 }`); events.waitForPage(`q=${ nsName2 }`);
events.eventslist().resourceTable().sortableTable().rowElementWithPartialName(uniquePod) events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.should('have.length.lte', 5); .should('have.length.lte', 5);
events.sortableTable().rowElementWithPartialName(uniquePod).should('be.visible'); events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.should('be.visible');
// filter by name // filter by name
events.sortableTable().filter(uniquePod); events.list().resourceTable().sortableTable().filter(uniquePod);
events.waitForPage(`q=${ uniquePod }`); events.waitForPage(`q=${ uniquePod }`);
events.eventslist().resourceTable().sortableTable().rowElementWithPartialName(uniquePod) events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.should('have.length.lte', 5); .should('have.length.lte', 5);
events.sortableTable().rowElementWithPartialName(uniquePod).should('be.visible'); events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.should('be.visible');
events.sortableTable().resetFilter(); events.list().resourceTable().sortableTable().resetFilter();
}); });
it('sorting changes the order of paginated events data', () => { it('sorting changes the order of paginated events data', () => {
EventsPagePo.navTo(); EventsPageListPo.navTo();
events.waitForPage(); events.waitForPage();
// check table is sorted by `last seen` in ASC order by default // check table is sorted by `last seen` in ASC order by default
events.sortableTable().tableHeaderRow().checkSortOrder(2, 'down'); events.list().resourceTable().sortableTable().tableHeaderRow()
.checkSortOrder(2, 'down');
// sort by name in ASC order // sort by name in ASC order
events.sortableTable().sort(11).click(); events.list().resourceTable().sortableTable().sort(11)
events.sortableTable().tableHeaderRow().checkSortOrder(11, 'down'); .click();
events.list().resourceTable().sortableTable().tableHeaderRow()
.checkSortOrder(11, 'down');
// event name should be visible on first page (sorted in ASC order) // event name should be visible on first page (sorted in ASC order)
events.sortableTable().tableHeaderRow().self().scrollIntoView(); events.list().resourceTable().sortableTable().tableHeaderRow()
events.sortableTable().rowElementWithPartialName(uniquePod).scrollIntoView().should('be.visible'); .self()
.scrollIntoView();
events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.scrollIntoView()
.should('be.visible');
// sort by name in DESC order // sort by name in DESC order
events.sortableTable().sort(11).click(); events.list().resourceTable().sortableTable().sort(11)
events.sortableTable().tableHeaderRow().checkSortOrder(11, 'up'); .click();
events.list().resourceTable().sortableTable().tableHeaderRow()
.checkSortOrder(11, 'up');
// event name should be NOT visible on first page (sorted in DESC order) // event name should be NOT visible on first page (sorted in DESC order)
events.sortableTable().rowElementWithPartialName(uniquePod).should('not.exist'); events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.should('not.exist');
// navigate to last page // navigate to last page
events.sortableTable().pagination().endButton().scrollIntoView() events.list().resourceTable().sortableTable().pagination()
.endButton()
.scrollIntoView()
.click(); .click();
// event name should be visible on last page (sorted in DESC order) // event name should be visible on last page (sorted in DESC order)
events.sortableTable().rowElementWithPartialName(uniquePod).scrollIntoView().should('be.visible'); events.list().resourceTable().sortableTable().rowElementWithPartialName(uniquePod)
.scrollIntoView()
.should('be.visible');
}); });
it('pagination is hidden', () => { it('pagination is hidden', () => {
@ -263,10 +328,11 @@ describe('Events', { testIsolation: 'off', tags: ['@explorer', '@adminUser'] },
events.waitForPage(); events.waitForPage();
cy.wait('@eventsDataSmall'); cy.wait('@eventsDataSmall');
events.sortableTable().checkVisible(); events.list().resourceTable().sortableTable().checkVisible();
events.sortableTable().checkLoadingIndicatorNotVisible(); events.list().resourceTable().sortableTable().checkLoadingIndicatorNotVisible();
events.sortableTable().checkRowCount(false, 3); events.list().resourceTable().sortableTable().checkRowCount(false, 3);
events.sortableTable().pagination().checkNotExists(); events.list().resourceTable().sortableTable().pagination()
.checkNotExists();
}); });
after('clean up', () => { after('clean up', () => {

View File

@ -1,8 +1,10 @@
import ProjectsNamespacesPagePo from '@/cypress/e2e/po/pages/explorer/projects-namespaces.po'; import { ProjectsNamespacesListPagePo, NamespaceCreateEditPagePo, ProjectCreateEditPagePo } from '@/cypress/e2e/po/pages/explorer/projects-namespaces.po';
import { spoofThirdPartyPrincipal } from '@/cypress/e2e/blueprints/explorer/rbac/third-party-principals-get'; import { spoofThirdPartyPrincipal } from '@/cypress/e2e/blueprints/explorer/rbac/third-party-principals-get';
describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => { describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
const projectsNamespacesPage = new ProjectsNamespacesPagePo('local'); const projectsNamespacesPage = new ProjectsNamespacesListPagePo();
const createProjectPage = new ProjectCreateEditPagePo();
const createNamespacePage = new NamespaceCreateEditPagePo();
beforeEach(() => { beforeEach(() => {
cy.login(); cy.login();
@ -11,13 +13,18 @@ describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
}); });
it('flat list view should have create Namespace button', () => { it('flat list view should have create Namespace button', () => {
projectsNamespacesPage.flatListClick(); projectsNamespacesPage.list().resourceTable().sortableTable().groupByButtons(0)
projectsNamespacesPage.createProjectNamespaceButton().should('exist'); .click();
projectsNamespacesPage.createNamespaceButton().should('exist');
projectsNamespacesPage.baseResourceList().masthead().actions().contains('Create Project')
.should('exist');
}); });
it('create namespace screen should have a projects dropdown', () => { it('create namespace screen should have a projects dropdown', () => {
projectsNamespacesPage.createProjectNamespaceClick(); projectsNamespacesPage.createNamespaceButton().click();
projectsNamespacesPage.nsProject().checkExists(); createNamespacePage.resourceDetail().createEditView().nameNsDescription()
.project()
.checkExists();
}); });
describe('Project creation', () => { describe('Project creation', () => {
@ -31,9 +38,13 @@ describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
// intercept the request to /v3/principals and return a principal authenticated by github instead of local // intercept the request to /v3/principals and return a principal authenticated by github instead of local
spoofThirdPartyPrincipal(); spoofThirdPartyPrincipal();
projectsNamespacesPage.createProjectButtonClick(); projectsNamespacesPage.baseResourceList().masthead().create();
projectsNamespacesPage.name().set(projectName); createProjectPage.resourceDetail().createEditView().nameNsDescription()
projectsNamespacesPage.buttonSubmit().click(); .name()
.set(projectName);
createProjectPage.resourceDetail().createEditView()
.create()
.click();
cy.wait('@createProjectRequest').then(({ request }) => { cy.wait('@createProjectRequest').then(({ request }) => {
expect(request.body.annotations['field.cattle.io/creator-principal-name']).to.equal('github://1234567890'); expect(request.body.annotations['field.cattle.io/creator-principal-name']).to.equal('github://1234567890');
@ -43,9 +54,12 @@ describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
it('does not set a creator principal id annotation when creating a project if using local auth', () => { it('does not set a creator principal id annotation when creating a project if using local auth', () => {
cy.get('@projectName').then((projectName) => { cy.get('@projectName').then((projectName) => {
projectsNamespacesPage.createProjectButtonClick(); projectsNamespacesPage.baseResourceList().masthead().create();
projectsNamespacesPage.name().set(projectName); createProjectPage.resourceDetail().createEditView().nameNsDescription()
projectsNamespacesPage.buttonSubmit().click(); .name()
.set(projectName);
createProjectPage.resourceDetail().createEditView()
.create();
cy.wait('@createProjectRequest').then(({ request, response }) => { cy.wait('@createProjectRequest').then(({ request, response }) => {
expect(request.body.annotations).to.not.have.property('field.cattle.io/creator-principal-name'); expect(request.body.annotations).to.not.have.property('field.cattle.io/creator-principal-name');
@ -55,7 +69,7 @@ describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
}); });
afterEach(() => { afterEach(() => {
cy.get('@projectName').then((projectName) => { cy.get<string>('@projectName').then((projectName) => {
cy.deleteRancherResource('v3', 'projects', projectName, false); cy.deleteRancherResource('v3', 'projects', projectName, false);
}); });
}); });
@ -68,77 +82,95 @@ describe('Projects/Namespaces', { tags: ['@explorer2', '@adminUser'] }, () => {
// Issue 5975: create button should be disabled unless name is filled in // Issue 5975: create button should be disabled unless name is filled in
it('Create button becomes available if the name is filled in', () => { it('Create button becomes available if the name is filled in', () => {
projectsNamespacesPage.createProjectButtonClick(); projectsNamespacesPage.baseResourceList().masthead().create();
projectsNamespacesPage.buttonSubmit().expectToBeDisabled(); createProjectPage.resourceDetail().createEditView()
projectsNamespacesPage.name().set('test-1234'); .createButton()
projectsNamespacesPage.buttonSubmit().expectToBeEnabled(); .expectToBeDisabled();
createProjectPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set('test-1234');
createProjectPage.resourceDetail().createEditView()
.createButton()
.expectToBeEnabled();
}); });
it('displays an error message when submitting a form with errors', () => { it('displays an error message when submitting a form with errors', () => {
projectsNamespacesPage.createProjectButtonClick(); projectsNamespacesPage.baseResourceList().masthead().create();
projectsNamespacesPage.name().set('test-1234'); createProjectPage.resourceDetail().createEditView().nameNsDescription()
projectsNamespacesPage.tabResourceQuotas().click(); .name()
projectsNamespacesPage.btnAddResource().click(); .set('test-1234');
projectsNamespacesPage.inputProjectLimit().set('50'); createProjectPage.tabResourceQuotas().click();
projectsNamespacesPage.buttonSubmit().click(); createProjectPage.btnAddResource().click();
createProjectPage.inputProjectLimit().set('50');
createProjectPage.resourceDetail().createEditView()
.create();
projectsNamespacesPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota'); createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
projectsNamespacesPage.bannerError(0).should('have.length', 1); createProjectPage.bannerError(0).should('have.length', 1);
}); });
it('displays a single error message on repeat submissions of a form with errors', () => { it('displays a single error message on repeat submissions of a form with errors', () => {
projectsNamespacesPage.createProjectButtonClick(); projectsNamespacesPage.baseResourceList().masthead().create();
projectsNamespacesPage.name().set('test-1234'); createProjectPage.resourceDetail().createEditView().nameNsDescription()
projectsNamespacesPage.tabResourceQuotas().click(); .name()
projectsNamespacesPage.btnAddResource().click(); .set('test-1234');
projectsNamespacesPage.inputProjectLimit().set('50'); createProjectPage.tabResourceQuotas().click();
projectsNamespacesPage.buttonSubmit().click(); createProjectPage.btnAddResource().click();
createProjectPage.inputProjectLimit().set('50');
createProjectPage.resourceDetail().createEditView()
.create();
projectsNamespacesPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota'); createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
projectsNamespacesPage.bannerError(0).should('have.length', 1); createProjectPage.bannerError(0).should('have.length', 1);
projectsNamespacesPage.buttonSubmit().click(); createProjectPage.resourceDetail().createEditView()
.create();
projectsNamespacesPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota'); createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
projectsNamespacesPage.bannerError(0).should('have.length', 1); createProjectPage.bannerError(0).should('have.length', 1);
projectsNamespacesPage.bannerError(1).should('have.length', 0); createProjectPage.bannerError(1).should('have.length', 0);
}); });
// https://github.com/rancher/dashboard/issues/11881 // testing https://github.com/rancher/dashboard/issues/11881
// it.skip('displays the most recent error after resolving a single error in a form with multiple errors', () => { it('displays the most recent error after resolving a single error in a form with multiple errors', () => {
// projectsNamespacesPage.createProjectButtonClick(); projectsNamespacesPage.baseResourceList().masthead().create();
// // Create the first error // Create the first error
// projectsNamespacesPage.name().set('test-1234'); createProjectPage.resourceDetail().createEditView().nameNsDescription()
// projectsNamespacesPage.tabResourceQuotas().click(); .name()
// projectsNamespacesPage.btnAddResource().click(); .set('test-1234');
// projectsNamespacesPage.inputProjectLimit().set('50'); createProjectPage.tabResourceQuotas().click();
// projectsNamespacesPage.buttonSubmit().click(); createProjectPage.btnAddResource().click();
createProjectPage.inputProjectLimit().set('50');
createProjectPage.resourceDetail().createEditView()
.create();
// // Create a second error // Create a second error
// projectsNamespacesPage.tabContainerDefaultResourceLimit().click(); createProjectPage.tabContainerDefaultResourceLimit().click();
// projectsNamespacesPage.inputCpuReservation().set('1000'); createProjectPage.inputCpuReservation().set('1000');
// projectsNamespacesPage.inputMemoryReservation().set('128'); createProjectPage.inputMemoryReservation().set('128');
// projectsNamespacesPage.inputCpuLimit().set('200'); createProjectPage.inputCpuLimit().set('200');
// projectsNamespacesPage.inputMemoryLimit().set('64'); createProjectPage.inputMemoryLimit().set('64');
// projectsNamespacesPage.buttonSubmit().click(); createProjectPage.resourceDetail().createEditView()
.create();
// // Assert that there is only a single error message // Assert that there is only a single error message
// projectsNamespacesPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota'); createProjectPage.bannerError(0).should('be.visible').contains('does not have all fields defined on a resourceQuota');
// projectsNamespacesPage.bannerError(0).should('have.length', 1); createProjectPage.bannerError(0).should('have.length', 1);
// projectsNamespacesPage.bannerError(1).should('have.length', 0); createProjectPage.bannerError(1).should('have.length', 0);
// // resolve the first error // resolve the first error
// projectsNamespacesPage.tabResourceQuotas().click(); createProjectPage.tabResourceQuotas().click();
// projectsNamespacesPage.inputNamespaceDefaultLimit().set('50'); createProjectPage.inputNamespaceDefaultLimit().set('50');
// projectsNamespacesPage.buttonSubmit().click(); createProjectPage.resourceDetail().createEditView()
.create();
// // Click on Create again and assert that there is only a single error // Click on Create again and assert that there is only a single error
// projectsNamespacesPage.bannerError(0).should('be.visible').contains('admission webhook "rancher.cattle.io.projects.management.cattle.io" denied the request'); createProjectPage.bannerError(0).should('be.visible').contains('admission webhook "rancher.cattle.io.projects.management.cattle.io" denied the request');
// projectsNamespacesPage.bannerError(0).should('have.length', 1); createProjectPage.bannerError(0).should('have.length', 1);
// projectsNamespacesPage.bannerError(1).should('have.length', 0); createProjectPage.bannerError(1).should('have.length', 0);
// }); });
}); });
}); });

View File

@ -24,26 +24,35 @@ describe('Cluster Explorer', { tags: ['@explorer2', '@adminUser'] }, () => {
workloadsDaemonsetsListPage.goTo(); workloadsDaemonsetsListPage.goTo();
workloadsDaemonsetsListPage.waitForPage(); workloadsDaemonsetsListPage.waitForPage();
workloadsDaemonsetsListPage.createDaemonset(); workloadsDaemonsetsListPage.baseResourceList().masthead().create();
// create a new daemonset // create a new daemonset
const workloadsDaemonsetsEditPage = new WorkLoadsDaemonsetsEditPagePo('local'); const workloadsDaemonsetsEditPage = new WorkLoadsDaemonsetsEditPagePo('local');
workloadsDaemonsetsEditPage.nameNsDescription().name().set(daemonsetName); workloadsDaemonsetsEditPage.resourceDetail().createEditView().nameNsDescription()
.name()
.set(daemonsetName);
workloadsDaemonsetsEditPage.containerImageInput().set('nginx'); workloadsDaemonsetsEditPage.containerImageInput().set('nginx');
workloadsDaemonsetsEditPage.saveCreateForm().click(); workloadsDaemonsetsEditPage.resourceDetail().cruResource().saveOrCreate()
.click();
workloadsDaemonsetsListPage.waitForPage(); workloadsDaemonsetsListPage.waitForPage();
workloadsDaemonsetsListPage.listElementWithName(daemonsetName).should('be.visible'); workloadsDaemonsetsListPage.list().resourceTable().sortableTable()
workloadsDaemonsetsListPage.goToeditItemWithName(daemonsetName); .rowElementWithName(daemonsetName)
.should('be.visible');
workloadsDaemonsetsListPage.list().actionMenu(daemonsetName).getMenuItem('Edit Config')
.click();
// edit daemonset // edit daemonset
workloadsDaemonsetsEditPage.clickTab('#DaemonSet'); workloadsDaemonsetsEditPage.clickTab('#DaemonSet');
workloadsDaemonsetsEditPage.clickTab('#upgrading'); workloadsDaemonsetsEditPage.clickTab('#upgrading');
workloadsDaemonsetsEditPage.ScalingUpgradePolicyRadioBtn().set(1); workloadsDaemonsetsEditPage.ScalingUpgradePolicyRadioBtn().set(1);
workloadsDaemonsetsEditPage.saveCreateForm().click(); workloadsDaemonsetsEditPage.resourceDetail().cruResource().saveOrCreate()
.click();
workloadsDaemonsetsListPage.listElementWithName(daemonsetName).should('be.visible'); workloadsDaemonsetsListPage.baseResourceList().resourceTable().sortableTable()
.rowElementWithName(daemonsetName)
.should('be.visible');
cy.wait('@daemonsetEdit', { requestTimeout: 4000 }).then((req) => { cy.wait('@daemonsetEdit', { requestTimeout: 4000 }).then((req) => {
expect(req.request.body.spec.updateStrategy.type).to.equal('OnDelete'); expect(req.request.body.spec.updateStrategy.type).to.equal('OnDelete');

View File

@ -1,4 +1,4 @@
import { FleetBundleNamespaceMappingListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.bundlenamespacemapping.po'; import { FleetBundleNamespaceMappingListPagePo, FleetBundleNsMappingCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.bundlenamespacemapping.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po'; import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import * as path from 'path'; import * as path from 'path';
import * as jsyaml from 'js-yaml'; import * as jsyaml from 'js-yaml';
@ -12,7 +12,7 @@ const mappingsNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder'); const downloadsFolder = Cypress.config('downloadsFolder');
describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => { describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetBundleNsMappingsPage = new FleetBundleNamespaceMappingListPagePo(); const fleetBundleNsMappingsListPage = new FleetBundleNamespaceMappingListPagePo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => { describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
@ -24,19 +24,21 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
}); });
it('can create a bundle namespace mapping', () => { it('can create a bundle namespace mapping', () => {
const fleetBundleNsMappingCreateEditPage = new FleetBundleNsMappingCreateEditPo();
cy.intercept('POST', '/v1/fleet.cattle.io.bundlenamespacemappings').as('createMapping'); cy.intercept('POST', '/v1/fleet.cattle.io.bundlenamespacemappings').as('createMapping');
fleetBundleNsMappingsPage.goTo(); fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().baseResourceList().masthead().title() fleetBundleNsMappingsListPage.baseResourceList().masthead().title()
.should('contain', 'BundleNamespaceMappings'); .should('contain', 'BundleNamespaceMappings');
headerPo.selectWorkspace(defaultWorkspace); headerPo.selectWorkspace(defaultWorkspace);
fleetBundleNsMappingsPage.sharedComponents().baseResourceList().masthead().createYaml(); fleetBundleNsMappingsListPage.baseResourceList().masthead().createYaml();
fleetBundleNsMappingsPage.createMappingForm().mastheadTitle().then((title) => { fleetBundleNsMappingCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('BundleNamespaceMapping: Create'); expect(title.replace(/\s+/g, ' ')).to.contain('BundleNamespaceMapping: Create');
}); });
fleetBundleNsMappingsPage.createMappingForm().waitForPage('as=yaml'); fleetBundleNsMappingCreateEditPage.waitForPage('as=yaml');
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -44,34 +46,36 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
json.metadata.name = customMappingName; json.metadata.name = customMappingName;
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@createMapping').then(({ response }) => { cy.wait('@createMapping').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
removeMappings = true; removeMappings = true;
mappingsNameList.push(customMappingName); mappingsNameList.push(customMappingName);
}); });
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().rowWithName(customMappingName).checkVisible(); fleetBundleNsMappingsListPage.list().rowWithName(customMappingName).checkVisible();
}); });
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990 // Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990
it.skip('can Edit Config', () => { it.skip('can Edit Config', () => {
const fleetBundleNsMappingCreateEditPage = new FleetBundleNsMappingCreateEditPo(defaultWorkspace, customMappingName);
cy.intercept('PUT', `/v1/fleet.cattle.io.bundlenamespacemappings/${ defaultWorkspace }/${ customMappingName }`).as('editMapping'); cy.intercept('PUT', `/v1/fleet.cattle.io.bundlenamespacemappings/${ defaultWorkspace }/${ customMappingName }`).as('editMapping');
fleetBundleNsMappingsPage.goTo(); fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(customMappingName).getMenuItem('Edit YAML') fleetBundleNsMappingsListPage.list().actionMenu(customMappingName).getMenuItem('Edit YAML')
.click(); .click();
fleetBundleNsMappingsPage.createMappingForm(defaultWorkspace, customMappingName).waitForPage('mode=edit&as=yaml'); fleetBundleNsMappingCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetBundleNsMappingsPage.createMappingForm().mastheadTitle().then((title) => { fleetBundleNsMappingCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`BundleNamespaceMapping: ${ customMappingName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`BundleNamespaceMapping: ${ customMappingName }`);
}); });
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -79,30 +83,32 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
json.metadata.namespace = localWorkspace; json.metadata.namespace = localWorkspace;
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@editMapping').then(({ response }) => { cy.wait('@editMapping').then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace); expect(response?.body.metadata.namespace).equals(localWorkspace);
}); });
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
}); });
it('can clone a bundle namespace mapping', () => { it('can clone a bundle namespace mapping', () => {
const fleetBundleNsMappingCreateEditPage = new FleetBundleNsMappingCreateEditPo(defaultWorkspace, customMappingName);
cy.intercept('POST', '/v1/fleet.cattle.io.bundlenamespacemappings').as('cloneMapping'); cy.intercept('POST', '/v1/fleet.cattle.io.bundlenamespacemappings').as('cloneMapping');
fleetBundleNsMappingsPage.goTo(); fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(customMappingName).getMenuItem('Clone') fleetBundleNsMappingsListPage.list().actionMenu(customMappingName).getMenuItem('Clone')
.click(); .click();
fleetBundleNsMappingsPage.createMappingForm(defaultWorkspace, customMappingName).waitForPage('mode=clone&as=yaml'); fleetBundleNsMappingCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetBundleNsMappingsPage.createMappingForm().mastheadTitle().then((title) => { fleetBundleNsMappingCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`BundleNamespaceMapping: Clone from ${ customMappingName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`BundleNamespaceMapping: Clone from ${ customMappingName }`);
}); });
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -110,25 +116,25 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
json.metadata.name = `${ customMappingName }-clone`; json.metadata.name = `${ customMappingName }-clone`;
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetBundleNsMappingsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetBundleNsMappingCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@cloneMapping').then(({ response }) => { cy.wait('@cloneMapping').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
}); });
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().rowWithName(`${ customMappingName }-clone`).checkVisible(); fleetBundleNsMappingsListPage.list().rowWithName(`${ customMappingName }-clone`).checkVisible();
}); });
it('can Download YAML', () => { it('can Download YAML', () => {
cy.deleteDownloadsFolder(); cy.deleteDownloadsFolder();
fleetBundleNsMappingsPage.goTo(); fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(customMappingName).getMenuItem('Download YAML') fleetBundleNsMappingsListPage.list().actionMenu(customMappingName).getMenuItem('Download YAML')
.click(); .click();
const downloadedFilename = path.join(downloadsFolder, `${ customMappingName }.yaml`); const downloadedFilename = path.join(downloadsFolder, `${ customMappingName }.yaml`);
@ -143,11 +149,11 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
}); });
it('can delete a bundle namespace mapping', () => { it('can delete a bundle namespace mapping', () => {
fleetBundleNsMappingsPage.goTo(); fleetBundleNsMappingsListPage.goTo();
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().actionMenu(`${ customMappingName }-clone`).getMenuItem('Delete') fleetBundleNsMappingsListPage.list().actionMenu(`${ customMappingName }-clone`).getMenuItem('Delete')
.click(); .click();
fleetBundleNsMappingsPage.sharedComponents().list().resourceTable().sortableTable() fleetBundleNsMappingsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.then((rows: any) => { .then((rows: any) => {
const promptRemove = new PromptRemove(); const promptRemove = new PromptRemove();
@ -156,10 +162,10 @@ describe('Bundle Namespace Mappings', { testIsolation: 'off', tags: ['@fleet', '
promptRemove.remove(); promptRemove.remove();
cy.wait('@deleteMapping'); cy.wait('@deleteMapping');
fleetBundleNsMappingsPage.waitForPage(); fleetBundleNsMappingsListPage.waitForPage();
fleetBundleNsMappingsPage.sharedComponents().list().resourceTable().sortableTable() fleetBundleNsMappingsListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1); .checkRowCount(false, rows.length - 1);
fleetBundleNsMappingsPage.sharedComponents().list().resourceTable().sortableTable() fleetBundleNsMappingsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.should('not.contain', `${ customMappingName }-clone`); .should('not.contain', `${ customMappingName }-clone`);
}); });

View File

@ -1,5 +1,4 @@
import { FleetBundlesListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.bundle.po'; import { FleetBundlesListPagePo, FleetBundleDetailsPo, FleetBundlesCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.bundle.po';
import FleetBundleDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.bundle.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po'; import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import * as path from 'path'; import * as path from 'path';
import * as jsyaml from 'js-yaml'; import * as jsyaml from 'js-yaml';
@ -15,7 +14,7 @@ const bundlesNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder'); const downloadsFolder = Cypress.config('downloadsFolder');
describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => { describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetBundles = new FleetBundlesListPagePo(); const fleetBundlesListPage = new FleetBundlesListPagePo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
describe('List', { tags: ['@vai', '@adminUser'] }, () => { describe('List', { tags: ['@vai', '@adminUser'] }, () => {
@ -25,13 +24,13 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
it('validate bundles table in empty state', () => { it('validate bundles table in empty state', () => {
FleetBundlesListPagePo.navTo(); FleetBundlesListPagePo.navTo();
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(defaultWorkspace); headerPo.selectWorkspace(defaultWorkspace);
// check table headers // check table headers
const expectedHeaders = ['State', 'Name', 'Deployments', 'Age']; const expectedHeaders = ['State', 'Name', 'Deployments', 'Age'];
fleetBundles.sharedComponents().list().resourceTable().sortableTable() fleetBundlesListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -41,13 +40,13 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
it('check table headers are available in list and details view', () => { it('check table headers are available in list and details view', () => {
FleetBundlesListPagePo.navTo(); FleetBundlesListPagePo.navTo();
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
// check table headers // check table headers
const expectedHeaders = ['State', 'Name', 'Deployments', 'Age']; const expectedHeaders = ['State', 'Name', 'Deployments', 'Age'];
fleetBundles.sharedComponents().list().resourceTable().sortableTable() fleetBundlesListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -55,16 +54,16 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
}); });
// go to fleet bundle details // go to fleet bundle details
fleetBundles.sharedComponents().goToDetailsPage(bundle); fleetBundlesListPage.goToDetailsPage(bundle);
const fleetBundleeDetailsPage = new FleetBundleDetailsPo(localWorkspace, bundle); const fleetBundlesDetailsPage = new FleetBundleDetailsPo(localWorkspace, bundle);
fleetBundleeDetailsPage.waitForPage(); fleetBundlesDetailsPage.waitForPage();
// check table headers // check table headers
const expectedHeadersDetailsViewEvents = ['State', 'Cluster', 'API Version', 'Kind', 'Name', 'Namespace']; const expectedHeadersDetailsViewEvents = ['State', 'Cluster', 'API Version', 'Kind', 'Name', 'Namespace'];
fleetBundleeDetailsPage.list().resourceTable().sortableTable() fleetBundlesDetailsPage.resourcesList().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -83,18 +82,19 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
it('can create a bundle', () => { it('can create a bundle', () => {
cy.intercept('POST', '/v1/fleet.cattle.io.bundles').as('createBundle'); cy.intercept('POST', '/v1/fleet.cattle.io.bundles').as('createBundle');
const fleetBundleCreateEditPage = new FleetBundlesCreateEditPo();
fleetBundles.goTo(); fleetBundlesListPage.goTo();
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
fleetBundles.sharedComponents().baseResourceList().masthead().title() fleetBundlesListPage.baseResourceList().masthead().title()
.should('contain', 'Bundles'); .should('contain', 'Bundles');
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().baseResourceList().masthead().createYaml(); fleetBundlesListPage.baseResourceList().masthead().createYaml();
fleetBundles.createBundlesForm().waitForPage('as=yaml'); fleetBundleCreateEditPage.waitForPage('as=yaml');
fleetBundles.createBundlesForm().mastheadTitle().then((title) => { fleetBundleCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Bundle: Create'); expect(title.replace(/\s+/g, ' ')).to.contain('Bundle: Create');
}); });
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -120,37 +120,39 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
} }
]; ];
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetBundles.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetBundleCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@createBundle').then(({ response }) => { cy.wait('@createBundle').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
removeBundle = true; removeBundle = true;
bundlesNameList.push(customBundleName); bundlesNameList.push(customBundleName);
}); });
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
fleetBundles.sharedComponents().list().rowWithName(customBundleName).checkVisible(); fleetBundlesListPage.list().rowWithName(customBundleName).checkVisible();
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/14146 // Skipping until issue resolved: https://github.com/rancher/dashboard/issues/14146
// fleetBundles.sharedComponents().resourceTableDetails(customBundleName, 3 ).contains(/^1$/, EXTRA_LONG_TIMEOUT_OPT); // fleetBundlesListPage.resourceTableDetails(customBundleName, 3 ).contains(/^1$/, EXTRA_LONG_TIMEOUT_OPT);
}); });
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990 // Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990
it.skip('can Edit Config', () => { it.skip('can Edit Config', () => {
const fleetBundleCreateEditPage = new FleetBundlesCreateEditPo(localWorkspace, customBundleName);
cy.intercept('PUT', `/v1/fleet.cattle.io.bundles/${ localWorkspace }/${ customBundleName }`).as('editBundle'); cy.intercept('PUT', `/v1/fleet.cattle.io.bundles/${ localWorkspace }/${ customBundleName }`).as('editBundle');
fleetBundles.goTo(); fleetBundlesListPage.goTo();
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(customBundleName).getMenuItem('Edit YAML') fleetBundlesListPage.list().actionMenu(customBundleName).getMenuItem('Edit YAML')
.click(); .click();
fleetBundles.createBundlesForm(localWorkspace, customBundleName).waitForPage('mode=edit&as=yaml'); fleetBundleCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetBundles.createBundlesForm().mastheadTitle().then((title) => { fleetBundleCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Bundle: ${ customBundleName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`Bundle: ${ customBundleName }`);
}); });
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -158,31 +160,33 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
json.metadata.namespace = localWorkspace; json.metadata.namespace = localWorkspace;
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetBundles.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetBundleCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@editBundle').then(({ response }) => { cy.wait('@editBundle').then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace); expect(response?.body.metadata.namespace).equals(localWorkspace);
}); });
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
}); });
it('can clone a bundle', () => { it('can clone a bundle', () => {
const fleetBundleCreateEditPage = new FleetBundlesCreateEditPo(localWorkspace, customBundleName);
cy.intercept('POST', '/v1/fleet.cattle.io.bundles').as('cloneBundle'); cy.intercept('POST', '/v1/fleet.cattle.io.bundles').as('cloneBundle');
fleetBundles.goTo(); fleetBundlesListPage.goTo();
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(customBundleName).getMenuItem('Clone') fleetBundlesListPage.list().actionMenu(customBundleName).getMenuItem('Clone')
.click(); .click();
fleetBundles.createBundlesForm(localWorkspace, customBundleName).waitForPage('mode=clone&as=yaml'); fleetBundleCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetBundles.createBundlesForm().mastheadTitle().then((title) => { fleetBundleCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Bundle: Clone from ${ customBundleName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`Bundle: Clone from ${ customBundleName }`);
}); });
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -190,28 +194,28 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
json.metadata.name = `${ customBundleName }-clone`; json.metadata.name = `${ customBundleName }-clone`;
fleetBundles.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetBundleCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetBundles.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetBundleCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@cloneBundle').then(({ response }) => { cy.wait('@cloneBundle').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
}); });
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
fleetBundles.sharedComponents().list().rowWithName(`${ customBundleName }-clone`).checkVisible(); fleetBundlesListPage.list().rowWithName(`${ customBundleName }-clone`).checkVisible();
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/14146 // Skipping until issue resolved: https://github.com/rancher/dashboard/issues/14146
// fleetBundles.sharedComponents().resourceTableDetails(`${ customBundleName }-clone`, 3 ).contains(/^1$/, EXTRA_LONG_TIMEOUT_OPT); // fleetBundlesListPage.resourceTableDetails(`${ customBundleName }-clone`, 3 ).contains(/^1$/, EXTRA_LONG_TIMEOUT_OPT);
}); });
it('can Download YAML', () => { it('can Download YAML', () => {
cy.deleteDownloadsFolder(); cy.deleteDownloadsFolder();
fleetBundles.goTo(); fleetBundlesListPage.goTo();
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(customBundleName).getMenuItem('Download YAML') fleetBundlesListPage.list().actionMenu(customBundleName).getMenuItem('Download YAML')
.click(); .click();
const downloadedFilename = path.join(downloadsFolder, `${ customBundleName }.yaml`); const downloadedFilename = path.join(downloadsFolder, `${ customBundleName }.yaml`);
@ -226,12 +230,12 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
}); });
it('can delete a bundle', () => { it('can delete a bundle', () => {
fleetBundles.goTo(); fleetBundlesListPage.goTo();
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetBundles.sharedComponents().list().actionMenu(`${ customBundleName }-clone`).getMenuItem('Delete') fleetBundlesListPage.list().actionMenu(`${ customBundleName }-clone`).getMenuItem('Delete')
.click(); .click();
fleetBundles.sharedComponents().list().resourceTable().sortableTable() fleetBundlesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.then((rows: any) => { .then((rows: any) => {
const promptRemove = new PromptRemove(); const promptRemove = new PromptRemove();
@ -240,10 +244,10 @@ describe('Bundles', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, ()
promptRemove.remove(); promptRemove.remove();
cy.wait('@deleteBundle'); cy.wait('@deleteBundle');
fleetBundles.waitForPage(); fleetBundlesListPage.waitForPage();
fleetBundles.sharedComponents().list().resourceTable().sortableTable() fleetBundlesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1); .checkRowCount(false, rows.length - 1);
fleetBundles.sharedComponents().list().resourceTable().sortableTable() fleetBundlesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.should('not.contain', `${ customBundleName }-clone`); .should('not.contain', `${ customBundleName }-clone`);
}); });

View File

@ -1,4 +1,4 @@
import { FleetClusterRegistrationTokenListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.clusterregistrationtoken.po'; import { FleetClusterRegistrationTokenListPagePo, FleetTokensCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.clusterregistrationtoken.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po'; import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import { clusterRegistrationTokensNoData, generateclusterRegistrationTokensDataSmall } from '@/cypress/e2e/blueprints/fleet/cluster-registration-tokens-get'; import { clusterRegistrationTokensNoData, generateclusterRegistrationTokensDataSmall } from '@/cypress/e2e/blueprints/fleet/cluster-registration-tokens-get';
import * as path from 'path'; import * as path from 'path';
@ -13,7 +13,8 @@ const tokenNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder'); const downloadsFolder = Cypress.config('downloadsFolder');
describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => { describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetTokensPage = new FleetClusterRegistrationTokenListPagePo(); const fleetTokensListPage = new FleetClusterRegistrationTokenListPagePo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => { describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
@ -25,19 +26,21 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
}); });
it('can create a cluster registration token', () => { it('can create a cluster registration token', () => {
const fleetTokenCreateEditPage = new FleetTokensCreateEditPo();
cy.intercept('POST', '/v1/fleet.cattle.io.clusterregistrationtokens').as('createToken'); cy.intercept('POST', '/v1/fleet.cattle.io.clusterregistrationtokens').as('createToken');
fleetTokensPage.goTo(); fleetTokensListPage.goTo();
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().baseResourceList().masthead().title() fleetTokensListPage.baseResourceList().masthead().title()
.should('contain', 'Cluster Registration Tokens'); .should('contain', 'Cluster Registration Tokens');
headerPo.selectWorkspace(defaultWorkspace); headerPo.selectWorkspace(defaultWorkspace);
fleetTokensPage.sharedComponents().baseResourceList().masthead().createYaml(); fleetTokensListPage.baseResourceList().masthead().createYaml();
fleetTokensPage.createTokenForm().waitForPage('as=yaml'); fleetTokenCreateEditPage.waitForPage('as=yaml');
fleetTokensPage.createTokenForm().mastheadTitle().then((title) => { fleetTokenCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Cluster Registration Token: Create'); expect(title.replace(/\s+/g, ' ')).to.contain('Cluster Registration Token: Create');
}); });
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -45,34 +48,36 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
json.metadata.name = customTokenName; json.metadata.name = customTokenName;
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetTokenCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@createToken').then(({ response }) => { cy.wait('@createToken').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
removeToken = true; removeToken = true;
tokenNameList.push(customTokenName); tokenNameList.push(customTokenName);
}); });
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().list().rowWithName(customTokenName).checkVisible(); fleetTokensListPage.list().rowWithName(customTokenName).checkVisible();
}); });
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990 // Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990
it.skip('can Edit Config', () => { it.skip('can Edit Config', () => {
const fleetTokenCreateEditPage = new FleetTokensCreateEditPo(defaultWorkspace, customTokenName);
cy.intercept('PUT', `/v1/fleet.cattle.io.clusterregistrationtokens/${ defaultWorkspace }/${ customTokenName }`).as('editToken'); cy.intercept('PUT', `/v1/fleet.cattle.io.clusterregistrationtokens/${ defaultWorkspace }/${ customTokenName }`).as('editToken');
fleetTokensPage.goTo(); fleetTokensListPage.goTo();
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(customTokenName).getMenuItem('Edit YAML') fleetTokensListPage.list().actionMenu(customTokenName).getMenuItem('Edit YAML')
.click(); .click();
fleetTokensPage.createTokenForm(defaultWorkspace, customTokenName).waitForPage('mode=edit&as=yaml'); fleetTokenCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetTokensPage.createTokenForm().mastheadTitle().then((title) => { fleetTokenCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Cluster Registration Token: ${ customTokenName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`Cluster Registration Token: ${ customTokenName }`);
}); });
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -80,30 +85,32 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
json.metadata.namespace = localWorkspace; json.metadata.namespace = localWorkspace;
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetTokenCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@editToken').then(({ response }) => { cy.wait('@editToken').then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace); expect(response?.body.metadata.namespace).equals(localWorkspace);
}); });
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
}); });
it('can clone a cluster registration token', () => { it('can clone a cluster registration token', () => {
const fleetTokenCreateEditPage = new FleetTokensCreateEditPo(defaultWorkspace, customTokenName);
cy.intercept('POST', '/v1/fleet.cattle.io.clusterregistrationtokens').as('cloneToken'); cy.intercept('POST', '/v1/fleet.cattle.io.clusterregistrationtokens').as('cloneToken');
fleetTokensPage.goTo(); fleetTokensListPage.goTo();
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(customTokenName).getMenuItem('Clone') fleetTokensListPage.list().actionMenu(customTokenName).getMenuItem('Clone')
.click(); .click();
fleetTokensPage.createTokenForm(defaultWorkspace, customTokenName).waitForPage('mode=clone&as=yaml'); fleetTokenCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetTokensPage.createTokenForm().mastheadTitle().then((title) => { fleetTokenCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Cluster Registration Token: Clone from ${ customTokenName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`Cluster Registration Token: Clone from ${ customTokenName }`);
}); });
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -111,25 +118,25 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
json.metadata.name = `${ customTokenName }-clone`; json.metadata.name = `${ customTokenName }-clone`;
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetTokenCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetTokensPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetTokenCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@cloneToken').then(({ response }) => { cy.wait('@cloneToken').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
}); });
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().list().rowWithName(`${ customTokenName }-clone`).checkVisible(); fleetTokensListPage.list().rowWithName(`${ customTokenName }-clone`).checkVisible();
}); });
it('can Download YAML', () => { it('can Download YAML', () => {
cy.deleteDownloadsFolder(); cy.deleteDownloadsFolder();
fleetTokensPage.goTo(); fleetTokensListPage.goTo();
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(customTokenName).getMenuItem('Download YAML') fleetTokensListPage.list().actionMenu(customTokenName).getMenuItem('Download YAML')
.click(); .click();
const downloadedFilename = path.join(downloadsFolder, `${ customTokenName }.yaml`); const downloadedFilename = path.join(downloadsFolder, `${ customTokenName }.yaml`);
@ -144,11 +151,11 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
}); });
it('can delete a cluster registration token', () => { it('can delete a cluster registration token', () => {
fleetTokensPage.goTo(); fleetTokensListPage.goTo();
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().list().actionMenu(`${ customTokenName }-clone`).getMenuItem('Delete') fleetTokensListPage.list().actionMenu(`${ customTokenName }-clone`).getMenuItem('Delete')
.click(); .click();
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable() fleetTokensListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.then((rows: any) => { .then((rows: any) => {
const promptRemove = new PromptRemove(); const promptRemove = new PromptRemove();
@ -157,10 +164,10 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
promptRemove.remove(); promptRemove.remove();
cy.wait('@deleteToken'); cy.wait('@deleteToken');
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable() fleetTokensListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1); .checkRowCount(false, rows.length - 1);
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable() fleetTokensListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.should('not.contain', `${ customTokenName }-clone`); .should('not.contain', `${ customTokenName }-clone`);
}); });
@ -180,33 +187,33 @@ describe('Cluster Registration Tokens', { testIsolation: 'off', tags: ['@fleet',
it('validate cluster registration tokens table in empty state', () => { it('validate cluster registration tokens table in empty state', () => {
clusterRegistrationTokensNoData(); clusterRegistrationTokensNoData();
fleetTokensPage.goTo(); fleetTokensListPage.goTo();
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
cy.wait('@clusterRegistrationTokensNoData'); cy.wait('@clusterRegistrationTokensNoData');
const expectedHeaders = ['State', 'Name', 'Namespace', 'Secret-Name']; const expectedHeaders = ['State', 'Name', 'Namespace', 'Secret-Name'];
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable() fleetTokensListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.get('.table-header-container .content') .get('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeaders[i]); expect(el.text().trim()).to.eq(expectedHeaders[i]);
}); });
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable() fleetTokensListPage.list().resourceTable().sortableTable()
.checkRowCount(true, 1); .checkRowCount(true, 1);
}); });
it('validate cluster registration tokens table', () => { it('validate cluster registration tokens table', () => {
generateclusterRegistrationTokensDataSmall(); generateclusterRegistrationTokensDataSmall();
FleetClusterRegistrationTokenListPagePo.navTo(); FleetClusterRegistrationTokenListPagePo.navTo();
fleetTokensPage.waitForPage(); fleetTokensListPage.waitForPage();
headerPo.selectWorkspace(defaultWorkspace); headerPo.selectWorkspace(defaultWorkspace);
// check table headers // check table headers
const expectedHeaders = ['State', 'Name', 'Namespace', 'Secret-Name']; const expectedHeaders = ['State', 'Name', 'Namespace', 'Secret-Name'];
fleetTokensPage.sharedComponents().list().resourceTable().sortableTable() fleetTokensListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {

View File

@ -1,4 +1,4 @@
import { FleetGitRepoRestrictionListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitreporestriction.po'; import { FleetGitRepoRestrictionListPagePo, FleetRestrictionCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitreporestriction.po';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po'; import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import * as path from 'path'; import * as path from 'path';
import * as jsyaml from 'js-yaml'; import * as jsyaml from 'js-yaml';
@ -12,7 +12,7 @@ const restrictionNameList = [];
const downloadsFolder = Cypress.config('downloadsFolder'); const downloadsFolder = Cypress.config('downloadsFolder');
describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => { describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetRestrictionsPage = new FleetGitRepoRestrictionListPagePo(); const fleetRestrictionsListPage = new FleetGitRepoRestrictionListPagePo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => { describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
@ -24,19 +24,21 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
}); });
it('can create a gitrepo restriction', () => { it('can create a gitrepo restriction', () => {
const fleetRestrictionCreateEditPage = new FleetRestrictionCreateEditPo();
cy.intercept('POST', '/v1/fleet.cattle.io.gitreporestrictions').as('createRestriction'); cy.intercept('POST', '/v1/fleet.cattle.io.gitreporestrictions').as('createRestriction');
fleetRestrictionsPage.goTo(); fleetRestrictionsListPage.goTo();
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().baseResourceList().masthead().title() fleetRestrictionsListPage.baseResourceList().masthead().title()
.should('contain', 'GitRepoRestrictions'); .should('contain', 'GitRepoRestrictions');
headerPo.selectWorkspace(defaultWorkspace); headerPo.selectWorkspace(defaultWorkspace);
fleetRestrictionsPage.sharedComponents().baseResourceList().masthead().createYaml(); fleetRestrictionsListPage.baseResourceList().masthead().createYaml();
fleetRestrictionsPage.createRestrictionForm().waitForPage('as=yaml'); fleetRestrictionCreateEditPage.waitForPage('as=yaml');
fleetRestrictionsPage.createRestrictionForm().mastheadTitle().then((title) => { fleetRestrictionCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('GitRepoRestriction: Create'); expect(title.replace(/\s+/g, ' ')).to.contain('GitRepoRestriction: Create');
}); });
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -44,34 +46,36 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
json.metadata.name = customRestrictionName; json.metadata.name = customRestrictionName;
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@createRestriction').then(({ response }) => { cy.wait('@createRestriction').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
removeRestriction = true; removeRestriction = true;
restrictionNameList.push(customRestrictionName); restrictionNameList.push(customRestrictionName);
}); });
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().rowWithName(customRestrictionName).checkVisible(); fleetRestrictionsListPage.list().rowWithName(customRestrictionName).checkVisible();
}); });
// Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990 // Skipping until issue resolved: https://github.com/rancher/dashboard/issues/13990
it.skip('can Edit Config', () => { it.skip('can Edit Config', () => {
const fleetRestrictionCreateEditPage = new FleetRestrictionCreateEditPo(defaultWorkspace, customRestrictionName);
cy.intercept('PUT', `/v1/fleet.cattle.io.gitreporestrictions/${ defaultWorkspace }/${ customRestrictionName }`).as('editRestriction'); cy.intercept('PUT', `/v1/fleet.cattle.io.gitreporestrictions/${ defaultWorkspace }/${ customRestrictionName }`).as('editRestriction');
fleetRestrictionsPage.goTo(); fleetRestrictionsListPage.goTo();
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(customRestrictionName).getMenuItem('Edit YAML') fleetRestrictionsListPage.list().actionMenu(customRestrictionName).getMenuItem('Edit YAML')
.click(); .click();
fleetRestrictionsPage.createRestrictionForm(defaultWorkspace, customRestrictionName).waitForPage('mode=edit&as=yaml'); fleetRestrictionCreateEditPage.waitForPage('mode=edit&as=yaml');
fleetRestrictionsPage.createRestrictionForm().mastheadTitle().then((title) => { fleetRestrictionCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`GitRepoRestriction: ${ customRestrictionName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`GitRepoRestriction: ${ customRestrictionName }`);
}); });
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -79,30 +83,32 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
json.metadata.namespace = localWorkspace; json.metadata.namespace = localWorkspace;
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@editRestriction').then(({ response }) => { cy.wait('@editRestriction').then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata.namespace).equals(localWorkspace); expect(response?.body.metadata.namespace).equals(localWorkspace);
}); });
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
}); });
it('can clone a gitrepo restriction', () => { it('can clone a gitrepo restriction', () => {
const fleetRestrictionCreateEditPage = new FleetRestrictionCreateEditPo(defaultWorkspace, customRestrictionName);
cy.intercept('POST', '/v1/fleet.cattle.io.gitreporestrictions').as('cloneRestriction'); cy.intercept('POST', '/v1/fleet.cattle.io.gitreporestrictions').as('cloneRestriction');
fleetRestrictionsPage.goTo(); fleetRestrictionsListPage.goTo();
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(customRestrictionName).getMenuItem('Clone') fleetRestrictionsListPage.list().actionMenu(customRestrictionName).getMenuItem('Clone')
.click(); .click();
fleetRestrictionsPage.createRestrictionForm(defaultWorkspace, customRestrictionName).waitForPage('mode=clone&as=yaml'); fleetRestrictionCreateEditPage.waitForPage('mode=clone&as=yaml');
fleetRestrictionsPage.createRestrictionForm().mastheadTitle().then((title) => { fleetRestrictionCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`GitRepoRestriction: Clone from ${ customRestrictionName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`GitRepoRestriction: Clone from ${ customRestrictionName }`);
}); });
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.value() .value()
.then((val) => { .then((val) => {
// convert yaml into json to update values // convert yaml into json to update values
@ -110,25 +116,25 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
json.metadata.name = `${ customRestrictionName }-clone`; json.metadata.name = `${ customRestrictionName }-clone`;
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().codeMirror() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().codeMirror()
.set(jsyaml.dump(json)); .set(jsyaml.dump(json));
}); });
fleetRestrictionsPage.sharedComponents().resourceDetail().resourceYaml().saveOrCreate() fleetRestrictionCreateEditPage.resourceDetail().resourceYaml().saveOrCreate()
.click(); .click();
cy.wait('@cloneRestriction').then(({ response }) => { cy.wait('@cloneRestriction').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
}); });
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().rowWithName(`${ customRestrictionName }-clone`).checkVisible(); fleetRestrictionsListPage.list().rowWithName(`${ customRestrictionName }-clone`).checkVisible();
}); });
it('can Download YAML', () => { it('can Download YAML', () => {
cy.deleteDownloadsFolder(); cy.deleteDownloadsFolder();
fleetRestrictionsPage.goTo(); fleetRestrictionsListPage.goTo();
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(customRestrictionName).getMenuItem('Download YAML') fleetRestrictionsListPage.list().actionMenu(customRestrictionName).getMenuItem('Download YAML')
.click(); .click();
const downloadedFilename = path.join(downloadsFolder, `${ customRestrictionName }.yaml`); const downloadedFilename = path.join(downloadsFolder, `${ customRestrictionName }.yaml`);
@ -143,11 +149,11 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
}); });
it('can delete a gitrepo restriction', () => { it('can delete a gitrepo restriction', () => {
fleetRestrictionsPage.goTo(); fleetRestrictionsListPage.goTo();
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().actionMenu(`${ customRestrictionName }-clone`).getMenuItem('Delete') fleetRestrictionsListPage.list().actionMenu(`${ customRestrictionName }-clone`).getMenuItem('Delete')
.click(); .click();
fleetRestrictionsPage.sharedComponents().list().resourceTable().sortableTable() fleetRestrictionsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.then((rows: any) => { .then((rows: any) => {
const promptRemove = new PromptRemove(); const promptRemove = new PromptRemove();
@ -156,10 +162,10 @@ describe('GitRepo Restrictions', { testIsolation: 'off', tags: ['@fleet', '@admi
promptRemove.remove(); promptRemove.remove();
cy.wait('@deleteRestriction'); cy.wait('@deleteRestriction');
fleetRestrictionsPage.waitForPage(); fleetRestrictionsListPage.waitForPage();
fleetRestrictionsPage.sharedComponents().list().resourceTable().sortableTable() fleetRestrictionsListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1); .checkRowCount(false, rows.length - 1);
fleetRestrictionsPage.sharedComponents().list().resourceTable().sortableTable() fleetRestrictionsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.should('not.contain', `${ customRestrictionName }-clone`); .should('not.contain', `${ customRestrictionName }-clone`);
}); });

View File

@ -1,5 +1,4 @@
import { FleetWorkspaceListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.fleetworkspace.po'; import { FleetWorkspaceListPagePo, FleetWorkspaceCreateEditPo, FleetWorkspaceDetailsPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.fleetworkspace.po';
import FleetWorkspaceDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.fleetworkspace.po';
import { generateFleetWorkspacesDataSmall } from '@/cypress/e2e/blueprints/fleet/workspaces-get'; import { generateFleetWorkspacesDataSmall } from '@/cypress/e2e/blueprints/fleet/workspaces-get';
import HomePagePo from '@/cypress/e2e/po/pages/home.po'; import HomePagePo from '@/cypress/e2e/po/pages/home.po';
import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po'; import SortableTablePo from '@/cypress/e2e/po/components/sortable-table.po';
@ -14,7 +13,8 @@ let customWorkspace = '';
const downloadsFolder = Cypress.config('downloadsFolder'); const downloadsFolder = Cypress.config('downloadsFolder');
describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => { describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetWorkspacesPage = new FleetWorkspaceListPagePo(); const fleetWorkspacesListPage = new FleetWorkspaceListPagePo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
before(() => { before(() => {
@ -28,16 +28,19 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
let initialCount: number; let initialCount: number;
it('check table headers are available in list and details view', () => { it('check table headers are available in list and details view', () => {
fleetWorkspacesPage.goTo(); fleetWorkspacesListPage.goTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist(); fleetWorkspacesListPage.list().resourceTable().sortableTable()
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().filter(defaultWorkspace); .noRowsShouldNotExist();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 1); fleetWorkspacesListPage.list().resourceTable().sortableTable()
.filter(defaultWorkspace);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 1);
// check table headers // check table headers
const expectedHeaders = ['State', 'Name', 'Git Repos', 'Clusters', 'Cluster Groups', 'Age']; const expectedHeaders = ['State', 'Name', 'Git Repos', 'Clusters', 'Cluster Groups', 'Age'];
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -45,7 +48,7 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
}); });
// go to fleet workspaces details // go to fleet workspaces details
fleetWorkspacesPage.sharedComponents().goToDetailsPage(defaultWorkspace); fleetWorkspacesListPage.goToDetailsPage(defaultWorkspace);
const fleetWorkspaceDetailsPage = new FleetWorkspaceDetailsPo(defaultWorkspace); const fleetWorkspaceDetailsPage = new FleetWorkspaceDetailsPo(defaultWorkspace);
@ -54,7 +57,7 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
// check table headers // check table headers
const expectedHeadersDetailsViewEvents = ['Type', 'Reason', 'Updated', 'Message']; const expectedHeadersDetailsViewEvents = ['Type', 'Reason', 'Updated', 'Message'];
fleetWorkspaceDetailsPage.recentEventsList().resourceTable().sortableTable() fleetWorkspaceDetailsPage.recentEventsList().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -67,14 +70,14 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
// check table headers // check table headers
const expectedHeadersDetailsViewResources = ['State', 'Type', 'Name', 'Namespace']; const expectedHeadersDetailsViewResources = ['State', 'Type', 'Name', 'Namespace'];
fleetWorkspaceDetailsPage.relatedResourcesList(1).resourceTable().sortableTable() fleetWorkspaceDetailsPage.relatedResourcesList(1).sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
expect(el.text().trim()).to.eq(expectedHeadersDetailsViewResources[i]); expect(el.text().trim()).to.eq(expectedHeadersDetailsViewResources[i]);
}); });
fleetWorkspaceDetailsPage.relatedResourcesList(2).resourceTable().sortableTable() fleetWorkspaceDetailsPage.relatedResourcesList(2).sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -125,100 +128,121 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
const count = resp.body.count; const count = resp.body.count;
FleetWorkspaceListPagePo.navTo(); FleetWorkspaceListPagePo.navTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
// pagination is visible // pagination is visible
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.checkVisible(); .checkVisible();
// basic checks on navigation buttons // basic checks on navigation buttons
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton() .beginningButton()
.isDisabled(); .isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton() .leftButton()
.isDisabled(); .isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.rightButton() .rightButton()
.isEnabled(); .isEnabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton() .endButton()
.isEnabled(); .isEnabled();
// check text before navigation // check text before navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText() .paginationText()
.then((el) => { .then((el) => {
expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`); expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`);
}); });
// navigate to next page - right button // navigate to next page - right button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.rightButton() .rightButton()
.click(); .click();
// check text and buttons after navigation // check text and buttons after navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText() .paginationText()
.then((el) => { .then((el) => {
expect(el.trim()).to.eq(`11 - 20 of ${ count } Workspaces`); expect(el.trim()).to.eq(`11 - 20 of ${ count } Workspaces`);
}); });
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton() .beginningButton()
.isEnabled(); .isEnabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton() .leftButton()
.isEnabled(); .isEnabled();
// navigate to first page - left button // navigate to first page - left button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton() .leftButton()
.click(); .click();
// check text and buttons after navigation // check text and buttons after navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText() .paginationText()
.then((el) => { .then((el) => {
expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`); expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`);
}); });
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton() .beginningButton()
.isDisabled(); .isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton() .leftButton()
.isDisabled(); .isDisabled();
// navigate to last page - end button // navigate to last page - end button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton() .endButton()
.scrollIntoView() .scrollIntoView()
.click(); .click();
// check row count on last page // check row count on last page
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, count - 20); fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, count - 20);
// check text after navigation // check text after navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText() .paginationText()
.then((el) => { .then((el) => {
expect(el.trim()).to.eq(`21 - ${ count } of ${ count } Workspaces`); expect(el.trim()).to.eq(`21 - ${ count } of ${ count } Workspaces`);
}); });
// navigate to first page - beginning button // navigate to first page - beginning button
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton() .beginningButton()
.click(); .click();
// check text and buttons after navigation // check text and buttons after navigation
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.paginationText() .paginationText()
.then((el) => { .then((el) => {
expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`); expect(el.trim()).to.eq(`1 - 10 of ${ count } Workspaces`);
}); });
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.beginningButton() .beginningButton()
.isDisabled(); .isDisabled();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.leftButton() .leftButton()
.isDisabled(); .isDisabled();
}); });
@ -226,79 +250,100 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
it('filter workspace', () => { it('filter workspace', () => {
FleetWorkspaceListPagePo.navTo(); FleetWorkspaceListPagePo.navTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkVisible(); fleetWorkspacesListPage.list().resourceTable().sortableTable()
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); .checkVisible();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 10); fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 10);
// filter by name // filter by name
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().filter(workspaceNameList[0]); fleetWorkspacesListPage.list().resourceTable().sortableTable()
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 1); .filter(workspaceNameList[0]);
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().rowElementWithName(workspaceNameList[0]) fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 1);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowElementWithName(workspaceNameList[0])
.scrollIntoView() .scrollIntoView()
.should('be.visible'); .should('be.visible');
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().resetFilter(); fleetWorkspacesListPage.list().resourceTable().sortableTable()
.resetFilter();
}); });
it('sorting changes the order of paginated workspace data', () => { it('sorting changes the order of paginated workspace data', () => {
FleetWorkspaceListPagePo.navTo(); FleetWorkspaceListPagePo.navTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
// check table is sorted by access key in ASC order by default // check table is sorted by access key in ASC order by default
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().tableHeaderRow() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.checkSortOrder(2, 'down'); .checkSortOrder(2, 'down');
// workspace name should be visible on first page (sorted in ASC order) // workspace name should be visible on first page (sorted in ASC order)
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().tableHeaderRow() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.self() .self()
.scrollIntoView(); .scrollIntoView();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().rowElementWithName(uniqueWorkspaceName) fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowElementWithName(uniqueWorkspaceName)
.scrollIntoView() .scrollIntoView()
.should('be.visible'); .should('be.visible');
// navigate to last page // navigate to last page
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton() .endButton()
.scrollIntoView() .scrollIntoView()
.click(); .click();
// workspace name should be NOT visible on last page (sorted in ASC order) // workspace name should be NOT visible on last page (sorted in ASC order)
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().rowElementWithName(uniqueWorkspaceName) fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowElementWithName(uniqueWorkspaceName)
.should('not.exist'); .should('not.exist');
// sort by name in DESC order // sort by name in DESC order
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().sort(2) fleetWorkspacesListPage.list().resourceTable().sortableTable()
.sort(2)
.click(); .click();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().tableHeaderRow() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.tableHeaderRow()
.checkSortOrder(2, 'up'); .checkSortOrder(2, 'up');
// workspace name should be NOT visible on first page (sorted in DESC order) // workspace name should be NOT visible on first page (sorted in DESC order)
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().rowElementWithName(uniqueWorkspaceName) fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowElementWithName(uniqueWorkspaceName)
.should('not.exist'); .should('not.exist');
// navigate to last page // navigate to last page
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.endButton() .endButton()
.scrollIntoView() .scrollIntoView()
.click(); .click();
// workspace name should be visible on last page (sorted in DESC order) // workspace name should be visible on last page (sorted in DESC order)
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().rowElementWithName(uniqueWorkspaceName) fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowElementWithName(uniqueWorkspaceName)
.scrollIntoView() .scrollIntoView()
.should('be.visible'); .should('be.visible');
}); });
it('pagination is hidden', () => { it('pagination is hidden', () => {
generateFleetWorkspacesDataSmall(); generateFleetWorkspacesDataSmall();
fleetWorkspacesPage.goTo(); fleetWorkspacesListPage.goTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
cy.wait('@fleetworkspacesDataSmall'); cy.wait('@fleetworkspacesDataSmall');
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkVisible(); fleetWorkspacesListPage.list().resourceTable().sortableTable()
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); .checkVisible();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 2); fleetWorkspacesListPage.list().resourceTable().sortableTable()
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().pagination() .checkLoadingIndicatorNotVisible();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 2);
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.pagination()
.checkNotExists(); .checkNotExists();
}); });
@ -311,99 +356,106 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => { describe('CRUD', { tags: ['@fleet', '@adminUser'] }, () => {
it('can create a fleet workspace', () => { it('can create a fleet workspace', () => {
const fleetWorkspaceCreateEditPage = new FleetWorkspaceCreateEditPo();
cy.intercept('POST', '/v3/fleetworkspaces').as('createWorkspace'); cy.intercept('POST', '/v3/fleetworkspaces').as('createWorkspace');
fleetWorkspacesPage.goTo(); fleetWorkspacesListPage.goTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().baseResourceList().masthead().title() fleetWorkspacesListPage.baseResourceList().masthead().title()
.should('contain', 'Workspaces'); .should('contain', 'Workspaces');
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist(); .noRowsShouldNotExist();
fleetWorkspacesPage.sharedComponents().baseResourceList().masthead().create(); fleetWorkspacesListPage.baseResourceList().masthead().create();
fleetWorkspacesPage.createWorkspaceForm().waitForPage(null, 'allowedtargetnamespaces'); fleetWorkspaceCreateEditPage.waitForPage(null, 'allowedtargetnamespaces');
fleetWorkspacesPage.createWorkspaceForm().mastheadTitle().then((title) => { fleetWorkspaceCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Workspace: Create'); expect(title.replace(/\s+/g, ' ')).to.contain('Workspace: Create');
}); });
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView() fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.nameNsDescription() .nameNsDescription()
.name() .name()
.set(customWorkspace); .set(customWorkspace);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView() fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.nameNsDescription() .nameNsDescription()
.description() .description()
.set(`${ customWorkspace }-desc`); .set(`${ customWorkspace }-desc`);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs() fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.allTabs() .allTabs()
.should('have.length.at.least', 2); .should('have.length.at.least', 2);
const tabs = ['Allowed Target Namespaces', 'Labels & Annotations']; const tabs = ['Allowed Target Namespaces', 'Labels & Annotations'];
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs() fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.tabNames() .tabNames()
.each((el, i) => { .each((el, i) => {
expect(el).to.eq(tabs[i]); expect(el).to.eq(tabs[i]);
}); });
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs() fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.assertTabIsActive('[data-testid="allowedtargetnamespaces"]'); .assertTabIsActive('[data-testid="allowedtargetnamespaces"]');
fleetWorkspacesPage.createWorkspaceForm().allowTargetNsTabList().setValueAtIndex('test', 0); fleetWorkspaceCreateEditPage.allowTargetNsTabList().setValueAtIndex('test', 0);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().tabs() fleetWorkspaceCreateEditPage.resourceDetail().tabs()
.clickTabWithSelector('[data-testid="btn-labels"]'); .clickTabWithSelector('[data-testid="btn-labels"]');
fleetWorkspacesPage.createWorkspaceForm().waitForPage(null, 'labels'); fleetWorkspaceCreateEditPage.waitForPage(null, 'labels');
fleetWorkspacesPage.createWorkspaceForm().lablesAnnotationsKeyValue().setKeyValueAtIndex('Add Label', 'label-key1', 'label-value1', 0, 'div.row:nth-of-type(2)'); fleetWorkspaceCreateEditPage.lablesAnnotationsKeyValue().setKeyValueAtIndex('Add Label', 'label-key1', 'label-value1', 0, 'div.row:nth-of-type(2)');
// Adding Annotations doesn't work via test automation // Adding Annotations doesn't work via test automation
// See https://github.com/rancher/dashboard/issues/13191 // See https://github.com/rancher/dashboard/issues/13191
// fleetWorkspacesPage.createWorkspaceForm().lablesAnnotationsKeyValue().setKeyValueAtIndex('Add Annotation', 'ann-key1', 'ann-value1', 0, 'div.row:nth-of-type(3)'); // fleetWorkspaceCreateEditPage.lablesAnnotationsKeyValue().setKeyValueAtIndex('Add Annotation', 'ann-key1', 'ann-value1', 0, 'div.row:nth-of-type(3)');
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView() fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.create(); .create();
cy.wait('@createWorkspace').then(({ response }) => { cy.wait('@createWorkspace').then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
}); });
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowWithName(customWorkspace) .rowWithName(customWorkspace)
.checkVisible(); .checkVisible();
}); });
it('user sees custom workspace as an option in workspace selector', () => { it('user sees custom workspace as an option in workspace selector', () => {
fleetWorkspacesPage.goTo(); fleetWorkspacesListPage.goTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist(); fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
headerPo.checkCurrentWorkspace(customWorkspace); headerPo.checkCurrentWorkspace(customWorkspace);
}); });
it('can Edit Config', () => { it('can Edit Config', () => {
fleetWorkspacesPage.goTo(); const fleetWorkspaceCreateEditPage = new FleetWorkspaceCreateEditPo(customWorkspace);
fleetWorkspacesPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist(); fleetWorkspacesListPage.goTo();
fleetWorkspacesPage.sharedComponents().list().actionMenu(customWorkspace).getMenuItem('Edit Config') fleetWorkspacesListPage.waitForPage();
fleetWorkspacesListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist();
fleetWorkspacesListPage.list().actionMenu(customWorkspace).getMenuItem('Edit Config')
.click(); .click();
fleetWorkspacesPage.createWorkspaceForm(customWorkspace).waitForPage('mode=edit', 'allowedtargetnamespaces'); fleetWorkspaceCreateEditPage.waitForPage('mode=edit', 'allowedtargetnamespaces');
fleetWorkspacesPage.createWorkspaceForm().mastheadTitle().then((title) => { fleetWorkspaceCreateEditPage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain(`Workspace: ${ customWorkspace }`); expect(title.replace(/\s+/g, ' ')).to.contain(`Workspace: ${ customWorkspace }`);
}); });
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().createEditView() fleetWorkspaceCreateEditPage.resourceDetail().createEditView()
.nameNsDescription() .nameNsDescription()
.description() .description()
.set(`${ customWorkspace }-desc-edit`); .set(`${ customWorkspace }-desc-edit`);
fleetWorkspacesPage.createWorkspaceForm().sharedComponents().resourceDetail().cruResource() fleetWorkspaceCreateEditPage.resourceDetail().cruResource()
.saveAndWaitForRequests('PUT', `/v3/fleetWorkspaces/${ customWorkspace }`) .saveAndWaitForRequests('PUT', `/v3/fleetWorkspaces/${ customWorkspace }`)
.then(({ response }) => { .then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
expect(response?.body.id).to.equal(customWorkspace); expect(response?.body.id).to.equal(customWorkspace);
expect(response?.body.annotations).to.have.property('field.cattle.io/description', `${ customWorkspace }-desc-edit`); expect(response?.body.annotations).to.have.property('field.cattle.io/description', `${ customWorkspace }-desc-edit`);
}); });
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
}); });
it('can Download YAML', () => { it('can Download YAML', () => {
cy.deleteDownloadsFolder(); cy.deleteDownloadsFolder();
fleetWorkspacesPage.goTo(); fleetWorkspacesListPage.goTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist(); fleetWorkspacesListPage.list().resourceTable().sortableTable()
fleetWorkspacesPage.sharedComponents().list().actionMenu(customWorkspace).getMenuItem('Download YAML') .noRowsShouldNotExist();
fleetWorkspacesListPage.list().actionMenu(customWorkspace).getMenuItem('Download YAML')
.click(); .click();
const downloadedFilename = path.join(downloadsFolder, `${ customWorkspace }.yaml`); const downloadedFilename = path.join(downloadsFolder, `${ customWorkspace }.yaml`);
@ -418,12 +470,13 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
}); });
it('can delete workspace', () => { it('can delete workspace', () => {
fleetWorkspacesPage.goTo(); fleetWorkspacesListPage.goTo();
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().resourceTable().sortableTable().noRowsShouldNotExist(); fleetWorkspacesListPage.list().resourceTable().sortableTable()
fleetWorkspacesPage.sharedComponents().list().actionMenu(customWorkspace).getMenuItem('Delete') .noRowsShouldNotExist();
fleetWorkspacesListPage.list().actionMenu(customWorkspace).getMenuItem('Delete')
.click(); .click();
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.then((rows: any) => { .then((rows: any) => {
const promptRemove = new PromptRemove(); const promptRemove = new PromptRemove();
@ -433,10 +486,10 @@ describe('Workspaces', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] },
promptRemove.confirmField().set(customWorkspace); promptRemove.confirmField().set(customWorkspace);
promptRemove.remove(); promptRemove.remove();
cy.wait('@deleteWorkspace'); cy.wait('@deleteWorkspace');
fleetWorkspacesPage.waitForPage(); fleetWorkspacesListPage.waitForPage();
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1); .checkRowCount(false, rows.length - 1);
fleetWorkspacesPage.sharedComponents().list().resourceTable().sortableTable() fleetWorkspacesListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.should('not.contain', customWorkspace); .should('not.contain', customWorkspace);
}); });

View File

@ -1,10 +1,10 @@
import { FleetClusterGroupsListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.clustergroup.po'; import { FleetClusterGroupsCreateEditPo, FleetClusterGroupsListPagePo, FleetClusterGroupDetailsPo } 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 { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po'; import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => { describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, () => {
const fleetClusterGroups = new FleetClusterGroupsListPagePo(); const fleetClusterGroupsListPage = new FleetClusterGroupsListPagePo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
const localWorkspace = 'fleet-local'; const localWorkspace = 'fleet-local';
let clusterGroupName; let clusterGroupName;
@ -19,17 +19,19 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
}); });
it('can create cluster group', () => { it('can create cluster group', () => {
FleetClusterGroupsListPagePo.navTo(); const fleetCreateEditClusterGroupPage = new FleetClusterGroupsCreateEditPo();
fleetClusterGroups.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.sharedComponents().baseResourceList().masthead().create();
fleetClusterGroups.createFleetClusterGroupsForm().waitForPage();
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().createEditView() FleetClusterGroupsListPagePo.navTo();
fleetClusterGroupsListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace);
fleetClusterGroupsListPage.baseResourceList().masthead().create();
fleetCreateEditClusterGroupPage.waitForPage();
fleetCreateEditClusterGroupPage.resourceDetail().createEditView()
.nameNsDescription() .nameNsDescription()
.name() .name()
.set(clusterGroupName); .set(clusterGroupName);
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().cruResource() fleetCreateEditClusterGroupPage.resourceDetail().cruResource()
.saveOrCreate() .saveOrCreate()
.click() .click()
.then(() => { .then(() => {
@ -37,47 +39,51 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
clusterGroupsToDelete.push(`${ localWorkspace }/${ clusterGroupName }`); clusterGroupsToDelete.push(`${ localWorkspace }/${ clusterGroupName }`);
}); });
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
fleetClusterGroups.sharedComponents().resourceTableDetails(clusterGroupName, 1).should('be.visible'); fleetClusterGroupsListPage.resourceTableDetails(clusterGroupName, 1).should('be.visible');
}); });
it('can edit a cluster group', () => { it('can edit a cluster group', () => {
const fleetCreateEditClusterGroupPage = new FleetClusterGroupsCreateEditPo(localWorkspace, clusterGroupName);
FleetClusterGroupsListPagePo.navTo(); FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.sharedComponents().list().actionMenu(clusterGroupName).getMenuItem('Edit Config') fleetClusterGroupsListPage.list().actionMenu(clusterGroupName).getMenuItem('Edit Config')
.click(); .click();
fleetClusterGroups.createFleetClusterGroupsForm(localWorkspace, clusterGroupName).waitForPage('mode=edit'); fleetCreateEditClusterGroupPage.waitForPage('mode=edit');
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().createEditView() fleetCreateEditClusterGroupPage.resourceDetail().createEditView()
.nameNsDescription() .nameNsDescription()
.description() .description()
.set(`${ clusterGroupName }-fleet-desc`); .set(`${ clusterGroupName }-fleet-desc`);
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().cruResource() fleetCreateEditClusterGroupPage.resourceDetail().cruResource()
.saveAndWaitForRequests('PUT', `v1/fleet.cattle.io.clustergroups/${ localWorkspace }/${ clusterGroupName }`) .saveAndWaitForRequests('PUT', `v1/fleet.cattle.io.clustergroups/${ localWorkspace }/${ clusterGroupName }`)
.then(({ response }) => { .then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata).to.have.property('name', clusterGroupName); expect(response?.body.metadata).to.have.property('name', clusterGroupName);
expect(response?.body.metadata.annotations).to.have.property('field.cattle.io/description', `${ clusterGroupName }-fleet-desc`); expect(response?.body.metadata.annotations).to.have.property('field.cattle.io/description', `${ clusterGroupName }-fleet-desc`);
}); });
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
}); });
it('can clone a cluster group', () => { it('can clone a cluster group', () => {
const fleetCreateEditClusterGroupPage = new FleetClusterGroupsCreateEditPo(localWorkspace, clusterGroupName);
FleetClusterGroupsListPagePo.navTo(); FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.sharedComponents().list().actionMenu(clusterGroupName).getMenuItem('Clone') fleetClusterGroupsListPage.list().actionMenu(clusterGroupName).getMenuItem('Clone')
.click(); .click();
fleetClusterGroups.createFleetClusterGroupsForm(localWorkspace, clusterGroupName).waitForPage('mode=clone'); fleetCreateEditClusterGroupPage.waitForPage('mode=clone');
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().createEditView() fleetCreateEditClusterGroupPage.resourceDetail().createEditView()
.nameNsDescription() .nameNsDescription()
.name() .name()
.set(`clone-${ clusterGroupName }`); .set(`clone-${ clusterGroupName }`);
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().createEditView() fleetCreateEditClusterGroupPage.resourceDetail().createEditView()
.nameNsDescription() .nameNsDescription()
.description() .description()
.set(`${ clusterGroupName }-fleet-desc`); .set(`${ clusterGroupName }-fleet-desc`);
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().cruResource() fleetCreateEditClusterGroupPage.resourceDetail().cruResource()
.saveAndWaitForRequests('POST', 'v1/fleet.cattle.io.clustergroups') .saveAndWaitForRequests('POST', 'v1/fleet.cattle.io.clustergroups')
.then(({ response }) => { .then(({ response }) => {
expect(response?.statusCode).to.eq(201); expect(response?.statusCode).to.eq(201);
@ -86,17 +92,17 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
expect(response?.body.metadata).to.have.property('name', `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`); expect(response?.body.metadata.annotations).to.have.property('field.cattle.io/description', `${ clusterGroupName }-fleet-desc`);
}); });
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
fleetClusterGroups.sharedComponents().resourceTableDetails(`clone-${ clusterGroupName }`, 1).should('be.visible'); fleetClusterGroupsListPage.resourceTableDetails(`clone-${ clusterGroupName }`, 1).should('be.visible');
}); });
it('can delete cluster group', () => { it('can delete cluster group', () => {
FleetClusterGroupsListPagePo.navTo(); FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.sharedComponents().list().actionMenu(clusterGroupName).getMenuItem('Delete') fleetClusterGroupsListPage.list().actionMenu(clusterGroupName).getMenuItem('Delete')
.click(); .click();
fleetClusterGroups.sharedComponents().list().resourceTable().sortableTable() fleetClusterGroupsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.then((rows: any) => { .then((rows: any) => {
const promptRemove = new PromptRemove(); const promptRemove = new PromptRemove();
@ -105,10 +111,10 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
promptRemove.remove(); promptRemove.remove();
cy.wait('@deleteClusterGroup'); cy.wait('@deleteClusterGroup');
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
fleetClusterGroups.sharedComponents().list().resourceTable().sortableTable() fleetClusterGroupsListPage.list().resourceTable().sortableTable()
.checkRowCount(false, rows.length - 1); .checkRowCount(false, rows.length - 1);
fleetClusterGroups.sharedComponents().list().resourceTable().sortableTable() fleetClusterGroupsListPage.list().resourceTable().sortableTable()
.rowNames('.col-link-detail') .rowNames('.col-link-detail')
.should('not.contain', `clone-${ clusterGroupName }`); .should('not.contain', `clone-${ clusterGroupName }`);
}); });
@ -116,12 +122,14 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
// testing https://github.com/rancher/dashboard/issues/11687 // testing https://github.com/rancher/dashboard/issues/11687
it('can open "Edit as YAML"', () => { it('can open "Edit as YAML"', () => {
const fleetCreateEditClusterGroupPage = new FleetClusterGroupsCreateEditPo();
FleetClusterGroupsListPagePo.navTo(); FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
fleetClusterGroups.sharedComponents().baseResourceList().masthead().create(); fleetClusterGroupsListPage.baseResourceList().masthead().create();
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().createEditView() fleetCreateEditClusterGroupPage.resourceDetail().createEditView()
.editAsYaml(); .editAsYaml();
fleetClusterGroups.createFleetClusterGroupsForm().sharedComponents().resourceDetail().resourceYaml() fleetCreateEditClusterGroupPage.resourceDetail().resourceYaml()
.codeMirror() .codeMirror()
.checkExists(); .checkExists();
}); });
@ -130,14 +138,14 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
const groupName = 'default'; const groupName = 'default';
FleetClusterGroupsListPagePo.navTo(); FleetClusterGroupsListPagePo.navTo();
fleetClusterGroups.waitForPage(); fleetClusterGroupsListPage.waitForPage();
headerPo.selectWorkspace(localWorkspace); headerPo.selectWorkspace(localWorkspace);
fleetClusterGroups.sharedComponents().list().rowWithName(groupName).checkVisible(); fleetClusterGroupsListPage.list().rowWithName(groupName).checkVisible();
// check table headers // check table headers
const expectedHeaders = ['State', 'Name', 'Clusters Ready', 'Resources', 'Age']; const expectedHeaders = ['State', 'Name', 'Clusters Ready', 'Resources', 'Age'];
fleetClusterGroups.sharedComponents().list().resourceTable().sortableTable() fleetClusterGroupsListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -145,7 +153,7 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
}); });
// go to fleet cluster details // go to fleet cluster details
fleetClusterGroups.sharedComponents().goToDetailsPage(groupName); fleetClusterGroupsListPage.goToDetailsPage(groupName);
const fleetClusterGroupDetailsPage = new FleetClusterGroupDetailsPo(localWorkspace, groupName); const fleetClusterGroupDetailsPage = new FleetClusterGroupDetailsPo(localWorkspace, groupName);
@ -154,7 +162,7 @@ describe('Cluster Groups', { testIsolation: 'off', tags: ['@fleet', '@adminUser'
// check table headers // check table headers
const expectedHeadersDetailsView = ['State', 'Name', 'Bundles Ready', 'Repos Ready', 'Resources', 'Last Seen', 'Age']; const expectedHeadersDetailsView = ['State', 'Name', 'Bundles Ready', 'Repos Ready', 'Resources', 'Last Seen', 'Age'];
fleetClusterGroupDetailsPage.clusterList().resourceTable().sortableTable() fleetClusterGroupDetailsPage.clusterList().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {

View File

@ -1,7 +1,4 @@
import { FleetDashboardPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po'; import { FleetDashboardListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet-dashboard.po';
import FleetGitRepoDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.gitrepo.po';
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 BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
import { LONG_TIMEOUT_OPT, MEDIUM_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 { gitRepoTargetAllClustersRequest } from '@/cypress/e2e/blueprints/fleet/gitrepos';
@ -9,12 +6,12 @@ import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import { MenuActions } from '@/cypress/support/types/menu-actions'; import { MenuActions } from '@/cypress/support/types/menu-actions';
import * as path from 'path'; import * as path from 'path';
import * as jsyaml from 'js-yaml'; import * as jsyaml from 'js-yaml';
import { FleetGitRepoListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po'; import { FleetGitRepoListPagePo, FleetGitRepoDetailsPo, FleetGitRepoCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po';
const downloadsFolder = Cypress.config('downloadsFolder'); const downloadsFolder = Cypress.config('downloadsFolder');
describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () => { describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () => {
const fleetDashboardPage = new FleetDashboardPagePo('_'); const fleetDashboardPage = new FleetDashboardListPagePo('_');
const gitRepoCreatePage = new GitRepoCreatePo('_'); const gitRepoCreatePage = new FleetGitRepoCreateEditPo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
let repoName; let repoName;
@ -70,7 +67,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
const row = fleetDashboardPage.collapsibleTable(localWorkspace).sortableTable().row(0); const row = fleetDashboardPage.collapsibleTable(localWorkspace).sortableTable().row(0);
row.get('.bg-success[data-testid="clusters-ready"]', LONG_TIMEOUT_OPT).should('exist'); row.get('.bg-success[data-testid="clusters-ready"]', LONG_TIMEOUT_OPT).should('exist');
row.get('.bg-success[data-testid="clusters-ready"] span').should('have.text', '1/1'); row.get('.bg-success[data-testid="clusters-ready"] span', MEDIUM_TIMEOUT_OPT).should('have.text', '1/1');
row.get('.bg-success[data-testid="bundles-ready"]').should('exist'); row.get('.bg-success[data-testid="bundles-ready"]').should('exist');
row.get('.bg-success[data-testid="bundles-ready"] span').should('have.text', '1/1'); row.get('.bg-success[data-testid="bundles-ready"] span').should('have.text', '1/1');
@ -84,7 +81,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
fleetDashboardPage.goTo(); fleetDashboardPage.goTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
fleetDashboardPage.sharedComponents().goToDetailsPage(repoName); fleetDashboardPage.collapsibleTable(localWorkspace).goToDetailsPage(repoName);
gitRepoDetails.waitForPage(null, 'bundles'); gitRepoDetails.waitForPage(null, 'bundles');
}); });
@ -121,7 +118,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
cy.intercept('GET', '/v1/fleet.cattle.io.clusters?exclude=metadata.managedFields').as('getFleetClusters'); cy.intercept('GET', '/v1/fleet.cattle.io.clusters?exclude=metadata.managedFields').as('getFleetClusters');
cy.intercept('GET', '/v1/secrets?exclude=metadata.managedFields').as('getSecrets'); cy.intercept('GET', '/v1/secrets?exclude=metadata.managedFields').as('getSecrets');
const gitRepoEditPage = new GitRepoEditPo(localWorkspace, repoName); const gitRepoEditPage = new FleetGitRepoCreateEditPo(localWorkspace, repoName);
fleetDashboardPage.goTo(); fleetDashboardPage.goTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
@ -134,20 +131,20 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
expect(title.replace(/\s+/g, ' ')).to.contain(`Git Repo: Clone from ${ repoName }`); expect(title.replace(/\s+/g, ' ')).to.contain(`Git Repo: Clone from ${ repoName }`);
}); });
headerPo.selectWorkspace(defaultWorkspace); headerPo.selectWorkspace(defaultWorkspace);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nameNsDescription() gitRepoEditPage.resourceDetail().createEditView().nameNsDescription()
.name() .name()
.set(`clone-${ repoName }`); .set(`clone-${ repoName }`);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage(); gitRepoEditPage.resourceDetail().createEditView().nextPage();
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage(); gitRepoEditPage.resourceDetail().createEditView().nextPage();
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage(); gitRepoEditPage.resourceDetail().createEditView().nextPage();
cy.wait('@getSecrets', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200); cy.wait('@getSecrets', MEDIUM_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().create() gitRepoEditPage.resourceDetail().createEditView().create()
.then(() => { .then(() => {
removeGitRepo = true; removeGitRepo = true;
reposToDelete.push(`${ defaultWorkspace }/clone-${ repoName }`); reposToDelete.push(`${ defaultWorkspace }/clone-${ repoName }`);
}); });
FleetDashboardPagePo.navTo(); FleetDashboardListPagePo.navTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
fleetDashboardPage.collapsibleTable(defaultWorkspace).sortableTable().rowElementWithName(`clone-${ repoName }`).should('be.visible'); fleetDashboardPage.collapsibleTable(defaultWorkspace).sortableTable().rowElementWithName(`clone-${ repoName }`).should('be.visible');
fleetDashboardPage.collapsibleTable(localWorkspace).sortableTable().rowElementWithName(repoName).should('be.visible'); fleetDashboardPage.collapsibleTable(localWorkspace).sortableTable().rowElementWithName(repoName).should('be.visible');
@ -175,7 +172,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
}); });
it('can Edit Yaml', () => { it('can Edit Yaml', () => {
const gitRepoEditPage = new GitRepoEditPo(localWorkspace, repoName); const gitRepoEditPage = new FleetGitRepoCreateEditPo(localWorkspace, repoName);
fleetDashboardPage.goTo(); fleetDashboardPage.goTo();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
@ -209,7 +206,7 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
}); });
it('can Edit Config', () => { it('can Edit Config', () => {
const gitRepoEditPage = new GitRepoEditPo(localWorkspace, repoName); const gitRepoEditPage = new FleetGitRepoCreateEditPo(localWorkspace, repoName);
const description = `${ repoName }-desc`; const description = `${ repoName }-desc`;
fleetDashboardPage.goTo(); fleetDashboardPage.goTo();
@ -218,11 +215,11 @@ describe('Fleet Dashboard', { tags: ['@fleet', '@adminUser', '@jenkins'] }, () =
.click(); .click();
gitRepoEditPage.waitForPage('mode=edit'); gitRepoEditPage.waitForPage('mode=edit');
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nameNsDescription() gitRepoEditPage.resourceDetail().createEditView().nameNsDescription()
.description() .description()
.set(description); .set(description);
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().nextPage(); gitRepoEditPage.resourceDetail().createEditView().nextPage();
gitRepoEditPage.sharedComponents().resourceDetail().createEditView().save(); gitRepoEditPage.resourceDetail().createEditView().save();
fleetDashboardPage.waitForPage(); fleetDashboardPage.waitForPage();
}); });

View File

@ -1,20 +1,18 @@
import { FleetClusterListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.cluster.po'; import { FleetClusterListPagePo, FleetClusterDetailsPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.cluster.po';
import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po'; import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
import { MenuActions } from '@/cypress/support/types/menu-actions'; import { MenuActions } from '@/cypress/support/types/menu-actions';
import { gitRepoTargetAllClustersRequest } from '@/cypress/e2e/blueprints/fleet/gitrepos'; import { gitRepoTargetAllClustersRequest } from '@/cypress/e2e/blueprints/fleet/gitrepos';
import { FleetGitRepoListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po'; import { FleetGitRepoListPagePo, FleetGitRepoCreateEditPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po';
import FleetClusterDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.cluster.po';
import { WorkloadsDeploymentsListPagePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads-deployments.po'; import { WorkloadsDeploymentsListPagePo } from '@/cypress/e2e/po/pages/explorer/workloads/workloads-deployments.po';
import * as path from 'path'; import * as path from 'path';
import * as jsyaml from 'js-yaml'; import * as jsyaml from 'js-yaml';
import { HeaderPo } from '@/cypress/e2e/po/components/header.po'; import { HeaderPo } from '@/cypress/e2e/po/components/header.po';
import { GitRepoCreatePo } from '@/cypress/e2e/po/pages/fleet/gitrepo-create.po';
import { LONG_TIMEOUT_OPT, MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; import { LONG_TIMEOUT_OPT, MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import { FeatureFlagsPagePo } from '@/cypress/e2e/po/pages/global-settings/feature-flags.po'; import { FeatureFlagsPagePo } from '@/cypress/e2e/po/pages/global-settings/feature-flags.po';
describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => { describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
const fleetClusterListPage = new FleetClusterListPagePo(); const fleetClusterListPage = new FleetClusterListPagePo();
const fleetGitRepoListPage = new FleetGitRepoListPagePo(); const fleetGitRepoPage = new FleetGitRepoListPagePo();
const clusterList = new ClusterManagerListPagePo(); const clusterList = new ClusterManagerListPagePo();
const featureFlagsPage = new FeatureFlagsPagePo(); const featureFlagsPage = new FeatureFlagsPagePo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
@ -102,49 +100,51 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
}); });
// go to fleet gitrepo and wait until git repo is in active state // go to fleet gitrepo and wait until git repo is in active state
fleetGitRepoListPage.navTo(); fleetGitRepoPage.navTo();
fleetGitRepoListPage.waitForPage(); fleetGitRepoPage.waitForPage();
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
fleetGitRepoListPage.sharedComponents().resourceTableDetails(gitRepo, 1).contains('Active', LONG_TIMEOUT_OPT); fleetGitRepoPage.resourceTableDetails(gitRepo, 1).contains('Active', LONG_TIMEOUT_OPT);
// go to fleet clusters // go to fleet clusters
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage(); fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); fleetClusterListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible();
// check name // check name
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).should('be.visible'); fleetClusterListPage.resourceTableDetails(clusterName, 2).should('be.visible');
// check cluster state in fleet // check cluster state in fleet
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 1).contains('Not Ready', MEDIUM_TIMEOUT_OPT); fleetClusterListPage.resourceTableDetails(clusterName, 1).contains('Not Ready', MEDIUM_TIMEOUT_OPT);
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 1).contains('Active', LONG_TIMEOUT_OPT); fleetClusterListPage.resourceTableDetails(clusterName, 1).contains('Active', LONG_TIMEOUT_OPT);
// check bundles ready // check bundles ready
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 3).should('have.text', '4'); fleetClusterListPage.resourceTableDetails(clusterName, 3).should('have.text', '4');
// check repos ready // check repos ready
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 4).should('have.text', '1'); fleetClusterListPage.resourceTableDetails(clusterName, 4).should('have.text', '1');
// check resources: testing https://github.com/rancher/dashboard/issues/11154 // check resources: testing https://github.com/rancher/dashboard/issues/11154
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 5).contains( ' 15 ', MEDIUM_TIMEOUT_OPT); fleetClusterListPage.resourceTableDetails(clusterName, 5).contains( ' 15 ', MEDIUM_TIMEOUT_OPT);
// check cluster labels // check cluster labels
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().subRows() fleetClusterListPage.list().resourceTable().sortableTable()
.subRows()
.should('contain.text', 'foo=bar'); .should('contain.text', 'foo=bar');
const fleetClusterDetailsPage = new FleetClusterDetailsPo(namespace, clusterName); const fleetClusterDetailsPage = new FleetClusterDetailsPo(namespace, clusterName);
// go to cluster details in fleet // go to cluster details in fleet
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).find('a').click(); fleetClusterListPage.goToDetailsPage(clusterName);
fleetClusterDetailsPage.waitForPage(null, 'repos'); fleetClusterDetailsPage.waitForPage(null, 'repos');
fleetClusterDetailsPage.clusterTabs().clickTabWithSelector('[data-testid="btn-repos"]'); fleetClusterDetailsPage.clusterTabs().clickTabWithSelector('[data-testid="btn-repos"]');
// check state // check state
fleetClusterDetailsPage.gitReposList().details(gitRepo, 1).contains('Ready'); fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 1).contains('Ready');
// check name // check name
fleetClusterDetailsPage.gitReposList().details(gitRepo, 2).should('be.visible'); fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 2).should('be.visible');
// check repo // check repo
fleetClusterDetailsPage.gitReposList().details(gitRepo, 3).contains('rancher/fleet-test-data master'); fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 3).contains('rancher/fleet-test-data master');
// check target // check target
fleetClusterDetailsPage.gitReposList().details(gitRepo, 4).contains('Advanced'); fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 4).contains('Advanced');
// check cluster resources // check cluster resources
fleetClusterDetailsPage.gitReposList().details(gitRepo, 5).should('have.text', ' 1 '); fleetClusterDetailsPage.gitReposList().resourceTableDetails(gitRepo, 5).should('have.text', ' 1 ');
}); });
it('check all tabs are available in the details view', () => { it('check all tabs are available in the details view', () => {
@ -155,7 +155,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage(); fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).find('a').click(); fleetClusterListPage.goToDetailsPage(clusterName);
fleetClusterDetailsPage.waitForPage(null, 'repos'); fleetClusterDetailsPage.waitForPage(null, 'repos');
fleetClusterDetailsPage.clusterTabs().allTabs().should('have.length', 4, { timeout: 10000 }); fleetClusterDetailsPage.clusterTabs().allTabs().should('have.length', 4, { timeout: 10000 });
const tabs = ['Git Repos', 'Conditions', 'Recent Events', 'Related Resources']; const tabs = ['Git Repos', 'Conditions', 'Recent Events', 'Related Resources'];
@ -184,7 +184,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
cy.intercept('PUT', `v1/fleet.cattle.io.clusters/${ namespace }/${ clusterName }`).as('pause'); cy.intercept('PUT', `v1/fleet.cattle.io.clusters/${ namespace }/${ clusterName }`).as('pause');
// pause // pause
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Pause') fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Pause')
.click(); .click();
cy.wait('@pause').then(({ response }) => { cy.wait('@pause').then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
@ -194,7 +194,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
}); });
// check cluster state // check cluster state
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 1).contains('Paused', LONG_TIMEOUT_OPT); fleetClusterListPage.resourceTableDetails(clusterName, 1).contains('Paused', LONG_TIMEOUT_OPT);
}); });
it('can Unpause', () => { it('can Unpause', () => {
@ -206,7 +206,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
cy.intercept('PUT', `v1/fleet.cattle.io.clusters/${ namespace }/${ clusterName }`).as('unpause'); cy.intercept('PUT', `v1/fleet.cattle.io.clusters/${ namespace }/${ clusterName }`).as('unpause');
// unpause // unpause
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Unpause') fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Unpause')
.click(); .click();
cy.wait('@unpause').then(({ response }) => { cy.wait('@unpause').then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
@ -216,7 +216,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
}); });
// check cluster state // check cluster state
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 1).contains('Active', LONG_TIMEOUT_OPT); fleetClusterListPage.resourceTableDetails(clusterName, 1).contains('Active', LONG_TIMEOUT_OPT);
}); });
it('can Edit Config', () => { it('can Edit Config', () => {
@ -224,16 +224,16 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage(); fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Edit Config') fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Edit Config')
.click(); .click();
const editFleetCluster = fleetClusterListPage.editFleetCluster(undefined, clusterName); const editFleetCluster = fleetClusterListPage.editFleetCluster(undefined, clusterName);
editFleetCluster.waitForPage('mode=edit'); editFleetCluster.waitForPage('mode=edit');
editFleetCluster.sharedComponents().resourceDetail().createEditView().nameNsDescription() editFleetCluster.resourceDetail().createEditView().nameNsDescription()
.description() .description()
.set(`${ clusterName }-fleet-desc`); .set(`${ clusterName }-fleet-desc`);
editFleetCluster.sharedComponents().resourceDetail().cruResource().saveAndWaitForRequests('PUT', `v1/fleet.cattle.io.clusters/${ namespace }/${ clusterName }`) editFleetCluster.resourceDetail().cruResource().saveAndWaitForRequests('PUT', `v1/fleet.cattle.io.clusters/${ namespace }/${ clusterName }`)
.then(({ response }) => { .then(({ response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);
expect(response?.body.metadata).to.have.property('name', clusterName); expect(response?.body.metadata).to.have.property('name', clusterName);
@ -248,7 +248,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage(); fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Download YAML') fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Download YAML')
.click(); .click();
const downloadedFilename = path.join(downloadsFolder, `${ clusterName }.yaml`); const downloadedFilename = path.join(downloadsFolder, `${ clusterName }.yaml`);
@ -286,32 +286,34 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
cy.intercept('PUT', '/v1/userpreferences/*').as('changeWorkspace'); cy.intercept('PUT', '/v1/userpreferences/*').as('changeWorkspace');
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Change workspace') fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Change workspace')
.click(); .click();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().toggle(); fleetClusterListPage.changeWorkspaceForm().workspaceSelect().toggle();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().clickOptionWithLabel(customWorkspace); fleetClusterListPage.changeWorkspaceForm().workspaceSelect().clickOptionWithLabel(customWorkspace);
fleetClusterListPage.changeWorkspaceForm().applyAndWait('v3/clusters/*'); fleetClusterListPage.changeWorkspaceForm().applyAndWait('v3/clusters/*');
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT); fleetClusterListPage.list().resourceTable().sortableTable()
.checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT);
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage(); fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(customWorkspace); headerPo.selectWorkspace(customWorkspace);
cy.wait('@changeWorkspace'); cy.wait('@changeWorkspace');
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).isVisible(); fleetClusterListPage.resourceTableDetails(clusterName, 2).isVisible();
// restore // restore
fleetClusterListPage.sharedComponents().list().actionMenu(clusterName).getMenuItem('Change workspace') fleetClusterListPage.list().actionMenu(clusterName).getMenuItem('Change workspace')
.click(); .click();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().toggle(); fleetClusterListPage.changeWorkspaceForm().workspaceSelect().toggle();
fleetClusterListPage.changeWorkspaceForm().workspaceSelect().clickOptionWithLabel(namespace); fleetClusterListPage.changeWorkspaceForm().workspaceSelect().clickOptionWithLabel(namespace);
fleetClusterListPage.changeWorkspaceForm().applyAndWait('v3/clusters/*'); fleetClusterListPage.changeWorkspaceForm().applyAndWait('v3/clusters/*');
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT); fleetClusterListPage.list().resourceTable().sortableTable()
.checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT);
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage(); fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
cy.wait('@changeWorkspace'); cy.wait('@changeWorkspace');
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).isVisible(); fleetClusterListPage.resourceTableDetails(clusterName, 2).isVisible();
}); });
it('removing git repo should remove bundles on downstream cluster (deployments removed)', () => { it('removing git repo should remove bundles on downstream cluster (deployments removed)', () => {
@ -338,8 +340,10 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
fleetClusterListPage.waitForPage(); fleetClusterListPage.waitForPage();
headerPo.selectWorkspace(namespace); headerPo.selectWorkspace(namespace);
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); fleetClusterListPage.list().resourceTable().sortableTable()
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT); .checkLoadingIndicatorNotVisible();
fleetClusterListPage.list().resourceTable().sortableTable()
.checkRowCount(true, 1, MEDIUM_TIMEOUT_OPT);
}); });
after('clean up', () => { after('clean up', () => {
@ -384,18 +388,20 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
}); });
it('should be able to list clusters in local workspace', () => { it('should be able to list clusters in local workspace', () => {
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkRowCount(false, 1); fleetClusterListPage.list().resourceTable().sortableTable()
.checkRowCount(false, 1);
}); });
it('Git Repos Tab Add Repository button takes you to the correct page', () => { it('Git Repos Tab Add Repository button takes you to the correct page', () => {
// testing https://github.com/rancher/dashboard/issues/11198 // testing https://github.com/rancher/dashboard/issues/11198
const fleetClusterDetailsPage = new FleetClusterDetailsPo(workspace, 'local'); const fleetClusterDetailsPage = new FleetClusterDetailsPo(workspace, 'local');
const gitRepoCreatePage = new GitRepoCreatePo('_'); const gitRepoCreatePage = new FleetGitRepoCreateEditPo();
fleetClusterListPage.sharedComponents().resourceTable().sortableTable().checkLoadingIndicatorNotVisible(); fleetClusterListPage.list().resourceTable().sortableTable()
fleetClusterListPage.sharedComponents().resourceTableDetails('local', 2).find('a').click(); .checkLoadingIndicatorNotVisible();
fleetClusterListPage.goToDetailsPage('local');
fleetClusterDetailsPage.waitForPage(null, 'repos'); fleetClusterDetailsPage.waitForPage(null, 'repos');
fleetClusterDetailsPage.gitReposTab().addRepostoryButton().click(); fleetClusterDetailsPage.addRepostoryButton().click();
gitRepoCreatePage.waitForPage(); gitRepoCreatePage.waitForPage();
gitRepoCreatePage.mastheadTitle().then((title) => { gitRepoCreatePage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Git Repo: Create'); expect(title.replace(/\s+/g, ' ')).to.contain('Git Repo: Create');
@ -406,7 +412,8 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
fleetClusterListPage.goTo(); fleetClusterListPage.goTo();
headerPo.selectWorkspace(workspace); headerPo.selectWorkspace(workspace);
const constActionMenu = fleetClusterListPage.sharedComponents().resourceTable().sortableTable().rowActionMenuOpen('local'); const constActionMenu = fleetClusterListPage.list().resourceTable().sortableTable()
.rowActionMenuOpen('local');
const allowedActions: MenuActions[] = [ const allowedActions: MenuActions[] = [
MenuActions.Pause, MenuActions.Pause,
@ -437,10 +444,10 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
}); });
// go to fleet gitrepo // go to fleet gitrepo
fleetGitRepoListPage.navTo(); fleetGitRepoPage.navTo();
fleetGitRepoListPage.waitForPage(); fleetGitRepoPage.waitForPage();
headerPo.selectWorkspace(workspace); headerPo.selectWorkspace(workspace);
fleetGitRepoListPage.sharedComponents().list().rowWithName(gitRepo).checkVisible(); fleetGitRepoPage.list().rowWithName(gitRepo).checkVisible();
// go to fleet cluster list // go to fleet cluster list
FleetClusterListPagePo.navTo(); FleetClusterListPagePo.navTo();
@ -449,7 +456,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
// check table headers // check table headers
const expectedHeaders = ['State', 'Name', 'Bundles Ready', 'Repos Ready', 'Resources', 'Last Seen', 'Age']; const expectedHeaders = ['State', 'Name', 'Bundles Ready', 'Repos Ready', 'Resources', 'Last Seen', 'Age'];
fleetClusterListPage.sharedComponents().list().resourceTable().sortableTable() fleetClusterListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -457,7 +464,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
}); });
// go to fleet cluster details // go to fleet cluster details
fleetClusterListPage.sharedComponents().resourceTableDetails(clusterName, 2).find('a').click(); fleetClusterListPage.resourceTableDetails(clusterName, 2).find('a').click();
const fleetClusterDetailsPage = new FleetClusterDetailsPo(workspace, clusterName); const fleetClusterDetailsPage = new FleetClusterDetailsPo(workspace, clusterName);
@ -466,7 +473,7 @@ describe('Fleet Clusters', { tags: ['@fleet', '@adminUser'] }, () => {
// check table headers // check table headers
const expectedHeadersDetailsView = ['Cluster State', 'Name', 'Repo', 'Target', 'Cluster Resources', 'Age']; const expectedHeadersDetailsView = ['Cluster State', 'Name', 'Repo', 'Target', 'Cluster Resources', 'Age'];
fleetClusterDetailsPage.gitReposTab().list().resourceTable().sortableTable() fleetClusterDetailsPage.gitReposList().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {

View File

@ -1,6 +1,4 @@
import { GitRepoCreatePo } from '@/cypress/e2e/po/pages/fleet/gitrepo-create.po'; import { FleetGitRepoListPagePo, FleetGitRepoCreateEditPo, FleetGitRepoDetailsPo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po';
import { FleetGitRepoListPagePo } from '@/cypress/e2e/po/pages/fleet/fleet.cattle.io.gitrepo.po';
import FleetGitRepoDetailsPo from '@/cypress/e2e/po/detail/fleet/fleet.cattle.io.gitrepo.po';
import { gitRepoCreateRequest, gitRepoTargetAllClustersRequest } from '@/cypress/e2e/blueprints/fleet/gitrepos'; import { gitRepoCreateRequest, gitRepoTargetAllClustersRequest } from '@/cypress/e2e/blueprints/fleet/gitrepos';
import { generateFakeClusterDataAndIntercepts } from '@/cypress/e2e/blueprints/nav/fake-cluster'; import { generateFakeClusterDataAndIntercepts } from '@/cypress/e2e/blueprints/nav/fake-cluster';
import PreferencesPagePo from '@/cypress/e2e/po/pages/preferences.po'; import PreferencesPagePo from '@/cypress/e2e/po/pages/preferences.po';
@ -16,8 +14,8 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
let adminUserId = ''; let adminUserId = '';
describe('Create', () => { describe('Create', () => {
const listPage = new FleetGitRepoListPagePo(); const gitRepoListPage = new FleetGitRepoListPagePo();
const gitRepoCreatePage = new GitRepoCreatePo('_'); const gitRepoCreatePage = new FleetGitRepoCreateEditPo();
const headerPo = new HeaderPo(); const headerPo = new HeaderPo();
const reposToDelete = []; const reposToDelete = [];
@ -67,23 +65,23 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
headerPo.selectWorkspace('fleet-default'); headerPo.selectWorkspace('fleet-default');
// Metadata step // Metadata step
gitRepoCreatePage.sharedComponents().resourceDetail().createEditView().nameNsDescription() gitRepoCreatePage.resourceDetail().createEditView().nameNsDescription()
.name() .name()
.set(name); .set(name);
gitRepoCreatePage.sharedComponents().resourceDetail().createEditView().nextPage(); gitRepoCreatePage.resourceDetail().createEditView().nextPage();
// Repository details step // Repository details step
gitRepoCreatePage.setGitRepoUrl(repo); gitRepoCreatePage.setGitRepoUrl(repo);
gitRepoCreatePage.setBranchName(branch); gitRepoCreatePage.setBranchName(branch);
gitRepoCreatePage.gitRepoPaths().setValueAtIndex(paths[0], 0); gitRepoCreatePage.gitRepoPaths().setValueAtIndex(paths[0], 0);
gitRepoCreatePage.sharedComponents().resourceDetail().createEditView().nextPage(); gitRepoCreatePage.resourceDetail().createEditView().nextPage();
// Target info step // Target info step
gitRepoCreatePage.targetCluster().toggle(); gitRepoCreatePage.targetCluster().toggle();
gitRepoCreatePage.targetCluster().clickOption(6); gitRepoCreatePage.targetCluster().clickOption(6);
gitRepoCreatePage.sharedComponents().resourceDetail().createEditView().nextPage(); gitRepoCreatePage.resourceDetail().createEditView().nextPage();
// Advanced info step // Advanced info step
gitRepoCreatePage.gitAuthSelectOrCreate().createSSHAuth('test1', 'test1', 'KNOWN_HOSTS'); gitRepoCreatePage.gitAuthSelectOrCreate().createSSHAuth('test1', 'test1', 'KNOWN_HOSTS');
@ -103,7 +101,7 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
cy.wait('@getSecrets', EXTRA_LONG_TIMEOUT_OPT).its('response.statusCode').should('eq', 200); cy.wait('@getSecrets', EXTRA_LONG_TIMEOUT_OPT).its('response.statusCode').should('eq', 200);
gitRepoCreatePage.sharedComponents().resourceDetail().createEditView().create() gitRepoCreatePage.resourceDetail().createEditView().create()
.then(() => { .then(() => {
reposToDelete.push(`fleet-default/${ name }`); reposToDelete.push(`fleet-default/${ name }`);
}); });
@ -141,9 +139,7 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
expect(response.statusCode).to.eq(201); expect(response.statusCode).to.eq(201);
expect(request.body).to.deep.eq(gitRepoCreateRequest); expect(request.body).to.deep.eq(gitRepoCreateRequest);
const listPage = new FleetGitRepoListPagePo(); gitRepoListPage.waitForPage();
listPage.waitForPage();
const prefPage = new PreferencesPagePo(); const prefPage = new PreferencesPagePo();
@ -164,18 +160,18 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
}); });
prefPage.languageDropdownMenu().isClosed(); prefPage.languageDropdownMenu().isClosed();
listPage.goTo(); gitRepoListPage.goTo();
listPage.waitForPage(); gitRepoListPage.waitForPage();
listPage.sharedComponents().list().resourceTable().checkVisible(); gitRepoListPage.list().resourceTable().checkVisible();
listPage.sharedComponents().list().resourceTable().sortableTable() gitRepoListPage.list().resourceTable().sortableTable()
.checkVisible(); .checkVisible();
listPage.sharedComponents().list().resourceTable().sortableTable() gitRepoListPage.list().resourceTable().sortableTable()
.checkLoadingIndicatorNotVisible(); .checkLoadingIndicatorNotVisible();
listPage.sharedComponents().list().resourceTable().sortableTable() gitRepoListPage.list().resourceTable().sortableTable()
.noRowsShouldNotExist(); .noRowsShouldNotExist();
// TESTING https://github.com/rancher/dashboard/issues/9984 make sure details page loads fine // TESTING https://github.com/rancher/dashboard/issues/9984 make sure details page loads fine
listPage.sharedComponents().goToDetailsPage('fleet-e2e-test-gitrepo'); gitRepoListPage.goToDetailsPage('fleet-e2e-test-gitrepo');
gitRepoCreatePage.mastheadTitle().then((title) => { gitRepoCreatePage.mastheadTitle().then((title) => {
expect(title.replace(/\s+/g, ' ')).to.contain('Git 仓库: fleet-e2e-test-gitrepo'); expect(title.replace(/\s+/g, ' ')).to.contain('Git 仓库: fleet-e2e-test-gitrepo');
}); });
@ -199,14 +195,14 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
const workspace = 'fleet-default'; const workspace = 'fleet-default';
// go to fleet gitrepo // go to fleet gitrepo
listPage.goTo(); gitRepoListPage.goTo();
listPage.waitForPage(); gitRepoListPage.waitForPage();
headerPo.selectWorkspace(workspace); headerPo.selectWorkspace(workspace);
// check table headers // check table headers
const expectedHeadersListView = ['State', 'Name', 'Repo', 'Target', 'Clusters Ready', 'Resources', 'Age']; const expectedHeadersListView = ['State', 'Name', 'Repo', 'Target', 'Clusters Ready', 'Resources', 'Age'];
listPage.sharedComponents().list().resourceTable().sortableTable() gitRepoListPage.list().resourceTable().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -214,7 +210,7 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
}); });
// go to fleet gitrepo details // go to fleet gitrepo details
listPage.sharedComponents().resourceTableDetails(this.gitRepo, 2).find('a').click(); gitRepoListPage.goToDetailsPage(this.gitRepo);
const gitRepoDetails = new FleetGitRepoDetailsPo(workspace, this.gitRepo); const gitRepoDetails = new FleetGitRepoDetailsPo(workspace, this.gitRepo);
@ -223,7 +219,7 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
// check table headers // check table headers
const expectedHeadersDetailsView = ['State', 'Name', 'Deployments', 'Last Updated', 'Date']; const expectedHeadersDetailsView = ['State', 'Name', 'Deployments', 'Last Updated', 'Date'];
gitRepoDetails.bundlesTab().list().resourceTable().sortableTable() gitRepoDetails.bundlesList().sortableTable()
.tableHeaderRow() .tableHeaderRow()
.within('.table-header-container .content') .within('.table-header-container .content')
.each((el, i) => { .each((el, i) => {
@ -238,10 +234,10 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
const gitRepoDetails = new FleetGitRepoDetailsPo(workspace, this.gitRepo); const gitRepoDetails = new FleetGitRepoDetailsPo(workspace, this.gitRepo);
listPage.goTo(); gitRepoListPage.goTo();
listPage.waitForPage(); gitRepoListPage.waitForPage();
headerPo.selectWorkspace(workspace); headerPo.selectWorkspace(workspace);
listPage.sharedComponents().resourceTableDetails(this.gitRepo, 2).find('a').click(); gitRepoListPage.goToDetailsPage(this.gitRepo);
gitRepoDetails.waitForPage(null, 'bundles'); gitRepoDetails.waitForPage(null, 'bundles');
gitRepoDetails.gitRepoTabs().allTabs().should('have.length', 4, { timeout: 10000 }); gitRepoDetails.gitRepoTabs().allTabs().should('have.length', 4, { timeout: 10000 });
const tabs = ['Bundles', 'Resources', 'Conditions', 'Recent Events']; const tabs = ['Bundles', 'Resources', 'Conditions', 'Recent Events'];
@ -287,11 +283,11 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
// }); // });
// // go to fleet gitrepo // // go to fleet gitrepo
// listPage.goTo(); // gitRepoListPage.goTo();
// listPage.waitForPage(); // gitRepoListPage.waitForPage();
// headerPo.selectWorkspace(workspace); // headerPo.selectWorkspace(workspace);
// listPage.goToDetailsPage(basicRepos[1].name); // gitRepoListPage.goToDetailsPage(basicRepos[1].name);
// const gitRepoDetails = new FleetGitRepoDetailsPo('fleet-local', basicRepos[1].name); // const gitRepoDetails = new FleetGitRepoDetailsPo('fleet-local', basicRepos[1].name);
@ -305,10 +301,10 @@ describe('Git Repo', { testIsolation: 'off', tags: ['@fleet', '@adminUser'] }, (
const gitRepoDetails = new FleetGitRepoDetailsPo(workspace, this.gitRepo); const gitRepoDetails = new FleetGitRepoDetailsPo(workspace, this.gitRepo);
listPage.goTo(); gitRepoListPage.goTo();
listPage.waitForPage(); gitRepoListPage.waitForPage();
headerPo.selectWorkspace(workspace); headerPo.selectWorkspace(workspace);
listPage.sharedComponents().resourceTableDetails(this.gitRepo, 2).find('a').click(); gitRepoListPage.goToDetailsPage(this.gitRepo);
gitRepoDetails.waitForPage(null, 'bundles'); gitRepoDetails.waitForPage(null, 'bundles');

View File

@ -1,6 +1,6 @@
import { PerformancePagePo } from '@/cypress/e2e/po/pages/global-settings/performance.po'; import { PerformancePagePo } from '@/cypress/e2e/po/pages/global-settings/performance.po';
import HomePagePo from '@/cypress/e2e/po/pages/home.po'; import HomePagePo from '@/cypress/e2e/po/pages/home.po';
import { promptModal } from '@/cypress/e2e/po/prompts/shared/promptInstances.po'; import { promptModal } from '@/cypress/e2e/po/prompts/shared/modalInstances.po';
const performancePage = new PerformancePagePo(); const performancePage = new PerformancePagePo();
const performanceSettingsOriginal = []; const performanceSettingsOriginal = [];
@ -176,7 +176,7 @@ describe('Performance', { testIsolation: 'off', tags: ['@globalSettings', '@admi
performancePage.namespaceFilteringCheckbox().set(); performancePage.namespaceFilteringCheckbox().set();
promptModal().getBody().contains('Required Namespace / Project Filtering is incompatible with Manual Refresh and Incremental Loading. Enabling this will disable them.'); promptModal().getBody().contains('Required Namespace / Project Filtering is incompatible with Manual Refresh and Incremental Loading. Enabling this will disable them.');
promptModal().submit('Continue'); promptModal().clickActionButton('Continue');
performancePage.namespaceFilteringCheckbox().isChecked(); performancePage.namespaceFilteringCheckbox().isChecked();
performancePage.applyAndWait('forceNsFilterV2-true').then(({ request, response }) => { performancePage.applyAndWait('forceNsFilterV2-true').then(({ request, response }) => {
expect(response?.statusCode).to.eq(200); expect(response?.statusCode).to.eq(200);

View File

@ -14,7 +14,7 @@ const accountPage = new AccountPagePo();
const clusterList = new ClusterManagerListPagePo(); const clusterList = new ClusterManagerListPagePo();
const burgerMenu = new BurgerMenuPo(); const burgerMenu = new BurgerMenuPo();
const settingsOrginal = []; const settingsOrginal = [];
const removeServerUrl = false; let removeServerUrl = false;
describe('Settings', { testIsolation: 'off' }, () => { describe('Settings', { testIsolation: 'off' }, () => {
before(() => { before(() => {

View File

@ -1,7 +1,7 @@
import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po'; import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
import ClusterManagerCreateRke2CustomPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke2-custom.po'; import ClusterManagerCreateRke2CustomPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-rke2-custom.po';
import * as jsyaml from 'js-yaml'; import * as jsyaml from 'js-yaml';
import { promptModal } from '@/cypress/e2e/po/prompts/shared/promptInstances.po'; import { promptModal } from '@/cypress/e2e/po/prompts/shared/modalInstances.po';
describe('Cluster List', { tags: ['@manager', '@adminUser'] }, () => { describe('Cluster List', { tags: ['@manager', '@adminUser'] }, () => {
const clusterList = new ClusterManagerListPagePo(); const clusterList = new ClusterManagerListPagePo();
@ -48,7 +48,7 @@ describe('Cluster List', { tags: ['@manager', '@adminUser'] }, () => {
createRKE2ClusterPage.waitForPage(); createRKE2ClusterPage.waitForPage();
createRKE2ClusterPage.resourceDetail().createEditView().editClusterAsYaml(); createRKE2ClusterPage.resourceDetail().createEditView().editClusterAsYaml();
promptModal().checkVisible(); promptModal().checkVisible();
promptModal().submit('Save and Continue'); promptModal().clickActionButton('Save and Continue');
createRKE2ClusterPage.waitForPage('type=custom&rkeType=rke2', 'basic'); createRKE2ClusterPage.waitForPage('type=custom&rkeType=rke2', 'basic');
// provision cluster into a custom namespace // provision cluster into a custom namespace
createRKE2ClusterPage.resourceDetail().resourceYaml().codeMirror().value() createRKE2ClusterPage.resourceDetail().resourceYaml().codeMirror().value()

View File

@ -27,6 +27,7 @@ import LoadingPo from '@/cypress/e2e/po/components/loading.po';
import { EXTRA_LONG_TIMEOUT_OPT, MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; import { EXTRA_LONG_TIMEOUT_OPT, MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import KontainerDriversPagePo from '@/cypress/e2e/po/pages/cluster-manager/kontainer-drivers.po'; import KontainerDriversPagePo from '@/cypress/e2e/po/pages/cluster-manager/kontainer-drivers.po';
import DeactivateDriverDialogPo from '@/cypress/e2e/po/prompts/deactivateDriverDialog.po'; import DeactivateDriverDialogPo from '@/cypress/e2e/po/prompts/deactivateDriverDialog.po';
import { USERS_BASE_URL } from '@/cypress/support/utils/api-endpoints';
// At some point these will come from somewhere central, then we can make tools to remove resources from this or all runs // 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 runTimestamp = +new Date();
@ -596,7 +597,7 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
describe('Generic', () => { describe('Generic', () => {
it('can create new cluster', () => { it('can create new cluster', () => {
cy.intercept('GET', `/v1/management.cattle.io.users?exclude=metadata.managedFields`).as('getUsers'); cy.intercept('GET', `${ USERS_BASE_URL }?exclude=metadata.managedFields`).as('getUsers');
cy.intercept('POST', `/v3/${ importType }s`).as('importRequest'); cy.intercept('POST', `/v3/${ importType }s`).as('importRequest');
clusterList.goTo(); clusterList.goTo();
@ -619,6 +620,9 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
importClusterPage.nameNsDescription().name().checkVisible(); importClusterPage.nameNsDescription().name().checkVisible();
importClusterPage.nameNsDescription().name().set(importGenericName); importClusterPage.nameNsDescription().name().set(importGenericName);
// Issue #13614: Imported Cluster Version Mgmt: Conditionally show warning message
importClusterPage.versionManagementBanner().should('exist').and('be.visible');
importClusterPage.create(); importClusterPage.create();
cy.wait('@importRequest').then((intercept) => { cy.wait('@importRequest').then((intercept) => {
@ -663,7 +667,7 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
}); });
it('can edit imported cluster and see changes afterwards', () => { it('can edit imported cluster and see changes afterwards', () => {
const editImportedClusterPage = new ClusterManagerEditImportedPagePo(undefined, importedClusterName); const editImportedClusterPage = new ClusterManagerEditImportedPagePo(undefined, 'fleet-default', importedClusterName);
cy.intercept('GET', '/v1-rke2-release/releases').as('getRke2Releases'); cy.intercept('GET', '/v1-rke2-release/releases').as('getRke2Releases');
clusterList.goTo(); clusterList.goTo();
@ -683,6 +687,13 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
// Issue #10432: Edit Cluster screen falsely gives impression imported cluster's name and description can be edited // Issue #10432: Edit Cluster screen falsely gives impression imported cluster's name and description can be edited
editImportedClusterPage.nameNsDescription().name().expectToBeDisabled(); editImportedClusterPage.nameNsDescription().name().expectToBeDisabled();
// Issue #13614: Imported Cluster Version Mgmt: Conditionally show warning message
editImportedClusterPage.versionManagementBanner().should('not.exist');
editImportedClusterPage.enableVersionManagement();
editImportedClusterPage.versionManagementBanner().should('exist').and('be.visible');
editImportedClusterPage.defaultVersionManagement();
editImportedClusterPage.toggleAccordion(5, 'Networking'); editImportedClusterPage.toggleAccordion(5, 'Networking');
editImportedClusterPage.ace().enable(); editImportedClusterPage.ace().enable();
editImportedClusterPage.ace().enterFdqn(fqdn); editImportedClusterPage.ace().enterFdqn(fqdn);
@ -798,6 +809,39 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
}); });
}); });
describe('Local', { tags: ['@jenkins', '@localCluster'] }, () => {
it(`can open edit for local cluster`, () => {
const editLocalClusterPage = new ClusterManagerEditImportedPagePo(undefined, 'fleet-local', 'local');
cy.intercept('GET', '/v1-rke2-release/releases').as('getRke2Releases');
clusterList.goTo();
clusterList.list().actionMenu('local').getMenuItem('Edit Config').click();
editLocalClusterPage.waitForPage('mode=edit');
editLocalClusterPage.nameNsDescription().name().value().should('eq', 'local' );
// check accordions are properly displayed
editLocalClusterPage.accordion(2, 'Basics').should('be.visible');
editLocalClusterPage.accordion(3, 'Member Roles').scrollIntoView().should('be.visible');
editLocalClusterPage.accordion(4, 'Labels and Annotations').scrollIntoView().should('be.visible');
editLocalClusterPage.accordion(5, 'Networking').scrollIntoView().should('be.visible');
editLocalClusterPage.accordion(6, 'Registries').scrollIntoView().should('be.visible');
editLocalClusterPage.accordion(7, 'Advanced').scrollIntoView().should('be.visible');
// Issue #13614: Imported Cluster Version Mgmt: Conditionally show warning message
editLocalClusterPage.versionManagementBanner().should('not.exist');
editLocalClusterPage.enableVersionManagement();
editLocalClusterPage.versionManagementBanner().should('exist').and('be.visible');
editLocalClusterPage.versionManagementBanner().should('not.contain.text', 'This change will trigger cluster agent redeployment.');
editLocalClusterPage.disableVersionManagement();
editLocalClusterPage.versionManagementBanner().should('exist').and('be.visible');
editLocalClusterPage.versionManagementBanner().should('not.contain.text', 'This change will trigger cluster agent redeployment.');
editLocalClusterPage.cancel();
// We should be taken back to the list page if the save was successful
clusterList.waitForPage();
});
it(`can navigate to local cluster's explore product`, () => { it(`can navigate to local cluster's explore product`, () => {
const clusterName = 'local'; const clusterName = 'local';
const clusterDashboard = new ClusterDashboardPagePo(clusterName); const clusterDashboard = new ClusterDashboardPagePo(clusterName);
@ -807,6 +851,7 @@ describe('Cluster Manager', { testIsolation: 'off', tags: ['@manager', '@adminUs
clusterDashboard.waitForPage(undefined, 'cluster-events'); clusterDashboard.waitForPage(undefined, 'cluster-events');
}); });
});
it('can download YAML via bulk actions', () => { it('can download YAML via bulk actions', () => {
// Delete downloads directory. Need a fresh start to avoid conflicting file names // Delete downloads directory. Need a fresh start to avoid conflicting file names

View File

@ -6,6 +6,7 @@ import PromptRemove from '@/cypress/e2e/po/prompts/promptRemove.po';
import LoadingPo from '@/cypress/e2e/po/components/loading.po'; import LoadingPo from '@/cypress/e2e/po/components/loading.po';
import TabbedPo from '@/cypress/e2e/po/components/tabbed.po'; import TabbedPo from '@/cypress/e2e/po/components/tabbed.po';
import { MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts'; import { MEDIUM_TIMEOUT_OPT } from '@/cypress/support/utils/timeouts';
import { USERS_BASE_URL } from '@/cypress/support/utils/api-endpoints';
// will only run this in jenkins pipeline where cloud credentials are stored // will only run this in jenkins pipeline where cloud credentials are stored
describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation: 'off', tags: ['@manager', '@adminUser', '@standardUser', '@jenkins'] }, () => { describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation: 'off', tags: ['@manager', '@adminUser', '@standardUser', '@jenkins'] }, () => {
@ -69,7 +70,7 @@ describe('Deploy RKE2 cluster using node driver on Amazon EC2', { testIsolation:
cloudCredForm.defaultRegion().clickOptionWithLabel('us-west-1'); cloudCredForm.defaultRegion().clickOptionWithLabel('us-west-1');
cloudCredForm.saveButton().expectToBeEnabled(); cloudCredForm.saveButton().expectToBeEnabled();
cy.intercept('GET', '/v1/management.cattle.io.users?exclude=metadata.managedFields').as('pageLoad'); cy.intercept('GET', `${ USERS_BASE_URL }?exclude=metadata.managedFields`).as('pageLoad');
cloudCredForm.saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials').then((req) => { cloudCredForm.saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials').then((req) => {
expect(req.response?.statusCode).to.equal(201); expect(req.response?.statusCode).to.equal(201);
cloudcredentialId = req.response?.body.id; cloudcredentialId = req.response?.body.id;

View File

@ -0,0 +1,211 @@
import HomePagePo from '@/cypress/e2e/po/pages/home.po';
import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
import LoadingPo from '@/cypress/e2e/po/components/loading.po';
import ClusterManagerCreateEKSPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-eks.po';
import * as eksDefaultSettings from '@/cypress/e2e/blueprints/cluster_management/eks-default-settings';
import RadioGroupInputPo from '~/cypress/e2e/po/components/radio-group-input.po';
/******
* Running this test will delete all Amazon cloud credentials from the target cluster
******/
describe('Create EKS cluster', { testIsolation: 'off', tags: ['@manager', '@adminUser', '@jenkins'] }, () => {
const clusterList = new ClusterManagerListPagePo();
const loadingPo = new LoadingPo('.loading-indicator');
let clusterId = '';
const eksSettings = {
eksRegion: eksDefaultSettings.DEFAULT_REGION,
nodegroupName: eksDefaultSettings.DEFAULT_NODE_GROUP_CONFIG.nodegroupName,
nodeRole: eksDefaultSettings.DEFAULT_NODE_GROUP_CONFIG.nodeRole,
desiredSize: eksDefaultSettings.DEFAULT_NODE_GROUP_CONFIG.desiredSize,
maxSize: eksDefaultSettings.DEFAULT_NODE_GROUP_CONFIG.maxSize,
minSize: eksDefaultSettings.DEFAULT_NODE_GROUP_CONFIG.minSize,
diskSize: eksDefaultSettings.DEFAULT_NODE_GROUP_CONFIG.diskSize,
instanceType: eksDefaultSettings.DEFAULT_NODE_GROUP_CONFIG.instanceType,
publicAccess: eksDefaultSettings.DEFAULT_EKS_CONFIG.publicAccess,
privateAccess: eksDefaultSettings.DEFAULT_EKS_CONFIG.privateAccess,
launchTemplate: 'Default (One will be created automatically)'
};
const createEKSClusterPage = new ClusterManagerCreateEKSPagePo();
const cloudCredForm = createEKSClusterPage.cloudCredentialsForm();
before( 'add cloud credentials', () => {
cy.login();
HomePagePo.goTo();
// clean up amazon cloud credentials
cy.getRancherResource('v3', 'cloudcredentials', null, null).then((resp: Cypress.Response<any>) => {
const body = resp.body;
if (body.pagination['total'] > 0) {
body.data.forEach((item: any) => {
if (item.amazonec2credentialConfig) {
const id = item.id;
cy.deleteRancherResource('v3', 'cloudcredentials', id);
} else {
cy.log('There are no existing amazon cloud credentials to delete');
}
});
}
});
// create cluster
ClusterManagerListPagePo.navTo();
clusterList.waitForPage();
clusterList.createCluster();
createEKSClusterPage.selectKubeProvider(0);
loadingPo.checkNotExists();
createEKSClusterPage.rke2PageTitle().should('include', 'Create Amazon EKS');
createEKSClusterPage.waitForPage('type=amazoneks&rkeType=rke2');
// create amazon cloud credential
cloudCredForm.saveButton().expectToBeDisabled();
cy.createE2EResourceName('ekscloudcredential').then((eksCloudCredentialName) => {
cloudCredForm.nameNsDescription().name().set(eksCloudCredentialName);
});
cloudCredForm.accessKey().set(Cypress.env('awsAccessKey'));
cloudCredForm.secretKey().set(Cypress.env('awsSecretKey'));
cloudCredForm.saveButton().expectToBeEnabled();
cy.intercept('GET', '/v1/management.cattle.io.users?exclude=metadata.managedFields').as('pageLoad');
cloudCredForm.saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials').then((req) => {
expect(req.response?.statusCode).to.equal(201);
});
cy.wait('@pageLoad').its('response.statusCode').should('eq', 200);
loadingPo.checkNotExists();
createEKSClusterPage.waitForPage('type=amazoneks&rkeType=rke2#group1%200');
});
beforeEach( () => {
cy.createE2EResourceName('ekscluster').as('eksClusterName');
cy.createE2EResourceName('ekscluster2').as('eksClusterName2');
});
it('can create an Amazon EKS cluster by just filling in the mandatory fields', function() {
// Set the cluster name and description in the Create EKS Page
createEKSClusterPage.getClusterName().set(this.eksClusterName);
createEKSClusterPage.getClusterDescription().set(`${ this.eksClusterName }-description`);
// Create EKS Cluster and verify that the properties posted to the server match the expected settings
cy.intercept('POST', 'v3/clusters').as('createEKSCluster');
createEKSClusterPage.create();
cy.wait('@createEKSCluster').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
expect(response?.body).to.have.property('type', 'cluster');
expect(response?.body).to.have.property('name', this.eksClusterName);
expect(response?.body).to.have.property('description', `${ this.eksClusterName }-description`);
clusterId = response?.body.id;
});
clusterList.waitForPage();
clusterList.list().state(this.eksClusterName).should('contain.text', 'Provisioning');
});
it('can create an Amazon EKS cluster with default values', function() {
// create cluster
ClusterManagerListPagePo.navTo();
clusterList.waitForPage();
clusterList.createCluster();
createEKSClusterPage.selectKubeProvider(0);
loadingPo.checkNotExists();
createEKSClusterPage.rke2PageTitle().should('include', 'Create Amazon EKS');
createEKSClusterPage.waitForPage('type=amazoneks&rkeType=rke2#group1%200');
// Verify that eks-zone-select dropdown is set to the default zone
createEKSClusterPage.getRegion().checkOptionSelected(eksSettings.eksRegion);
// Get latest EKS kubernetes version and verify that eks-version-select dropdown is set to the default version as defined in CruEKS.vue
const latestEKSversion = createEKSClusterPage.getLatestEKSversion();
createEKSClusterPage.getVersion().checkOptionSelected(latestEKSversion);
// Check the node group name is set to the default name
createEKSClusterPage.getNodeGroup().shouldHaveValue(eksSettings.nodegroupName);
// Check the node role is set to the default role
createEKSClusterPage.getNodeRole().checkOptionSelected(eksSettings.nodeRole);
// Check the default ASG Sizes
createEKSClusterPage.getDesiredASGSize().shouldHaveValue(eksSettings.desiredSize);
createEKSClusterPage.getMinASGSize().shouldHaveValue(eksSettings.minSize);
createEKSClusterPage.getMaxASGSize().shouldHaveValue(eksSettings.maxSize);
// Check the default Launch template
createEKSClusterPage.getLauchTemplate().checkOptionSelected(eksSettings.launchTemplate);
// Check the default instance type
createEKSClusterPage.getInstanceType().checkContainsOptionSelected(eksSettings.instanceType);
// Check the default volume Size
createEKSClusterPage.getDiskSize().shouldHaveValue(eksSettings.diskSize);
// Check that standard role is selected
const serviceRolebuttonGroup = new RadioGroupInputPo('[data-testid= "eks-service-role-radio"]');
serviceRolebuttonGroup.isChecked(0);
// Check that standard Networking access
createEKSClusterPage.getPublicAccess().isChecked();
createEKSClusterPage.getPrivateAccess().isUnchecked();
// Check that default VPC and subnets are set
const vpcButtonGroup = new RadioGroupInputPo('[aria-label="VPCs and Subnets"]');
vpcButtonGroup.isChecked(0);
// Set the cluster name and description in the Create EKS Page
createEKSClusterPage.getClusterName().set(this.eksClusterName2);
createEKSClusterPage.getClusterDescription().set(`${ this.eksClusterName2 }-description`);
// Create EKS Cluster and verify that the properties posted to the server match the expected settings
cy.intercept('POST', 'v3/clusters').as('createEKSCluster');
createEKSClusterPage.create();
cy.wait('@createEKSCluster').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
expect(response?.body).to.have.property('type', 'cluster');
expect(response?.body).to.have.property('name', this.eksClusterName2);
expect(response?.body).to.have.property('description', `${ this.eksClusterName2 }-description`);
expect(response?.body.eksConfig).to.have.property('kubernetesVersion').contains(latestEKSversion);
expect(response?.body.eksConfig).to.have.property('region', eksSettings.eksRegion);
expect(response?.body.eksConfig).to.have.property('privateAccess', eksSettings.privateAccess);
expect(response?.body.eksConfig).to.have.property('publicAccess', eksSettings.publicAccess);
expect(response?.body.eksConfig.nodeGroups[0]).to.have.property('nodegroupName', eksSettings.nodegroupName);
expect(response?.body.eksConfig.nodeGroups[0]).to.have.property('desiredSize', Number(eksSettings.desiredSize));
expect(response?.body.eksConfig.nodeGroups[0]).to.have.property('minSize', Number(eksSettings.minSize));
expect(response?.body.eksConfig.nodeGroups[0]).to.have.property('maxSize', Number(eksSettings.maxSize));
expect(response?.body.eksConfig.nodeGroups[0]).to.have.property('instanceType', eksSettings.instanceType);
expect(response?.body.eksConfig.nodeGroups[0]).to.have.property('diskSize', Number(eksSettings.diskSize));
clusterId = response?.body.id;
});
clusterList.waitForPage();
clusterList.list().state(this.eksClusterName).should('contain.text', 'Provisioning');
});
after('clean up', () => {
// delete cluster
cy.deleteRancherResource('v1', 'provisioning.cattle.io.clusters', `fleet-default/${ clusterId }`, false);
// clean up Amazon cloud credentials
cy.getRancherResource('v3', 'cloudcredentials', null, null).then((resp: Cypress.Response<any>) => {
const body = resp.body;
if (body.pagination['total'] > 0) {
body.data.forEach((item: any) => {
if (item.amazonec2credentialConfig) {
const id = item.id;
cy.deleteRancherResource('v3', 'cloudcredentials', id);
} else {
cy.log('There are no existing Amazon cloud credentials to delete');
}
});
}
});
});
});

View File

@ -3,6 +3,7 @@ import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/clu
import LoadingPo from '@/cypress/e2e/po/components/loading.po'; import LoadingPo from '@/cypress/e2e/po/components/loading.po';
import ClusterManagerCreateGKEPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-gke.po'; import ClusterManagerCreateGKEPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-gke.po';
import { DEFAULT_GCP_ZONE } from '@/pkg/gke/util/gcp'; import { DEFAULT_GCP_ZONE } from '@/pkg/gke/util/gcp';
import { USERS_BASE_URL } from '@/cypress/support/utils/api-endpoints';
/****** /******
* Running this test will delete all GKE cloud credentials from the target cluster * Running this test will delete all GKE cloud credentials from the target cluster
@ -88,7 +89,7 @@ describe('Deploy GKE cluster with default settings', { tags: ['@manager', '@admi
cloudCredForm.serviceAccount().set(serviceAccount); cloudCredForm.serviceAccount().set(serviceAccount);
cloudCredForm.serviceAccount().set(serviceAccount); cloudCredForm.serviceAccount().set(serviceAccount);
cloudCredForm.saveButton().expectToBeEnabled(); cloudCredForm.saveButton().expectToBeEnabled();
cy.intercept('GET', '/v1/management.cattle.io.users?exclude=metadata.managedFields').as('pageLoad'); cy.intercept('GET', `${ USERS_BASE_URL }?exclude=metadata.managedFields`).as('pageLoad');
cloudCredForm.saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials').then((req) => { cloudCredForm.saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials').then((req) => {
expect(req.response?.statusCode).to.equal(201); expect(req.response?.statusCode).to.equal(201);
cloudcredentialId = req.response?.body.id.replace(':', '%3A'); cloudcredentialId = req.response?.body.id.replace(':', '%3A');

Some files were not shown because too many files have changed in this diff Show More